1 /******************************************************************************
2 * Filename: cpu.c
3 * Revised: 2015-11-03 19:58:00 +0100 (Tue, 03 Nov 2015)
4 * Revision: 44946
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 #if !defined(DOXYGEN)
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 //
63 //! Disable all external interrupts
64 //
65 //*****************************************************************************
66 #if defined(__IAR_SYSTEMS_ICC__) || defined(DOXYGEN)
67 uint32_t
CPUcpsid(void)68 CPUcpsid(void)
69 {
70 //
71 // Read PRIMASK and disable interrupts.
72 //
73 __asm(" mrs r0, PRIMASK\n"
74 " cpsid i\n");
75
76 //
77 // "Warning[Pe940]: missing return statement at end of non-void function"
78 // is suppressed here to avoid putting a "bx lr" in the inline assembly
79 // above and a superfluous return statement here.
80 //
81 #pragma diag_suppress=Pe940
82 }
83 #pragma diag_default=Pe940
84 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
85 __asm uint32_t
CPUcpsid(void)86 CPUcpsid(void)
87 {
88 //
89 // Read PRIMASK and disable interrupts.
90 //
91 mrs r0, PRIMASK;
92 cpsid i;
93 bx lr
94 }
95 #elif defined(__TI_COMPILER_VERSION__)
96 uint32_t
CPUcpsid(void)97 CPUcpsid(void)
98 {
99 //
100 // Read PRIMASK and disable interrupts.
101 //
102 __asm(" mrs r0, PRIMASK\n"
103 " cpsid i\n"
104 " bx lr\n");
105
106 //
107 // The following keeps the compiler happy, because it wants to see a
108 // return value from this function. It will generate code to return
109 // a zero. However, the real return is the "bx lr" above, so the
110 // return(0) is never executed and the function returns with the value
111 // you expect in R0.
112 //
113 return(0);
114 }
115 #else
116 uint32_t __attribute__((naked))
CPUcpsid(void)117 CPUcpsid(void)
118 {
119 uint32_t ui32Ret;
120
121 //
122 // Read PRIMASK and disable interrupts
123 //
124 __asm(" mrs r0, PRIMASK\n"
125 " cpsid i\n"
126 " bx lr\n"
127 : "=r"(ui32Ret));
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(ui32Ret);
136 }
137 #endif
138
139 //*****************************************************************************
140 //
141 //! Get the current interrupt state
142 //
143 //*****************************************************************************
144 #if defined(__IAR_SYSTEMS_ICC__) || defined(DOXYGEN)
145 uint32_t
CPUprimask(void)146 CPUprimask(void)
147 {
148 //
149 // Read PRIMASK.
150 //
151 __asm(" mrs r0, PRIMASK\n");
152
153 //
154 // "Warning[Pe940]: missing return statement at end of non-void function"
155 // is suppressed here to avoid putting a "bx lr" in the inline assembly
156 // above and a superfluous return statement here.
157 //
158 #pragma diag_suppress=Pe940
159 }
160 #pragma diag_default=Pe940
161 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
162 __asm uint32_t
CPUprimask(void)163 CPUprimask(void)
164 {
165 //
166 // Read PRIMASK.
167 //
168 mrs r0, PRIMASK;
169 bx lr
170 }
171 #elif defined(__TI_COMPILER_VERSION__)
172 uint32_t
CPUprimask(void)173 CPUprimask(void)
174 {
175 //
176 // Read PRIMASK.
177 //
178 __asm(" mrs r0, PRIMASK\n"
179 " bx lr\n");
180
181 //
182 // The following keeps the compiler happy, because it wants to see a
183 // return value from this function. It will generate code to return
184 // a zero. However, the real return is the "bx lr" above, so the
185 // return(0) is never executed and the function returns with the value
186 // you expect in R0.
187 //
188 return(0);
189 }
190 #else
191 uint32_t __attribute__((naked))
CPUprimask(void)192 CPUprimask(void)
193 {
194 uint32_t ui32Ret;
195
196 //
197 // Read PRIMASK
198 //
199 __asm(" mrs r0, PRIMASK\n"
200 " bx lr\n"
201 : "=r"(ui32Ret));
202
203 //
204 // The return is handled in the inline assembly, but the compiler will
205 // still complain if there is not an explicit return here (despite the fact
206 // that this does not result in any code being produced because of the
207 // naked attribute).
208 //
209 return(ui32Ret);
210 }
211 #endif
212
213 //*****************************************************************************
214 //
215 //! Enable all external interrupts
216 //
217 //*****************************************************************************
218 #if defined(__IAR_SYSTEMS_ICC__) || defined(DOXYGEN)
219 uint32_t
CPUcpsie(void)220 CPUcpsie(void)
221 {
222 //
223 // Read PRIMASK and enable interrupts.
224 //
225 __asm(" mrs r0, PRIMASK\n"
226 " cpsie i\n");
227
228 //
229 // "Warning[Pe940]: missing return statement at end of non-void function"
230 // is suppressed here to avoid putting a "bx lr" in the inline assembly
231 // above and a superfluous return statement here.
232 //
233 #pragma diag_suppress=Pe940
234 }
235 #pragma diag_default=Pe940
236 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
237 __asm uint32_t
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 #elif defined(__TI_COMPILER_VERSION__)
248 uint32_t
CPUcpsie(void)249 CPUcpsie(void)
250 {
251 //
252 // Read PRIMASK and enable interrupts.
253 //
254 __asm(" mrs r0, PRIMASK\n"
255 " cpsie i\n"
256 " bx lr\n");
257
258 //
259 // The following keeps the compiler happy, because it wants to see a
260 // return value from this function. It will generate code to return
261 // a zero. However, the real return is the "bx lr" above, so the
262 // return(0) is never executed and the function returns with the value
263 // you expect in R0.
264 //
265 return(0);
266 }
267 #else
268 uint32_t __attribute__((naked))
CPUcpsie(void)269 CPUcpsie(void)
270 {
271 uint32_t ui32Ret;
272
273 //
274 // Read PRIMASK and enable interrupts.
275 //
276 __asm(" mrs r0, PRIMASK\n"
277 " cpsie i\n"
278 " bx lr\n"
279 : "=r"(ui32Ret));
280
281 //
282 // The return is handled in the inline assembly, but the compiler will
283 // still complain if there is not an explicit return here (despite the fact
284 // that this does not result in any code being produced because of the
285 // naked attribute).
286 //
287 return(ui32Ret);
288 }
289 #endif
290
291 //*****************************************************************************
292 //
293 //! Get the interrupt priority disable level
294 //
295 //*****************************************************************************
296 #if defined(__IAR_SYSTEMS_ICC__) || defined(DOXYGEN)
297 uint32_t
CPUbasepriGet(void)298 CPUbasepriGet(void)
299 {
300 //
301 // Read BASEPRI.
302 //
303 __asm(" mrs r0, BASEPRI\n");
304
305 //
306 // "Warning[Pe940]: missing return statement at end of non-void function"
307 // is suppressed here to avoid putting a "bx lr" in the inline assembly
308 // above and a superfluous return statement here.
309 //
310 #pragma diag_suppress=Pe940
311 }
312 #pragma diag_default=Pe940
313 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
314 __asm uint32_t
CPUbasepriGet(void)315 CPUbasepriGet(void)
316 {
317 //
318 // Read BASEPRI.
319 //
320 mrs r0, BASEPRI;
321 bx lr
322 }
323 #elif defined(__TI_COMPILER_VERSION__)
324 uint32_t
CPUbasepriGet(void)325 CPUbasepriGet(void)
326 {
327 //
328 // Read BASEPRI.
329 //
330 __asm(" mrs r0, BASEPRI\n"
331 " bx lr\n");
332
333 //
334 // The following keeps the compiler happy, because it wants to see a
335 // return value from this function. It will generate code to return
336 // a zero. However, the real return is the "bx lr" above, so the
337 // return(0) is never executed and the function returns with the value
338 // you expect in R0.
339 //
340 return(0);
341 }
342 #else
343 uint32_t __attribute__((naked))
CPUbasepriGet(void)344 CPUbasepriGet(void)
345 {
346 uint32_t ui32Ret;
347
348 //
349 // Read BASEPRI.
350 //
351 __asm(" mrs r0, BASEPRI\n"
352 " bx lr\n"
353 : "=r"(ui32Ret));
354
355 //
356 // The return is handled in the inline assembly, but the compiler will
357 // still complain if there is not an explicit return here (despite the fact
358 // that this does not result in any code being produced because of the
359 // naked attribute).
360 //
361 return(ui32Ret);
362 }
363 #endif
364
365 //*****************************************************************************
366 //
367 //! Provide a small delay
368 //
369 //*****************************************************************************
370 #if defined(__IAR_SYSTEMS_ICC__) || defined(DOXYGEN)
371 void
CPUdelay(uint32_t ui32Count)372 CPUdelay(uint32_t ui32Count)
373 {
374 //
375 // Delay the specified number of times (3 cycles pr. loop)
376 //
377 __asm("CPUdelay:\n"
378 " subs r0, #1\n"
379 " bne.n CPUdelay\n"
380 " bx lr");
381 #pragma diag_suppress=Pe940
382 }
383 #pragma diag_default=Pe940
384 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
385 __asm void
CPUdelay(uint32_t ui32Count)386 CPUdelay(uint32_t ui32Count)
387 {
388 //
389 // Delay the specified number of times (3 cycles pr. loop)
390 //
391 CPUdel
392 subs r0, #1;
393 bne CPUdel;
394 bx lr;
395 }
396 #elif defined(__TI_COMPILER_VERSION__)
397 //
398 // For CCS implement this function in pure assembly. This prevents the TI
399 // compiler from doing funny things with the optimizer.
400 //
401 //
402 // Delay the specified number of times (3 cycles pr. loop)
403 //
404 __asm(" .sect \".text:NOROM_CPUdelay\"\n"
405 " .clink\n"
406 " .thumbfunc NOROM_CPUdelay\n"
407 " .thumb\n"
408 " .global NOROM_CPUdelay\n"
409 "NOROM_CPUdelay:\n"
410 " subs r0, #1\n"
411 " bne.n NOROM_CPUdelay\n"
412 " bx lr\n");
413 #else
414 void __attribute__((naked))
CPUdelay(uint32_t ui32Count)415 CPUdelay(uint32_t ui32Count)
416 {
417 //
418 // Delay the specified number of times (3 cycles pr. loop)
419 //
420 __asm(" subs r0, #1\n"
421 " bne NOROM_CPUdelay\n"
422 " bx lr");
423 }
424 #endif
425