; *********************************************************************** ; * * ; * Flash the LEDs on the DSLMU Microcontroller Board * ; * Third 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. ; The difference between this program and flash-v2.s is that this program ; uses the registers reserved by the ATPCS for local variables: R4-R11. ; This means that it is up to the CALLER to preserve the contents of these ; registers, and to restore their value afterwards. ; ----------------------------------------------------------------------- ; 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" mov ip, sp ; Save the "caller's" stack pointer stmfd sp!, {r4, r5, fp, ip, lr, pc} ; and caller's registers sub fp, ip, #4 ; Set up the stack frame pointer ; Although "main" is technically a function, this particular ; function has an infinite loop and so never returns to its caller. ; Thus, strictly speaking, the above three lines are not really ; needed, since there is no caller (no operating system) to return ; to. In other words, you can safely delete the above three ; lines, but ONLY in the function main. ldr r4, =portA ; Load address of Port A into R4 ; (ie, the value of the constant ; LED_port) into register R4 main_loop: ; Start of the infinite loop mov r5, #Value1 ; Load value to turn LEDs on strb r5, [r4] ; Write the byte to Port A ldr r0, =WaitVal ; R0 = number of loops to wait bl delay ; Delay the program... mov r5, #Value2 ; Load value to turn LEDs off strb r5, [r4] ; Write the byte to Port A ldr r0, =WaitVal ; R0 = number of loops to wait bl delay ; Delay the program... 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