I am trying to boot my new PocketBeagle into a plain assembly program.
.equ GPIO_BANK1, 0x4804C000
.equ GPIO_OE, 0x134
.equ GPIO_USR_SETPIN0, 0x194
.equ GPIO_USR_PIN0, 0x13C
.globl _start
_start:
ldr r0, =GPIO_BANK1
ldr r1, =GPIO_OE @ Get the output enable register
add r0, r1
mov r1, #0 @ Set all of the GPIO1 Pins to output
str r1, [r0]
_main:
ldr r0, =GPIO_BANK1
ldr r1, =GPIO_USR_PIN0 @ Get the output register
add r0, r1
mov r1, #1
lsl r1, #24
str r1, [r0] @ Set the USR LED to hi.
loop:
ldr r2, =0x00010000
sub r2, #1
cmp r2, #0
beq _main
mov r1, #0
str r1, [r0]
_hang:
b _main
I compile this file using the following makefile
ARMGNU = arm-eabi
boot.bin: boot.asm
$(ARMGNU)-as boot.asm -o boot.o
$(ARMGNU)-ld -T linker.ld boot.o -o boot.elf
$(ARMGNU)-objdump -D boot.elf > boot.list
$(ARMGNU)-objcopy boot.elf -O srec boot.srec
$(ARMGNU)-objcopy boot.elf -O binary boot.bin
According to the manual section 26.1.6 (26.1.8.5 for SD booting), I can boot into this code from an SD card with the FAT filesystem if I name the file MLO
. Now, if I got my registers right in the assembly code, then the USR0, USR1, USR2, and USR3 LEDs on the PocketBeagle should light up. (See here USR to PIN Mappings) This is because the GPIO1_21, 22, 23, and 24 pins correspond to those 4 LEDs, and those are the pins that I am (trying to) set high.
But the LEDs do not light up. So I'm doing something wrong, but I can't figure it out.
There is very little documentation on the PocketBeagle online. Apparently the PocketBeagle should be electrically very similar to the BeagleBone Black.
Some direction. Where do I go from here? I've come to accept the fact that I probably won't be able to get the USR LEDs to blink. I don't think the manual can help me any more, and there aren't any resources on the web. I am still learning embedded programming, and I've had success with Arduino and Atmel Studio. I'm not completely novice but guidance is appreciated.
Where can I look for information on embedded system booting? Is there a similar simpler problem that I can tackle to help me understand?
This is probably a poorly formatted question for stackoverflow, but I have such little knowledge of the subject. Please advise.
I linked to the website for the PocketBeagle above. For those who don't want to leave SO, here is some info. It is similar to the BeagleBoneBlack. It has three main components, a micro USB port, an SD card reader and the Octavo Systems OSD3358 1GHz ARM® Cortex-A8 System on Chip. The OSD3358 contains the AM3358 TI Processor; the manual is above. The PocketBeagle comes conveniently configured so that it can boot from the SD card without fussing around with the SYSCONFIG pins. So you can put code on the SD card, put it in the PocketBeagle, and it will boot into that code... hopefully.
After some digging, I realized that my code is accurate, but I was forgetting one step. I need to turn on the GPIO1 bus clock before the GPIO1 bus will output signals. The register that controls this clock can be seen in section 8.1.12.1.29 of the manual. Additionally, I found this noted in a forum on the TI Website.
I abandoned trying to boot from the FAT file system and resorted to booting in 'raw mode.' See section 26.1.8.5.5 of the manual. I originally avoided this method because there was less detail, but it was ultimately easier.
This method was a bit trickier however, because I had to write raw bytes to an SD card. I used HxD to do this. At address 0, I put the following code... this is magic code described in section 26.1.10 of the manual. View this in a hex editor for your reading convenience.
40 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 @...............
00 00 00 00 43 48 53 45 54 54 49 4E 47 53 00 00 ....CHSETTINGS..
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
C1 C0 C0 C0 00 01 00 00 00 00 00 00 00 00 00 00 ÁÀÀÀ............
00 [0x50-0x1FF]...
Then there must be zeros until address 0x200 (512 Bytes). I put the binary code at address 0x200 with the addition of a GP header described in section 26.1.10.2 of the manual. The GP Header consists of 2 words (of 4 bytes each). The first word being the size of the 'image' (aka YOUR binary) and the second word being the destination in memory that the ROM bootloader will put your code. Since the public RAM of the AM335x chip starts at 0x402F0400, we want to put our code there. (Section 26.1.4.2 of the manual). Keep in mind, this is little endian. I put FF in for the size of my image, but in reality, that is larger than my image.
FF 00 00 00 00 04 2F 40
Immediately following that, I put the binary of the compiled assembly code posted in the original question. (So my code starts at 0x208) All together, starting from 0x200, the hex dump looks like
FF 00 00 00 00 04 2F 40 50 00 9F E5 AC 10 A0 E3
01 00 80 E0 02 10 A0 E3 00 10 80 E5 40 00 9F E5
4D 1F A0 E3 01 00 80 E0 00 10 A0 E3 00 10 80 E5
2C 00 9F E5 4F 1F A0 E3 01 00 80 E0 00 10 E0 E3
00 10 80 E5 01 28 A0 E3 01 20 42 E2 00 00 52 E3
F6 FF FF 0A 00 10 A0 E3 00 10 80 E5 F3 FF FF EA
00 00 E0 44 00 C0 04 48 00 00 00 00 00 00 00 00
My final assembly looked like this
.equ GPIO1, 0x4804C000
.equ GPIO_OE, 0x134
.equ CM_PER, 0x44E00000
.equ CM_PER_GPIO1_CLKCTRL, 0xAC
.equ GPIO_DATAOUT, 0x13C
.globl _start
_start:
ldr r0, =CM_PER @Clocks control register bus.
ldr r1, =CM_PER_GPIO1_CLKCTRL @Offset of the clock register for GPIO1
add r0, r1
mov r1, #2 @Set the enable bit. Man 8.1.12.1.29
str r1, [r0]
_led_enable:
ldr r0, =GPIO1 @Register bank for GPIO1
ldr r1, =GPIO_OE @Register that controls output enable.
add r0, r1
mov r1, #0
str r1, [r0]
_main:
ldr r0, =GPIO1
ldr r1, =GPIO_DATAOUT @Register than controls the output of GPIO1
add r0, r1
ldr r1, =0xFFFFFFFF
str r1, [r0]
loop:
ldr r2, =0x00010000 @The start of a loop that may or may not work.
sub r2, #1 @I tried to make the USR LEDs blink, but I posted
cmp r2, #0 @this before I tested it.
beq _main
mov r1, #0
str r1, [r0]
_hang:
b _main
My makefile looks like it did in the original question.