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