Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: Turn the LED on with assembler code ( Teensy 3.1 )

  1. #1

    Turn the LED on with assembler code ( Teensy 3.1 )

    Hi all. I like to know what is going on under the hood so I started from developing a simple app in assembler language. The app should just turn on the LED. I checked everything several times but no success. Could you please have a look and maybe find some fixes ?

    Build script:
    Code:
    ./bin/arm-none-eabi-as -mcpu=cortex-m4 -o crt0.o crt0.s
    ./bin/arm-none-eabi-ld -Ttext 0x0 -o crt0.elf crt0.o
    ./bin/arm-none-eabi-objcopy -O binary crt0.elf crt0.bin
    ./bin/arm-none-eabi-objcopy -O ihex crt0.elf crt0.hex
    Source code of the app crt0.s ( I know I should not use 'crt0' as a name for this ):
    Code:
    	.text
    	.org 0
    
    vectors:
    	.word 0x20000000   	@ Initial Stack Pointer
    	.word reset 		@ Initial Program Counter
    	.word default 		@ NMI
    	.word default		@ Hard Default
    	.word default		@ Memory Manage Fault
    	.word default		@ Bus Fault
    	.word default		@ Usage Fault
    	.word default		@ SV Call
    	.word default		@ Debug monitor
    	.word default		@ Pendable Request for System Service
    	.word default		@ System Tick Timer
    	
    	.org 0x400
    	.byte 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF
    	.align
    
    default: 
    	b default
    
    reset:
    
    unlock_watchdog:
    	ldr r6, =0x4005200e
    	ldr r0, =0xc520
    	strh r0, [r6]
    	ldr r0, =0xd928
    	strh r0, [r6]
    
    disable_watchdog:
    	ldr r6, =0x40052000
    	ldr r0, =0x01d2
    	strh r0, [r6]
    
    led_on:
    	ldr r6, = 0x40048038 @ SIM_SCGC5
    	ldr r0, = 0x00043F82 @ Clocks active to all GPIO
    	str r0, [r6]
    
    	.set GPIO_ENABLE, (0x001 << 8)
    	.set PULL_UP_ENABLE, (1 << 1)
    	.set PULL_UP_SELECT, (1 << 0)
    	.set DRIVE_STR, (1 << 6)
    	.set PORT_CTRL_FLAGS, (DRIVE_STR | GPIO_ENABLE ) 
    
    	ldr r6, = 0x4004B000
    	ldr r0, = PORT_CTRL_FLAGS
    	str r0, [r6]
    
    	ldr r6, = 0x400FF094 @ GPIOC_PDDR
    	ldr r0, = 0xFFFFFFFF @ All as output
    	str r0, [r6]
    
    	ldr r6, = 0x400FF080 @ GPIOC_PDOR
    	ldr r0, = 0xFFFFFFFF @ All as high
    	str r0, [r6]
    
    loop:
    	b loop
    My ideas are:
    1. I handle the Watch Dog badly.
    2. I setup pin 5 of port C badly.
    4. Build script is invalid because of following error printed by Teensy Loader.
    Code:
    15:12:43: File "crt0.hex". 1184 bytes, 0% used
    15:12:43: elf size appears to be 0
    15:12:43: Code size from .elf file = 0
    Last edited by glock45; 05-11-2014 at 06:18 PM.

  2. #2
    I updated the source code. All files are available here: https://gist.github.com/glock45/63c421639deb492dabe3
    Still no success. Putting more data so maybe someone will notice bugs.

    Results of -size crt0.elf:

    Click image for larger version. 

Name:	Screen Shot 2014-05-15 at 09.18.20.png 
Views:	159 
Size:	14.2 KB 
ID:	1989

    Results of 'arm-none-eabi-objdump -d crt0.o': http://pastebin.com/CmWstXBF
    Results of 'arm-none-eabi-objdump -d crt0.elf': http://pastebin.com/9xbeFzns

    Teensy Loader version: 1.17
    Build host: osx 10.9.2
    Build tools: arm toolchain from Teensyduion 1.18

    Questions:
    1. Should I initialise clock after the reset to get my application working ? ( It's just turning the LED/GPIO on so I shouldn't do anything more than enabling PORTC clock ).
    2. Does the boot-loader modify somehow my code or expects predefined symbols ?
    3. Do you know what is the reason why Teensy Loader prints messages "elf size appears to be 0" and "Code size from .elf file = 0" ?

    Best
    Last edited by glock45; 05-15-2014 at 08:17 AM.

  3. #3
    Name:  IMG_0470_medium.png
Views: 1030
Size:  112.5 KB

    As you can see it works now I did a mistake with addressing PORTC_PCR5 register. The correct value of address is [0x4004B014].

    Here is a working version of the source code:

    Application:
    Code:
        
        .syntax unified
        .thumb    
        .section ".vectors"
        .global _start
        .global _vectors
    
    _vectors:    
    _start:
    
        /* Initial Stack Pointer and Reset Vector */
    
        .long 0x20000000             
        .long _startup
      
        .org 0x400
    
        /* Flash Configuration */
    
        .long   0xFFFFFFFF
        .long   0xFFFFFFFF
        .long   0xFFFFFFFF
        .long   0xFFFFFFFE
    
        .thumb
        .section ".startup","x",%progbits
        .thumb_func
        .global _startup
    
    _startup:
    
        /* Suggested register initialisation from "Definitive guide to Cortex-M3 guide" */
        
        mov     r0,#0
        mov     r1,#0
        mov     r2,#0
        mov     r3,#0
        mov     r4,#0
        mov     r5,#0
        mov     r6,#0
        mov     r7,#0
        mov     r8,#0
        mov     r9,#0
        mov     r10,#0
        mov     r11,#0
        mov     r12,#0
    
        CPSID i
    
    unlock_watchdog:
    
        ldr r6, = 0x4005200e @ WDOG_UNLOCK doc: K20P64M50SF0RM.pdf ( Page: 423 )
        ldr r0, = 0xc520
        strh r0, [r6]
        ldr r0, = 0xd928
        strh r0, [r6]
    
    disable_watchdog:
    
        ldr r6, = 0x40052000 @ WDOG_STCTRLH doc: K20P64M50SF0RM.pdf ( Page: 418 )
        ldr r0, = 0x01d2
        strh r0, [r6]
    
        CPSIE i
    
    led_on:
    
        ldr r6, = 0x40048038 @ SIM_SCGC5  doc: K20P64M50SF0RM.pdf ( Page 239 )
        ldr r0, = 0x00043F82 @ Clocks active to all GPIO
        str r0, [r6]
    
        .set GPIO_ENABLE, (0x001 << 8)
        .set PULL_UP_ENABLE, (1 << 1)
        .set PULL_UP_SELECT, (1 << 0)
        .set DRIVE_STR, (1 << 6)
        .set PORT_CTRL_FLAGS, ( DRIVE_STR | GPIO_ENABLE | PULL_UP_ENABLE | PULL_UP_SELECT) @ doc: K20P64M50SF0RM.pdf ( Page 213 )
    
        ldr r6, = 0x4004B014 @ PORTC_PCR5 doc: K20P64M50SF0RM.pdf ( Pages 210, 213 )
        ldr r0, = PORT_CTRL_FLAGS
        str r0, [r6]
    
        ldr r6, = 0x400FF094 @ GPIOC_PDDR doc: K20P64M50SF0RM.pdf ( Pages: 1181, 1185 )
        ldr r0, = 0xFFFFFFFF @ All as output
        str r0, [r6]
    
        ldr r6, = 0x400FF080 @ GPIOC_PDOR doc: K20P64M50SF0RM.pdf ( Pages: 1180, 1182 )
        ldr r0, = 0xFFFFFFFF @ All as high
        str r0, [r6]
    
    loop:
        b loop
        .end

    Build script:
    Code:
    rm -f *.o *.d *.elf *.hex *.bin *.out
    ./bin/arm-none-eabi-as -g -mcpu=cortex-m4 -mthumb -o crt0.o crt0.s
    ./bin/arm-none-eabi-ld -T linker.ld -o crt0.elf crt0.o
    ./bin/arm-none-eabi-objcopy -O ihex -R .eeprom crt0.elf crt0.hex
    ./bin/arm-none-eabi-objcopy -O binary -R .eeprom crt0.elf crt0.bin
    Linker:
    Code:
    OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
    OUTPUT_ARCH(arm)
    ENTRY(_start)
    
    EXTERN(_vectors);
    
    MEMORY
    {
        FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
        SRAM (W!RX) : ORIGIN = 0x20000000, LENGTH = 64K
    }
    
    SECTIONS 
    {
    	.text :
    	{
    		CREATE_OBJECT_SYMBOLS
    		_vectors = .;
    		*(.vectors)
    		*(.startup)
    		*(.text)
    		*(.text.*)
    	} > FLASH
    
    }
    Last edited by glock45; 05-15-2014 at 05:29 PM.

  4. #4
    Senior Member+
    Join Date
    Jul 2013
    Posts
    296
    That's very nice!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •