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