This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Assembly GNU compiler on TMC123GXL (arm-none-eabi-as)

Hello All,


I can't seem to find the answer to my issue on the internet and several reference guides after many hours of research.  I want to run a simple gpio toggle (turn on pin labeled pb2 - pin 47) program in assembly compiled using the GNU AS compiler (arm-none-eabi-as) and this is what I have so far:

-----begin of start.s --------

.syntax unified
.text

.global _start

_start:
.word  0x20007000
.word _reset
.word .
.word .
.word .
.word .
.word .
.word .
.word .
.word .
.word .
.word .
.word .
.word .
.word .
.word .
.word .
.word .

_reset:
ldr  sp,=stack_top
isb
ldr  r0,=0x400fe608 Enables the clock to all GPIO blocks
ldr  r1,=0xff
str  r1,[r0]
nop
nop
nop
nop

ldr  r0,=0x40059400 Sets the direction of the gpio pins in block B
ldr  r1,=0xff
str  r0,[r1]
nop
nop

ldr  r0,=0x40059420 Sets AFSEL - this is likely redundant as AFSEL defaults to 0x0 on reset/powerup.
ldr  r1,=0x0
str  r0,[r1]


ldr  r0,=0x40059500 Sets the pin to DR2R.
ldr  r1,=0xff
str  r0,[r1]
nop
nop

ldr  r0,=0x4005950c Sets ODR.
ldr  r1,=0xff
str  r0,[r1]
nop
nop

ldr  r0,=0x4005951c Sets DEN.
ldr  r1,=0xff
str  r0,[r1]

ldr  r0,=0x40059fff Sets DATA on all pins in block B.
ldr  r1,=0xff
str  r0,[r1]

---end of start.s---

----begin of start.ld---

ENTRY(_start)
SECTIONS
{
 . = 0x0;
 .text : {
 *start.o (_start)
 }
 . = 0x20007000;
 stack_top = .;
}

----end of start.ld----

The compile commands are as follows:

arm-none-eabi-as -mcpu=cortex-m4 -mthumb -o start.o start.s

 arm-none-eabi-ld -T start.ld start.o -o start.elf

 arm-none-eabi-objcopy -O binary start.elf start.bin

There are no problems compiling and uploading start.bin to the launchpad via the LM Flash Programmer; however the pin does not open and there is power to the unit (the green pwr led is on).  The .word directive was used in place of the dcd directive, as the GNU assembler does not understand dcd.  The hex memory addresses have been hard coded in the body and there is a better way of doing things, but that's all semantics.  Any help is appreciated, thanks.

Below is the output of nm and objdump.

:~/programming# arm-none-eabi-nm start.elf
00000044 t _reset
20007000 A stack_top
00000000 T _start

~/programming# arm-none-eabi-objdump -D -b binary -marm start.bin

start.bin:     file format binary


Disassembly of section .data:

00000000 <.data>:
   0:   20007000        andcs   r7, r0, r0
   4:   00000044        andeq   r0, r0, r4, asr #32
   8:   00000008        andeq   r0, r0, r8
   c:   0000000c        andeq   r0, r0, ip
  10:   00000010        andeq   r0, r0, r0, lsl r0
  14:   00000014        andeq   r0, r0, r4, lsl r0
  18:   00000018        andeq   r0, r0, r8, lsl r0
  1c:   0000001c        andeq   r0, r0, ip, lsl r0
  20:   00000020        andeq   r0, r0, r0, lsr #32
  24:   00000024        andeq   r0, r0, r4, lsr #32
  28:   00000028        andeq   r0, r0, r8, lsr #32
  2c:   0000002c        andeq   r0, r0, ip, lsr #32
  30:   00000030        andeq   r0, r0, r0, lsr r0
  34:   00000034        andeq   r0, r0, r4, lsr r0
  38:   00000038        andeq   r0, r0, r8, lsr r0
  3c:   0000003c        andeq   r0, r0, ip, lsr r0
  40:   00000040        andeq   r0, r0, r0, asr #32
  44:   d04cf8df        ldrdle  pc, [ip], #-143 ; 0xffffff71
  48:   8f6ff3bf        svchi   0x006ff3bf
  4c:   49134812        ldmdbmi r3, {r1, r4, fp, lr}
  50:   bf006001        svclt   0x00006001
  54:   bf00bf00        svclt   0x0000bf00
  58:   4811bf00        ldmdami r1, {r8, r9, sl, fp, ip, sp, pc}
  5c:   6008490f        andvs   r4, r8, pc, lsl #18
  60:   bf00bf00        svclt   0x0000bf00
  64:   4910480f        ldmdbmi r0, {r0, r1, r2, r3, fp, lr}
  68:   bf006008        svclt   0x00006008
  6c:   480fbf00        stmdami pc, {r8, r9, sl, fp, ip, sp, pc}        ; <UNPREDICTABLE>
  70:   6008490a        andvs   r4, r8, sl, lsl #18
  74:   bf00bf00        svclt   0x0000bf00
  78:   4908480d        stmdbmi r8, {r0, r2, r3, fp, lr}
  7c:   bf006008        svclt   0x00006008
  80:   480cbf00        stmdami ip, {r8, r9, sl, fp, ip, sp, pc}
  84:   60084905        andvs   r4, r8, r5, lsl #18
  88:   bf00bf00        svclt   0x0000bf00
  8c:   4903480a        stmdbmi r3, {r1, r3, fp, lr}
  90:   00006008        andeq   r6, r0, r8
  94:   20007000        andcs   r7, r0, r0
  98:   400fe608        andmi   lr, pc, r8, lsl #12
  9c:   000000ff        strdeq  r0, [r0], -pc   ; <UNPREDICTABLE>
  a0:   40059400        andmi   r9, r5, r0, lsl #8
  a4:   40059420        andmi   r9, r5, r0, lsr #8
  a8:   00000000        andeq   r0, r0, r0
  ac:   40059500        andmi   r9, r5, r0, lsl #10
  b0:   4005950c        andmi   r9, r5, ip, lsl #10
  b4:   4005951c        andmi   r9, r5, ip, lsl r5
  b8:   40059fff        strdmi  r9, [r5], -pc   ; <UNPREDICTABLE>

  • Hello Ivan,

    Please remove the Write to the ODR register.

    Regards

    Amit

  • Sorry Amit, not sure what you mean, can you explain?


    Thanks

  • Hi Ivan,

    Please remove the line

    ldr  r0,=0x4005950c Sets ODR.
    ldr  r1,=0xff
    str  r0,[r1]
    nop
    nop

    with

    ldr  r0,=0x4005950c Sets ODR.
    ldr  r1,=0x00
    str  r0,[r1]
    nop
    nop

    Regards

    Amit Ashara

  • Got it.  I removed and replaced it as well, no go.  Below is the new file:

    .syntax unified
    .text

    .global _start

    _start:
    .word  0x20007000
    .word _reset
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .

    _reset:
    ldr  sp,=stack_top
    isb
    ldr  r0,=0x400fe608
    ldr  r1,=0xff
    str  r0,[r1]
    nop
    nop
    nop
    nop

    ldr  r0,=0x40059400
    ldr  r1,=0xff
    str  r0,[r1]
    nop
    nop

    ldr  r0,=0x40059420
    ldr  r1,=0x0
    str  r0,[r1]
    nop
    nop

    ldr  r0,=0x40059500
    ldr  r1,=0xff
    str  r0,[r1]
    nop
    nop

    ldr  r0,=0x4005950c
    ldr  r1,=0x00
    str  r0,[r1]
    nop
    nop

    ldr  r0,=0x4005951c
    ldr  r1,=0xff
    str  r0,[r1]
    nop
    nop

    ldr  r0,=0x40059fff
    ldr  r1,=0xff
    str  r0,[r1]




  • Hi Ivan,

    The offset for the data register is also not correct,

    ldr  r0,=0x40059fff Sets DATA on all pins in block B.
    ldr  r1,=0xff
    str  r0,[r1]

    It should be 0x400593FC

    Please check all the register address

    Regards

    Amit

  • This particular register was confusing to me, as it does that weird [9:2] register selection, I was under the impression that if an 0xfff was given with a mask of 0xff all of the pins in block B would light up.  I have double checked the rest and they seem to concur, the rest of the registers were of a straight forward offset.  Below is a snippet of the changes made:

    ldr  r0,=0x40059500
    ldr  r1,=0xff
    str  r0,[r1]
    nop
    nop

    ldr  r0,=0x4005950c
    ldr  r1,=0x00
    str  r0,[r1]
    nop
    nop

    ldr  r0,=0x4005951c
    ldr  r1,=0xff
    str  r0,[r1]
    nop
    nop

    ldr  r0,=0x400593fc
    ldr  r1,=0xff
    str  r0,[r1]

  • Sorry, I wasn't clear, it's still no go on the toggle.

  • Hi Ivan,

    Let me know how the final code works out?

    Regards

    Amit Ashara

  • Hi Ivan,

    Can you please attach the binary file. I can check it on my system and let you know what the issue is?

    Regards

    Amit

  • Yea, the suggestions did not solve the problem; it's still a no-go.  The .bin file downloads to the launchpad and the green pwr led is on but no volage on pin pb2 to gnd.  Do you have any more suggestions?  Thanks.

  • Hi Ivan,

    The last thing that you may want to check is the SYSCTL.GPIOHBCTL register. By default for GPIO Port B is accessible through the APB Aperture. The address for GPIO Port that you are putting is on the AHB aperture. In a nutshell the Base address of 0x40059XXX to be replaced by 0x40005XXX

    I will try the bin file and let you know what the issue is.

    Regards

    Amit Ashara

  • Hi Amit,


    I remember having come across this so I went back to double-check on the reference guide and it looks like the apb bus is the legacy bus and the ahb is the higher performance one.  The apb bus is 1 clock slower than the ahb bus.  Can you kindly confirm?
      thx

    9.4 Register Map
    Table 9-6 on page 618 lists the GPIO registers. Each GPIO port can be accessed through one of
    two bus apertures. The legacy aperture, the Advanced Peripheral Bus (APB), is backwards-compatible
    with previous devices. The other aperture, the Advanced High-Performance Bus (AHB), offers the
    same register map but provides better back-to-back access performance than the APB bus.
    Important: The GPIO registers in this chapter are duplicated in each GPIO block; however,
    depending on the block, all eight bits may not be connected to a GPIO pad. In those
    cases, writing to unconnected bits has no effect, and reading unconnected bits returns
    no meaningful data. See “Signal Description” on page 608 for the GPIOs included on
    this device.
    The offset listed is a hexadecimal increment to the register's address, relative to that GPIO port's
    base address:
    ■ GPIO Port A (APB): 0x4000.4000
    ■ GPIO Port A (AHB): 0x4005.8000
    ■ GPIO Port B (APB): 0x4000.5000
    ■ GPIO Port B (AHB): 0x4005.9000
    ■ GPIO Port C (APB): 0x4000.6000
    ■ GPIO

  • Made a change to the GPIOHBCTL register and set all the bits to use the ahb bus.  still no go.  below is the new config:

    .syntax unified
    .text

    .global _start

    _start:
    .word  0x20007000
    .word _reset
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .

    _reset:
    ldr  sp,=stack_top
    isb
    ldr  r0,=0x400fe608
    ldr  r1,=0xff
    str  r0,[r1]
    nop
    nop
    nop
    nop

    ldr  r0,=0x40059400
    ldr  r1,=0xff
    str  r0,[r1]
    nop
    nop

    ldr  r0,=0x40059420
    ldr  r1,=0x0
    str  r0,[r1]
    nop
    nop

    ldr  r0,=0x40059500
    ldr  r1,=0xff
    str  r0,[r1]
    nop
    nop

    ldr  r0,=0x400fe06c
    ldr  r1,=0xff
    str  r0,[r1]
    nop
    nop


    ldr  r0,=0x4005950c
    ldr  r1,=0x00
    str  r0,[r1]
    nop
    nop
    ldr  r0,=0x400593fc
    ldr  r1,=0xff
    str  r0,[r1]




    this is the new .bin file:

    6254.start.zip

    These are the version numbers of the tools in use;

    ~/programming# arm-none-eabi-as -v
    GNU assembler version 2.23.2 (arm-none-eabi) using BFD version (GNU Tools for ARM Embedded Processors) 2.23.2.20131129

    ~/programming# arm-none-eabi-ld -v
    GNU ld (GNU Tools for ARM Embedded Processors) 2.23.2.20131129

    ~/programming# arm-none-eabi-ld -V
    GNU ld (GNU Tools for ARM Embedded Processors) 2.23.2.20131129
      Supported emulations:
       armelf

    thx

  • Hi Ivan,

    In the last code post, the GPIOHBCTL register for Port B is not being set?

    Also regarding the AHB v/s APB bus, the AHB Bus allows for back to back access, unlike the APB Bus where there is a single clock cycle delay

    Regards

    Amit Ashara

  • Hi Ivan,

    I ran the code and it did not work either for me. However I could use the debugger to manually set the PC and SP and get the code to work.

    During this I noticed that there is an error in the code you had sent. The error is

    ldr  r0,=0x40005500
    ldr  r1,=0xff
    str  r0,[r1]

    has been used at almost all places whereas it should be

    ldr  r0,=0x40005500
    ldr  r1,=0xff
    str  r1,[r0]

    I am still looking into it as to why SP and PC are not getting loaded.

    Regards,

    Amit Ashara

  • Hi Ivan,

    Good News. The code is working. The issue was besides all that has been mentioned is that the OC location has to be the actual value+0x1.

    For your reference the Cortex Tech Manual

    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CHDBIBGJ.html

    And the code

    .syntax unified
    .text

    .global _start

    _start:
    .word  0x20007000
    .word  _reset+0x1
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .
    .word .

    _reset:
    ldr  r0,=0x400fe608
    ldr  r1,=0xff
    str  r1,[r0]
    nop
    nop
    nop
    nop

    ldr  r0,=0x40005400
    ldr  r1,=0xff
    str  r1,[r0]
    nop
    nop

    ldr  r0,=0x40005420
    ldr  r1,=0x0
    str  r1,[r0]


    ldr  r0,=0x40005500
    ldr  r1,=0xff
    str  r1,[r0]
    nop
    nop

    ldr  r0,=0x4000550c
    ldr  r1,=0x00
    str  r1,[r0]
    nop
    nop

    ldr  r0,=0x4000551c
    ldr  r1,=0xff
    str  r1,[r0]

    ldr  r0,=0x400053fC
    ldr  r1,=0xff
    str  r1,[r0]


    Regards

    Amit

  • Alright!!! well done!  I tried the code in my board and it works as well.  so it was the ldr instructions and an alignment issue of the reset handler in the vector table (the +0x1 after the _reset label).  It also looks like you are using the apb bus rather than ahb.  what debug tool are you using?


    thanks for you help!

  • Oh, also I see that the sp does not need to be specified in the reset handler, this must mean that the chip retains the sp after a reset right?

  • Hi Ivan,

    Yes, the SP does not need to be specified. The 0x0 location has the SP and 0x4 has the PC

    Regards

    Amit