1 //*****************************************************************************
2 //
3 // cpu.c - Instruction wrappers for special CPU instructions needed by the
4 //         drivers.
5 //
6 // Copyright (c) 2006-2011 Texas Instruments Incorporated.  All rights reserved.
7 // Software License Agreement
8 //
9 // Texas Instruments (TI) is supplying this software for use solely and
10 // exclusively on TI's microcontroller products. The software is owned by
11 // TI and/or its suppliers, and is protected under applicable copyright
12 // laws. You may not combine this software with "viral" open-source
13 // software in order to form a larger program.
14 //
15 // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
16 // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
17 // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
19 // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
20 // DAMAGES, FOR ANY REASON WHATSOEVER.
21 //
22 // This is part of revision 8264 of the Stellaris Peripheral Driver Library.
23 //
24 //*****************************************************************************
25 
26 #include "driverlib/cpu.h"
27 
28 //*****************************************************************************
29 //
30 // Wrapper function for the CPSID instruction.  Returns the state of PRIMASK
31 // on entry.
32 //
33 //*****************************************************************************
34 #if defined(codered) || defined(gcc) || defined(sourcerygxx)
35 unsigned long __attribute__((naked))
CPUcpsid(void)36 CPUcpsid(void)
37 {
38     unsigned long ulRet;
39 
40     //
41     // Read PRIMASK and disable interrupts.
42     //
43     __asm("    mrs     r0, PRIMASK\n"
44           "    cpsid   i\n"
45           "    bx      lr\n"
46           : "=r" (ulRet));
47 
48     //
49     // The return is handled in the inline assembly, but the compiler will
50     // still complain if there is not an explicit return here (despite the fact
51     // that this does not result in any code being produced because of the
52     // naked attribute).
53     //
54     return(ulRet);
55 }
56 #endif
57 #if defined(ewarm)
58 unsigned long
CPUcpsid(void)59 CPUcpsid(void)
60 {
61     //
62     // Read PRIMASK and disable interrupts.
63     //
64     __asm("    mrs     r0, PRIMASK\n"
65           "    cpsid   i\n");
66 
67     //
68     // "Warning[Pe940]: missing return statement at end of non-void function"
69     // is suppressed here to avoid putting a "bx lr" in the inline assembly
70     // above and a superfluous return statement here.
71     //
72 #pragma diag_suppress=Pe940
73 }
74 #pragma diag_default=Pe940
75 #endif
76 #if defined(rvmdk) || defined(__ARMCC_VERSION)
77 __asm unsigned long
CPUcpsid(void)78 CPUcpsid(void)
79 {
80     //
81     // Read PRIMASK and disable interrupts.
82     //
83     mrs     r0, PRIMASK;
84     cpsid   i;
85     bx      lr
86 }
87 #endif
88 #if defined(ccs)
89 unsigned long
CPUcpsid(void)90 CPUcpsid(void)
91 {
92     //
93     // Read PRIMASK and disable interrupts.
94     //
95     __asm("    mrs     r0, PRIMASK\n"
96           "    cpsid   i\n"
97           "    bx      lr\n");
98 
99     //
100     // The following keeps the compiler happy, because it wants to see a
101     // return value from this function.  It will generate code to return
102     // a zero.  However, the real return is the "bx lr" above, so the
103     // return(0) is never executed and the function returns with the value
104     // you expect in R0.
105     //
106     return(0);
107 }
108 #endif
109 
110 //*****************************************************************************
111 //
112 // Wrapper function returning the state of PRIMASK (indicating whether
113 // interrupts are enabled or disabled).
114 //
115 //*****************************************************************************
116 #if defined(codered) || defined(gcc) || defined(sourcerygxx)
117 unsigned long __attribute__((naked))
CPUprimask(void)118 CPUprimask(void)
119 {
120     unsigned long ulRet;
121 
122     //
123     // Read PRIMASK and disable interrupts.
124     //
125     __asm("    mrs     r0, PRIMASK\n"
126           "    bx      lr\n"
127           : "=r" (ulRet));
128 
129     //
130     // The return is handled in the inline assembly, but the compiler will
131     // still complain if there is not an explicit return here (despite the fact
132     // that this does not result in any code being produced because of the
133     // naked attribute).
134     //
135     return(ulRet);
136 }
137 #endif
138 #if defined(ewarm)
139 unsigned long
CPUprimask(void)140 CPUprimask(void)
141 {
142     //
143     // Read PRIMASK and disable interrupts.
144     //
145     __asm("    mrs     r0, PRIMASK\n");
146 
147     //
148     // "Warning[Pe940]: missing return statement at end of non-void function"
149     // is suppressed here to avoid putting a "bx lr" in the inline assembly
150     // above and a superfluous return statement here.
151     //
152 #pragma diag_suppress=Pe940
153 }
154 #pragma diag_default=Pe940
155 #endif
156 #if defined(rvmdk) || defined(__ARMCC_VERSION)
157 __asm unsigned long
CPUprimask(void)158 CPUprimask(void)
159 {
160     //
161     // Read PRIMASK and disable interrupts.
162     //
163     mrs     r0, PRIMASK;
164     bx      lr
165 }
166 #endif
167 #if defined(ccs)
168 unsigned long
CPUprimask(void)169 CPUprimask(void)
170 {
171     //
172     // Read PRIMASK and disable interrupts.
173     //
174     __asm("    mrs     r0, PRIMASK\n"
175           "    bx      lr\n");
176 
177     //
178     // The following keeps the compiler happy, because it wants to see a
179     // return value from this function.  It will generate code to return
180     // a zero.  However, the real return is the "bx lr" above, so the
181     // return(0) is never executed and the function returns with the value
182     // you expect in R0.
183     //
184     return(0);
185 }
186 #endif
187 
188 //*****************************************************************************
189 //
190 // Wrapper function for the CPSIE instruction.  Returns the state of PRIMASK
191 // on entry.
192 //
193 //*****************************************************************************
194 #if defined(codered) || defined(gcc) || defined(sourcerygxx)
195 unsigned long __attribute__((naked))
CPUcpsie(void)196 CPUcpsie(void)
197 {
198     unsigned long ulRet;
199 
200     //
201     // Read PRIMASK and enable interrupts.
202     //
203     __asm("    mrs     r0, PRIMASK\n"
204           "    cpsie   i\n"
205           "    bx      lr\n"
206           : "=r" (ulRet));
207 
208     //
209     // The return is handled in the inline assembly, but the compiler will
210     // still complain if there is not an explicit return here (despite the fact
211     // that this does not result in any code being produced because of the
212     // naked attribute).
213     //
214     return(ulRet);
215 }
216 #endif
217 #if defined(ewarm)
218 unsigned long
CPUcpsie(void)219 CPUcpsie(void)
220 {
221     //
222     // Read PRIMASK and enable interrupts.
223     //
224     __asm("    mrs     r0, PRIMASK\n"
225           "    cpsie   i\n");
226 
227     //
228     // "Warning[Pe940]: missing return statement at end of non-void function"
229     // is suppressed here to avoid putting a "bx lr" in the inline assembly
230     // above and a superfluous return statement here.
231     //
232 #pragma diag_suppress=Pe940
233 }
234 #pragma diag_default=Pe940
235 #endif
236 #if defined(rvmdk) || defined(__ARMCC_VERSION)
237 __asm unsigned long
CPUcpsie(void)238 CPUcpsie(void)
239 {
240     //
241     // Read PRIMASK and enable interrupts.
242     //
243     mrs     r0, PRIMASK;
244     cpsie   i;
245     bx      lr
246 }
247 #endif
248 #if defined(ccs)
249 unsigned long
CPUcpsie(void)250 CPUcpsie(void)
251 {
252     //
253     // Read PRIMASK and enable interrupts.
254     //
255     __asm("    mrs     r0, PRIMASK\n"
256           "    cpsie   i\n"
257           "    bx      lr\n");
258 
259     //
260     // The following keeps the compiler happy, because it wants to see a
261     // return value from this function.  It will generate code to return
262     // a zero.  However, the real return is the "bx lr" above, so the
263     // return(0) is never executed and the function returns with the value
264     // you expect in R0.
265     //
266     return(0);
267 }
268 #endif
269 
270 //*****************************************************************************
271 //
272 // Wrapper function for the WFI instruction.
273 //
274 //*****************************************************************************
275 #if defined(codered) || defined(gcc) || defined(sourcerygxx)
276 void __attribute__((naked))
CPUwfi(void)277 CPUwfi(void)
278 {
279     //
280     // Wait for the next interrupt.
281     //
282     __asm("    wfi\n"
283           "    bx      lr\n");
284 }
285 #endif
286 #if defined(ewarm)
287 void
CPUwfi(void)288 CPUwfi(void)
289 {
290     //
291     // Wait for the next interrupt.
292     //
293     __asm("    wfi\n");
294 }
295 #endif
296 #if defined(rvmdk) || defined(__ARMCC_VERSION)
297 __asm void
CPUwfi(void)298 CPUwfi(void)
299 {
300     //
301     // Wait for the next interrupt.
302     //
303     wfi;
304     bx      lr
305 }
306 #endif
307 #if defined(ccs)
308 void
CPUwfi(void)309 CPUwfi(void)
310 {
311     //
312     // Wait for the next interrupt.
313     //
314     __asm("    wfi\n");
315 }
316 #endif
317 
318 //*****************************************************************************
319 //
320 // Wrapper function for writing the BASEPRI register.
321 //
322 //*****************************************************************************
323 #if defined(codered) || defined(gcc) || defined(sourcerygxx)
324 void __attribute__((naked))
CPUbasepriSet(unsigned long ulNewBasepri)325 CPUbasepriSet(unsigned long ulNewBasepri)
326 {
327 
328     //
329     // Set the BASEPRI register
330     //
331     __asm("    msr     BASEPRI, r0\n"
332           "    bx      lr\n");
333 }
334 #endif
335 #if defined(ewarm)
336 void
CPUbasepriSet(unsigned long ulNewBasepri)337 CPUbasepriSet(unsigned long ulNewBasepri)
338 {
339     //
340     // Set the BASEPRI register
341     //
342     __asm("    msr     BASEPRI, r0\n");
343 }
344 #endif
345 #if defined(rvmdk) || defined(__ARMCC_VERSION)
346 __asm void
CPUbasepriSet(unsigned long ulNewBasepri)347 CPUbasepriSet(unsigned long ulNewBasepri)
348 {
349     //
350     // Set the BASEPRI register
351     //
352     msr     BASEPRI, r0;
353     bx      lr
354 }
355 #endif
356 #if defined(ccs)
357 void
CPUbasepriSet(unsigned long ulNewBasepri)358 CPUbasepriSet(unsigned long ulNewBasepri)
359 {
360     //
361     // Set the BASEPRI register
362     //
363     __asm("    msr     BASEPRI, r0\n");
364 }
365 #endif
366 
367 //*****************************************************************************
368 //
369 // Wrapper function for reading the BASEPRI register.
370 //
371 //*****************************************************************************
372 #if defined(codered) || defined(gcc) || defined(sourcerygxx)
373 unsigned long __attribute__((naked))
CPUbasepriGet(void)374 CPUbasepriGet(void)
375 {
376     unsigned long ulRet;
377 
378     //
379     // Read BASEPRI
380     //
381     __asm("    mrs     r0, BASEPRI\n"
382           "    bx      lr\n"
383           : "=r" (ulRet));
384 
385     //
386     // The return is handled in the inline assembly, but the compiler will
387     // still complain if there is not an explicit return here (despite the fact
388     // that this does not result in any code being produced because of the
389     // naked attribute).
390     //
391     return(ulRet);
392 }
393 #endif
394 #if defined(ewarm)
395 unsigned long
CPUbasepriGet(void)396 CPUbasepriGet(void)
397 {
398     //
399     // Read BASEPRI
400     //
401     __asm("    mrs     r0, BASEPRI\n");
402 
403     //
404     // "Warning[Pe940]: missing return statement at end of non-void function"
405     // is suppressed here to avoid putting a "bx lr" in the inline assembly
406     // above and a superfluous return statement here.
407     //
408 #pragma diag_suppress=Pe940
409 }
410 #pragma diag_default=Pe940
411 #endif
412 #if defined(rvmdk) || defined(__ARMCC_VERSION)
413 __asm unsigned long
CPUbasepriGet(void)414 CPUbasepriGet(void)
415 {
416     //
417     // Read BASEPRI
418     //
419     mrs     r0, BASEPRI;
420     bx      lr
421 }
422 #endif
423 #if defined(ccs)
424 unsigned long
CPUbasepriGet(void)425 CPUbasepriGet(void)
426 {
427     //
428     // Read BASEPRI
429     //
430     __asm("    mrs     r0, BASEPRI\n"
431           "    bx      lr\n");
432 
433     //
434     // The following keeps the compiler happy, because it wants to see a
435     // return value from this function.  It will generate code to return
436     // a zero.  However, the real return is the "bx lr" above, so the
437     // return(0) is never executed and the function returns with the value
438     // you expect in R0.
439     //
440     return(0);
441 }
442 #endif
443