Turn the LED on with assembler code ( Teensy 3.1 )

glock45

Member
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:
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:

Screen Shot 2014-05-15 at 09.18.20.png

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:
IMG_0470_medium.png

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:
Back
Top