; *********************************************************************** ; * * ; * Flash the LEDs on the DSLMU Microcontroller Board * ; * Second Version * ; * * ; *********************************************************************** ; ; Author: John Zaitseff ; Date: 26th June, 2003 ; Version: 1.9 ; ; This program, when run on the DSLMU Microcontroller Board, flashes the ; LEDs on and off. This program is similar to flash-v2.s in Experiment 1, ; except that it has been rewritten to use the ARM Thumb Procedure Call ; Standard. Note that the DSLMU Microcontroller Board does NOT have an ; operating system---hence the need to set up a private stack. ; Please see flash-v3.s for another way of writing this program. ; ----------------------------------------------------------------------- ; Constant values used in this program .equ portA, 0x10000000 ; Address of Port A in the I/O space .equ Value1, 0b11111111 ; Value to turn LEDs on .equ Value2, 0b00000000 ; Value to turn LEDs off .equ WaitVal, 10000 ; Number of loops to wait ; ----------------------------------------------------------------------- ; Assembly-language preamble .text ; Executable code follows _start: .global _start ; "_start" is required by the linker .global main ; "main" is our main program ldr sp, =stack_top ; Initialise the stack pointer b main ; and jump to the main program ; ----------------------------------------------------------------------- ; Start of the main program ; void main (void) main: ; Entry to the function "main" ; Although "main" is technically a function, this particular ; function has an infinite loop and so never returns to its ; caller. ; Strictly speaking, a stack frame should be generated at this ; point in the program. However, since there is no operating ; system to return to, there is no need to do so AT THIS LEVEL. ; Any functions called by main MAY need to generate a stack frame ; to comply with the ATPCS. ldr r1, =portA ; Load address of Port A into R1 ; (ie, the value of the constant ; LED_port) into register R1 main_loop: ; Start of the infinite loop mov r0, #Value1 ; Load value to turn LEDs on strb r0, [r1] ; Write the byte to Port A str r1, [sp, #-4]! ; We want to continue to use R1 ; after the following function ; call, so it must be saved to the ; stack to comply with the ATPCS. ; No need to preserve R0 ldr r0, =WaitVal ; R0 = number of loops to wait bl delay ; Delay the program... ldr r1, [sp], #4 ; Restore R1 from the stack mov r0, #Value2 ; Load value to turn LEDs off strb r0, [r1] ; Write the byte to Port A str r1, [sp, #-4]! ; Preserve the value of R1. In this ; program, it would have been simpler ; to reload R1 every time (using ; "ldr ="), so this is more as an ; example of what to do... ldr r0, =WaitVal ; R0 = number of loops to wait bl delay ; Delay the program... ldr r1, [sp], #4 ; Restore R1 b main_loop ; Do this forever (or until stopped) ; ----------------------------------------------------------------------- ; Function "delay": delay program execution by wasting time in a loop ; void delay (int delaycount) delay: ; This function expects R0 to contain the number of loops for ; which to wait. It does not return any meaningful values. The ; value in R0 is destroyed. All other registers are preserved. ; No stack frame is needed or generated delay_1: subs r0, r0, #1 ; Decrement number of cycles to go bne delay_1 ; Repeat the loop if not finished mov pc, lr ; Return to the caller ; ----------------------------------------------------------------------- ; Stack space ; The DSLMU Microcontroller Board does not have an operating system ; available for your use. Among other things, an operating system would ; set up a stack. As it is, the stack pointer (register SP, ie, R13) is ; NOT initialised when the program starts running. For this reason, any ; program wishing to conform to the ARM Thumb Procedure Call Standard MUST ; set up its own stack. .bss ; Allocate uninitialised memory .align ; Make sure it is word-aligned .skip 2048 ; Allow 2KB for the stack stack_top: ; Top of stack pointer ; ----------------------------------------------------------------------- .end