2 @ This code expects to find a function named 'swiDispatchC' (which should be
3 @ in swi.c) to dispatch any functions that aren't written in assembly.
4 @ (What nut-case picked '@' as the comment character for .s files?)
12 @ Equates for GPIO0 registers
14 .set GPIO0_IOPIN, 0xe0028000
15 .set GPIO0_IOSET, 0xe0028004
16 .set GPIO0_IODIR, 0xe0028008
17 .set GPIO0_IOCLR, 0xe002800c
18 .set GPIO_IO_P11, 0x00000800
21 @ No check for Thumb mode. The LPC2148 demo code doesn't do Thumb
24 stmfd sp!, {r4, lr} @ Save r4, lr
25 ldr r4, [lr, #-4] @ Fetch the SWI instruction that invoked us
26 bic r4, r4, #0xff000000 @ Clear top 8 bits leaving swi "comment field"=number
27 cmp r4, #SWI_LAST @ <= SWI_LAST, handled in assembly, otherwise, in C handler
28 ldrls pc, [pc, r4, lsl #2] @ If <= SWI_LAST, we're handling it in assembly
29 b swiDispatchToC @ Not handled in here, switch to the C handler
32 @ Dispatch table for functions in assembly. The swiEntriesStart label isn't
33 @ referenced directly by the code. Rather, it must directly follow the
34 @ swiDispatch code, because it is relatively referenced.
37 .word swiPYP @ 0 - FreeRTOS Yield Process
38 .word LED2Set @ 1 - Set LED2 state, return previous state
39 .word LED2On @ 2 - Turn LED2 on, return previous state
40 .word LED2Off @ 3 - Turn LED2 off, return previous state
41 .word LED2Toggle @ 4 - Toggle LED2, return previous state
43 .set SWI_LAST, ((swiEntriesEnd-swiEntriesStart)/4)-1
46 @ FreeRTOS uses SWI to yield process, but it's greedy and wants SWI all to its
47 @ self. So... Special handling it is!
50 ldmfd sp!, {r4, lr} @ Recover r4, lr
51 b vPortYieldProcessor @ Yield... yield like the wind!
54 @ Values are returned in r0. LED2 is hardwired in this code (bad programmer!) Also
55 @ remember that LED2 (and LED1) have their anodes tied to +3.3V, so we have to drive
56 @ the port pin LOW to turn them on. When the caller wants to turn an LED off, it
57 @ passes in a non-zero value (keeping the same software logic as the hardware logic)
60 stmfd sp!, {r1} @ Save r1
61 cmp r0, #0 @ Turn LED2 off?
62 ldreq r4, =GPIO0_IOCLR @ Get GPIO0_IOCLR address (0 == on)
63 ldrne r4, =GPIO0_IOSET @ Get GPIO0_IOSET address (!0 == off)
64 ldr r0, =GPIO0_IOPIN @ Load GPIO0_IOPIN address
65 ldr r0, [r0] @ Get GPIO0_IOPIN contents
66 ldr r1, =GPIO_IO_P11 @ Constant for port pin LED2 attached to
67 and r0, r0, r1 @ R0 has bit that reflects LED2 current state
68 str r1, [r4] @ Set LED2 on
69 ldmfd sp!, {r1} @ Recover r1
70 b swiExit @ Exit SWI handler
73 stmfd sp!, {r1} @ Save r1
74 ldr r0, =GPIO0_IOPIN @ Load GPIO0_IOPIN address
75 ldr r0, [r0] @ Get GPIO0_IOPIN contents
76 ldr r1, =GPIO_IO_P11 @ Constant for port pin LED2 attached to
77 and r0, r0, r1 @ R0 has bit that reflects LED2 current state
78 ldr r4, =GPIO0_IOCLR @ Get GPIO0_IOCLR address
79 str r1, [r4] @ Set LED2 on
80 ldmfd sp!, {r1} @ Recover r1
81 b swiExit @ Exit SWI handler
84 stmfd sp!, {r1} @ Save r1
85 ldr r0, =GPIO0_IOPIN @ Load GPIO0_IOPIN address
86 ldr r0, [r0] @ Get GPIO0_IOPIN contents
87 ldr r1, =GPIO_IO_P11 @ Constant for port pin LED2 attached to
88 and r0, r0, r1 @ R0 has bit that reflects LED2 current state
89 ldr r4, =GPIO0_IOSET @ Get GPIO0_IOSET address
90 str r1, [r4] @ Set LED2 off
91 ldmfd sp!, {r1} @ Recover r1
92 b swiExit @ Exit SWI handler
95 stmfd sp!, {r1} @ Save r1
96 ldr r0, =GPIO0_IOPIN @ Load GPIO0_IOPIN address
97 ldr r0, [r0] @ Get GPIO0_IOPIN contents
98 ldr r1, =GPIO_IO_P11 @ Constant for port pin LED2 attached to
99 ands r0, r0, r1 @ R0 has bit that reflects LED2 current state
100 ldrne r4, =GPIO0_IOCLR @ Get GPIO0_IOCLR address (!0 == off, so turn on)
101 ldreq r4, =GPIO0_IOSET @ Get GPIO0_IOSET address (0 == on, so turn off)
102 str r1, [r4] @ Set LED2 off
103 ldmfd sp!, {r1} @ Recover r1
104 b swiExit @ Exit SWI handler
107 @ Not an internal function, try the C dispatch handler. r0, r1, r2 will be
108 @ passed through as set. r3 will contain the SWI number. Return value will
112 stmfd sp!,{r1-r12, lr} @ Save r1..r12, lr on stack
113 mrs r12, spsr @ Saved Process Status Register (SPSR) to r12
114 stmfd sp!, {r12} @ Save r12
115 ldr r12, =swiDispatchC @ Get the address of the C handler function
116 mov r3, r4 @ Pass SWI number as parameter in r3
117 mov lr, pc @ Save current PC to lr
118 bx r12 @ Branch to r12 (C handler function), return to next instruction
119 ldmfd sp!, {r12} @ Recover old SPSR to r12
120 msr spsr_cxsf, r12 @ Set SPSR from r12
121 ldmfd sp!, {r1-r12, pc}^ @ Recover r1..r12, return value in r0
125 @ Exit SWI handler. Recover r4, return to caller
128 ldmfd sp!, {r4, pc}^ @ Recover r4, return to caller