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