forked from autosportlabs/RaceCapture-Pro_firmware
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterrupt_utils.h
270 lines (244 loc) · 7.95 KB
/
interrupt_utils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
* Defines and Macros for Interrupt-Service-Routines
* collected and partly created by
* Martin Thomas <[email protected]>
*
* Copyright 2005 M. Thomas
* No guarantees, warrantees, or promises, implied or otherwise.
* May be used for hobby or commercial purposes provided copyright
* notice remains intact.
*/
#ifndef interrupt_utils_
#define interrupt_utils_
/*
The following defines are usefull for
interrupt service routine declarations.
*/
/*
RAMFUNC
Attribute which defines a function to be located
in memory section .fastrun and called via "long calls".
See linker-skript and startup-code to see how the
.fastrun-section is handled.
The definition is not only useful for ISRs but since
ISRs should be executed fast the macro is defined in
this header.
*/
#define RAMFUNC __attribute__ ((long_call, section (".fastrun")))
/*
INTFUNC
standard attribute for arm-elf-gcc which marks
a function as ISR (for the VIC). Since gcc seems
to produce wrong code if this attribute is used in
thumb/thumb-interwork the attribute should only be
used for "pure ARM-mode" binaries.
*/
#define INTFUNC __attribute__ ((interrupt("IRQ")))
/*
NACKEDFUNC
gcc will not add any code to a function declared
"nacked". The user has to take care to save registers
and add the needed code for ISR functions. Some
macros for this tasks are provided below.
*/
#define NACKEDFUNC __attribute__((naked))
/******************************************************************************
*
* MACRO Name: ISR_STORE()
*
* Description:
* This MACRO is used upon entry to an ISR with interrupt nesting.
* Should be used together with ISR_ENABLE_NEST(). The MACRO
* performs the following steps:
*
* 1 - Save the non-banked registers r0-r12 and lr onto the IRQ stack.
*
*****************************************************************************/
#define ISR_STORE() asm volatile( \
"STMDB SP!,{R0-R12,LR}\n" )
/******************************************************************************
*
* MACRO Name: ISR_RESTORE()
*
* Description:
* This MACRO is used upon exit from an ISR with interrupt nesting.
* Should be used together with ISR_DISABLE_NEST(). The MACRO
* performs the following steps:
*
* 1 - Load the non-banked registers r0-r12 and lr from the IRQ stack.
* 2 - Adjusts resume adress
*
*****************************************************************************/
#define ISR_RESTORE() asm volatile( \
"LDMIA SP!,{R0-R12,LR}\n" \
"SUBS R15,R14,#0x0004\n" )
/******************************************************************************
*
* MACRO Name: ISR_ENABLE_NEST()
*
* Description:
* This MACRO is used upon entry from an ISR with interrupt nesting.
* Should be used after ISR_STORE.
*
*****************************************************************************/
#define ISR_ENABLE_NEST() asm volatile( \
"MRS LR, SPSR \n" \
"STMFD SP!, {LR} \n" \
"MSR CPSR_c, #0x1F \n" \
"STMFD SP!, {LR} " )
/******************************************************************************
*
* MACRO Name: ISR_DISABLE_NEST()
*
* Description:
* This MACRO is used upon entry from an ISR with interrupt nesting.
* Should be used before ISR_RESTORE.
*
*****************************************************************************/
#define ISR_DISABLE_NEST() asm volatile( \
"LDMFD SP!, {LR} \n" \
"MSR CPSR_c, #0x92 \n" \
"LDMFD SP!, {LR} \n" \
"MSR SPSR_cxsf, LR \n" )
/*
* The following marcos are from the file "armVIC.h" by:
*
* Copyright 2004, R O SoftWare
* No guarantees, warrantees, or promises, implied or otherwise.
* May be used for hobby or commercial purposes provided copyright
* notice remains intact.
*
*/
/******************************************************************************
*
* MACRO Name: ISR_ENTRY()
*
* Description:
* This MACRO is used upon entry to an ISR. The current version of
* the gcc compiler for ARM does not produce correct code for
* interrupt routines to operate properly with THUMB code. The MACRO
* performs the following steps:
*
* 1 - Adjust address at which execution should resume after servicing
* ISR to compensate for IRQ entry
* 2 - Save the non-banked registers r0-r12 and lr onto the IRQ stack.
* 3 - Get the status of the interrupted program is in SPSR.
* 4 - Push it onto the IRQ stack as well.
*
*****************************************************************************/
#define ISR_ENTRY() asm volatile(" sub lr, lr,#4\n" \
" stmfd sp!,{r0-r12,lr}\n" \
" mrs r1, spsr\n" \
" stmfd sp!,{r1}")
/******************************************************************************
*
* MACRO Name: ISR_EXIT()
*
* Description:
* This MACRO is used to exit an ISR. The current version of the gcc
* compiler for ARM does not produce correct code for interrupt
* routines to operate properly with THUMB code. The MACRO performs
* the following steps:
*
* 1 - Recover SPSR value from stack
* 2 - and restore its value
* 3 - Pop the return address & the saved general registers from
* the IRQ stack & return
*
*****************************************************************************/
#define ISR_EXIT() asm volatile(" ldmfd sp!,{r1}\n" \
" msr spsr_c,r1\n" \
" ldmfd sp!,{r0-r12,pc}^")
/******************************************************************************
*
* Function Name: disableIRQ()
*
* Description:
* This function sets the IRQ disable bit in the status register
*
* Calling Sequence:
* void
*
* Returns:
* previous value of CPSR
*
*****************************************************************************/
unsigned disableIRQ(void);
/******************************************************************************
*
* Function Name: enableIRQ()
*
* Description:
* This function clears the IRQ disable bit in the status register
*
* Calling Sequence:
* void
*
* Returns:
* previous value of CPSR
*
*****************************************************************************/
unsigned enableIRQ(void);
/******************************************************************************
*
* Function Name: restoreIRQ()
*
* Description:
* This function restores the IRQ disable bit in the status register
* to the value contained within passed oldCPSR
*
* Calling Sequence:
* void
*
* Returns:
* previous value of CPSR
*
*****************************************************************************/
unsigned restoreIRQ(unsigned oldCPSR);
/******************************************************************************
*
* Function Name: disableFIQ()
*
* Description:
* This function sets the FIQ disable bit in the status register
*
* Calling Sequence:
* void
*
* Returns:
* previous value of CPSR
*
*****************************************************************************/
unsigned disableFIQ(void);
/******************************************************************************
*
* Function Name: enableFIQ()
*
* Description:
* This function clears the FIQ disable bit in the status register
*
* Calling Sequence:
* void
*
* Returns:
* previous value of CPSR
*
*****************************************************************************/
unsigned enableFIQ(void);
/******************************************************************************
*
* Function Name: restoreFIQ()
*
* Description:
* This function restores the FIQ disable bit in the status register
* to the value contained within passed oldCPSR
*
* Calling Sequence:
* void
*
* Returns:
* previous value of CPSR
*
*****************************************************************************/
unsigned restoreFIQ(unsigned oldCPSR);
#endif