]> begriffs open source - cmsis/blob - CMSIS/CoreValidation/Source/CV_CoreFunc.c
CoreValidation: Fixed stack configuration during TC_CoreFunc_Control.
[cmsis] / CMSIS / CoreValidation / Source / CV_CoreFunc.c
1 /*-----------------------------------------------------------------------------
2  *      Name:         CV_CoreFunc.c
3  *      Purpose:      CMSIS CORE validation tests implementation
4  *-----------------------------------------------------------------------------
5  *      Copyright (c) 2017 ARM Limited. All rights reserved.
6  *----------------------------------------------------------------------------*/
7
8 #include "CV_Framework.h"
9 #include "cmsis_cv.h"
10
11 /*-----------------------------------------------------------------------------
12  *      Test implementation
13  *----------------------------------------------------------------------------*/
14
15 static volatile uint32_t irqTaken = 0U;
16 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
17 static volatile uint32_t irqActive = 0U;
18 #endif
19
20 static void TC_CoreFunc_EnDisIRQIRQHandler(void) {
21   ++irqTaken;
22 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
23   irqActive = NVIC_GetActive(WDT_IRQn);
24 #endif
25 }
26
27 static volatile uint32_t irqIPSR = 0U;
28 static volatile uint32_t irqXPSR = 0U;
29
30 static void TC_CoreFunc_IPSR_IRQHandler(void) {
31   irqIPSR = __get_IPSR();
32   irqXPSR = __get_xPSR();
33 }
34
35 /*-----------------------------------------------------------------------------
36  *      Test cases
37  *----------------------------------------------------------------------------*/
38
39 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
40 /**
41 \brief Test case: TC_CoreFunc_EnDisIRQ
42 \details
43 Check expected behavior of interrupt related control functions:
44 - __disable_irq() and __enable_irq()
45 - NVIC_EnableIRQ, NVIC_DisableIRQ,  and NVIC_GetEnableIRQ
46 - NVIC_SetPendingIRQ, NVIC_ClearPendingIRQ, and NVIC_GetPendingIRQ
47 - NVIC_GetActive (not on Cortex-M0/M0+)
48 */
49 void TC_CoreFunc_EnDisIRQ (void)
50 {
51   // Globally disable all interrupt servicing
52   __disable_irq();
53
54   // Enable the interrupt
55   NVIC_EnableIRQ(WDT_IRQn);
56   ASSERT_TRUE(NVIC_GetEnableIRQ(WDT_IRQn) != 0U);
57   
58   // Clear its pending state
59   NVIC_ClearPendingIRQ(WDT_IRQn);
60   ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) == 0U);
61
62   // Register test interrupt handler.
63   TST_IRQHandler = TC_CoreFunc_EnDisIRQIRQHandler;
64   irqTaken = 0U;
65 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
66   irqActive = UINT32_MAX;
67 #endif
68
69   // Set the interrupt pending state
70   NVIC_SetPendingIRQ(WDT_IRQn);
71   for(uint32_t i = 10U; i > 0U; --i) {}
72
73   // Interrupt is not taken
74   ASSERT_TRUE(irqTaken == 0U);
75   ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) != 0U);
76 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
77   ASSERT_TRUE(NVIC_GetActive(WDT_IRQn) == 0U);
78 #endif
79
80   // Globally enable interrupt servicing
81   __enable_irq();
82
83   for(uint32_t i = 10U; i > 0U; --i) {}
84
85   // Interrupt was taken
86   ASSERT_TRUE(irqTaken == 1U);
87 #if defined(__CORTEX_M) && (__CORTEX_M > 0)
88   ASSERT_TRUE(irqActive != 0U);
89   ASSERT_TRUE(NVIC_GetActive(WDT_IRQn) == 0U);
90 #endif
91
92   // Interrupt it not pending anymore.
93   ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) == 0U);
94
95   // Disable interrupt
96   NVIC_DisableIRQ(WDT_IRQn);
97   ASSERT_TRUE(NVIC_GetEnableIRQ(WDT_IRQn) == 0U);
98
99   // Set interrupt pending
100   NVIC_SetPendingIRQ(WDT_IRQn);
101   for(uint32_t i = 10U; i > 0U; --i) {}
102
103   // Interrupt is not taken again
104   ASSERT_TRUE(irqTaken == 1U);
105   ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) != 0U);
106   
107   // Clear interrupt pending
108   NVIC_ClearPendingIRQ(WDT_IRQn);
109   for(uint32_t i = 10U; i > 0U; --i) {}
110
111   // Interrupt it not pending anymore.
112   ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) == 0U);
113
114   // Globally disable interrupt servicing
115   __disable_irq();
116 }
117
118 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
119 /**
120 \brief Test case: TC_CoreFunc_IRQPrio
121 \details
122 Check expected behavior of interrupt priority control functions:
123 - NVIC_SetPriority, NVIC_GetPriority
124 */
125 void TC_CoreFunc_IRQPrio (void)
126 {
127   /* Test Exception Priority */
128   uint32_t orig = NVIC_GetPriority(SVCall_IRQn);
129   
130   NVIC_SetPriority(SVCall_IRQn, orig+1U);
131   uint32_t prio = NVIC_GetPriority(SVCall_IRQn);
132
133   ASSERT_TRUE(prio == orig+1U);
134   
135   NVIC_SetPriority(SVCall_IRQn, orig);
136
137   /* Test Interrupt Priority */
138   orig = NVIC_GetPriority(WDT_IRQn);
139   
140   NVIC_SetPriority(WDT_IRQn, orig+1U);
141   prio = NVIC_GetPriority(WDT_IRQn);
142
143   ASSERT_TRUE(prio == orig+1U);
144   
145   NVIC_SetPriority(WDT_IRQn, orig);
146 }
147
148 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
149 /** Helper function for TC_CoreFunc_EncDecIRQPrio
150 \details
151 The helper encodes and decodes the given priority configuration.
152 \param[in] prigroup The PRIGROUP setting to be considered for encoding/decoding.
153 \param[in] pre The preempt priority value.
154 \param[in] sub The subpriority value.
155 */
156 static void TC_CoreFunc_EncDecIRQPrio_Step(uint32_t prigroup, uint32_t pre, uint32_t sub) {
157   uint32_t prio = NVIC_EncodePriority(prigroup, pre, sub);
158   
159   uint32_t ret_pre = UINT32_MAX;
160   uint32_t ret_sub = UINT32_MAX;
161   
162   NVIC_DecodePriority(prio, prigroup, &ret_pre, &ret_sub);
163   
164   ASSERT_TRUE(ret_pre == pre);
165   ASSERT_TRUE(ret_sub == sub);
166 }
167
168 /**
169 \brief Test case: TC_CoreFunc_EncDecIRQPrio
170 \details
171 Check expected behavior of interrupt priority encoding/decoding functions:
172 - NVIC_EncodePriority, NVIC_DecodePriority
173 */
174 void TC_CoreFunc_EncDecIRQPrio (void)
175 {
176   /* Check only the valid range of PRIGROUP and preempt-/sub-priority values. */
177   static const uint32_t priobits = (__NVIC_PRIO_BITS > 7U) ? 7U : __NVIC_PRIO_BITS;
178   for(uint32_t prigroup = 7U-priobits; prigroup<7U; prigroup++) {
179     for(uint32_t pre = 0U; pre<(128U>>prigroup); pre++) {
180       for(uint32_t sub = 0U; sub<(256U>>(8U-__NVIC_PRIO_BITS+7U-prigroup)); sub++) {
181         TC_CoreFunc_EncDecIRQPrio_Step(prigroup, pre, sub);
182       }
183     }
184   }
185 }
186
187 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
188 /**
189 \brief Test case: TC_CoreFunc_IRQVect
190 \details
191 Check expected behavior of interrupt vector relocation functions:
192 - NVIC_SetVector, NVIC_GetVector
193 */
194 void TC_CoreFunc_IRQVect(void) {
195 #if defined(__VTOR_PRESENT) && __VTOR_PRESENT
196   /* relocate vector table */
197   extern uint32_t __Vectors[];
198   static uint32_t vectors[32] __ALIGNED(512);
199   
200   for(uint32_t i=0U; i<32U; i++) {
201     vectors[i] = __Vectors[i];
202   }
203   
204   const uint32_t orig_vtor = SCB->VTOR;
205   const uint32_t vtor = ((uint32_t)vectors) & SCB_VTOR_TBLOFF_Msk;
206   SCB->VTOR = vtor;
207   
208   ASSERT_TRUE(vtor == SCB->VTOR);
209   
210   /* check exception vectors */
211   extern void HardFault_Handler(void);
212   extern void SVC_Handler(void);
213   extern void PendSV_Handler(void);
214   extern void SysTick_Handler(void);
215   
216   ASSERT_TRUE(NVIC_GetVector(HardFault_IRQn) == (uint32_t)HardFault_Handler);
217   ASSERT_TRUE(NVIC_GetVector(SVCall_IRQn) == (uint32_t)SVC_Handler);
218   ASSERT_TRUE(NVIC_GetVector(PendSV_IRQn) == (uint32_t)PendSV_Handler);
219   ASSERT_TRUE(NVIC_GetVector(SysTick_IRQn) == (uint32_t)SysTick_Handler);
220   
221   /* reconfigure WDT IRQ vector */
222   extern void WDT_IRQHandler(void);
223   
224   const uint32_t wdtvec = NVIC_GetVector(WDT_IRQn);
225   ASSERT_TRUE(wdtvec == (uint32_t)WDT_IRQHandler);
226   
227   NVIC_SetVector(WDT_IRQn, wdtvec + 32U);
228   
229   ASSERT_TRUE(NVIC_GetVector(WDT_IRQn) == (wdtvec + 32U));
230   
231   /* restore vector table */
232   SCB->VTOR = orig_vtor;
233 #endif
234 }
235
236 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
237 /**
238 \brief Test case: TC_CoreFunc_GetCtrl
239 \details
240 - Check if __set_CONTROL and __get_CONTROL() sets/gets control register
241 */
242 void TC_CoreFunc_Control (void) {
243   // don't use stack for this variables
244   static uint32_t orig;
245   static uint32_t ctrl;
246   static uint32_t result;
247
248   orig = __get_CONTROL();
249   ctrl = orig;
250   result = UINT32_MAX;
251
252 #ifdef CONTROL_SPSEL_Msk
253   // SPSEL set to 0 (MSP)
254   ASSERT_TRUE((ctrl & CONTROL_SPSEL_Msk) == 0U);
255   
256   // SPSEL set to 1 (PSP)
257   ctrl |= CONTROL_SPSEL_Msk;
258   
259   // Move MSP to PSP
260   __set_PSP(__get_MSP());
261 #endif
262
263   __set_CONTROL(ctrl);
264   __ISB();
265
266   result = __get_CONTROL();
267
268   __set_CONTROL(orig);
269   __ISB();
270
271   ASSERT_TRUE(result == ctrl);
272   ASSERT_TRUE(__get_CONTROL() == orig);
273 }
274
275 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
276 /**
277 \brief Test case: TC_CoreFunc_IPSR
278 \details
279 - Check if __get_IPSR intrinsic is available
280 - Check if __get_xPSR intrinsic is available
281 - Result differentiates between thread and exception modes
282 */
283 void TC_CoreFunc_IPSR (void) {
284   uint32_t result = __get_IPSR();
285   ASSERT_TRUE(result == 0U); // Thread Mode
286
287   result = __get_xPSR();
288   ASSERT_TRUE((result & xPSR_ISR_Msk) == 0U); // Thread Mode
289
290   TST_IRQHandler = TC_CoreFunc_IPSR_IRQHandler;
291   irqIPSR = 0U;
292   irqXPSR = 0U;
293
294   NVIC_ClearPendingIRQ(WDT_IRQn);
295   NVIC_EnableIRQ(WDT_IRQn);
296   __enable_irq();
297
298   NVIC_SetPendingIRQ(WDT_IRQn);
299   for(uint32_t i = 10U; i > 0U; --i) {}
300
301   __disable_irq();
302   NVIC_DisableIRQ(WDT_IRQn);
303
304   ASSERT_TRUE(irqIPSR != 0U); // Exception Mode
305   ASSERT_TRUE((irqXPSR & xPSR_ISR_Msk) != 0U); // Exception Mode
306 }
307
308 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
309
310 #if defined(__CC_ARM)
311 #define SUBS(Rd, Rm, Rn) __ASM("SUBS " # Rd ", " # Rm ", " # Rn)
312 #define ADDS(Rd, Rm, Rn) __ASM("ADDS " # Rd ", " # Rm ", " # Rn)
313 #elif defined( __GNUC__ )  && (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__))
314 #define SUBS(Rd, Rm, Rn) __ASM("SUB %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
315 #define ADDS(Rd, Rm, Rn) __ASM("ADD %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
316 #elif defined(_lint)
317 //lint -save -e(9026) allow function-like macro
318 #define SUBS(Rd, Rm, Rn) ((Rd) = (Rm) - (Rn))
319 #define ADDS(Rd, Rm, Rn) ((Rd) = (Rm) + (Rn))
320 //lint -restore
321 #else
322 #define SUBS(Rd, Rm, Rn) __ASM("SUBS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
323 #define ADDS(Rd, Rm, Rn) __ASM("ADDS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
324 #endif
325
326 /**
327 \brief Test case: TC_CoreFunc_APSR
328 \details
329 - Check if __get_APSR intrinsic is available
330 - Check if __get_xPSR intrinsic is available
331 - Check negative, zero and overflow flags
332 */
333 void TC_CoreFunc_APSR (void) {
334   uint32_t result;
335   //lint -esym(838, Rm) unused values
336   //lint -esym(438, Rm) unused values
337
338   // Check negative flag
339   int32_t Rm = 5;
340   int32_t Rn = 7;
341   SUBS(Rm, Rm, Rn);
342   result  = __get_APSR();
343   ASSERT_TRUE((result & APSR_N_Msk) == APSR_N_Msk);
344
345   Rm = 5;
346   Rn = 7;
347   SUBS(Rm, Rm, Rn);
348   result  = __get_xPSR();
349   ASSERT_TRUE((result & xPSR_N_Msk) == xPSR_N_Msk);
350
351   // Check zero and compare flag
352   Rm = 5;
353   SUBS(Rm, Rm, Rm);
354   result  = __get_APSR();
355   ASSERT_TRUE((result & APSR_Z_Msk) == APSR_Z_Msk);
356   ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
357
358   Rm = 5;
359   SUBS(Rm, Rm, Rm);
360   result  = __get_xPSR();
361   ASSERT_TRUE((result & xPSR_Z_Msk) == xPSR_Z_Msk);
362   ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
363
364   // Check overflow flag
365   Rm = 5;
366   Rn = INT32_MAX;
367   ADDS(Rm, Rm, Rn);
368   result  = __get_APSR();
369   ASSERT_TRUE((result & APSR_V_Msk) == APSR_V_Msk);
370
371   Rm = 5;
372   Rn = INT32_MAX;
373   ADDS(Rm, Rm, Rn);
374   result  = __get_xPSR();
375   ASSERT_TRUE((result & xPSR_V_Msk) == xPSR_V_Msk);
376 }
377
378 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
379 /**
380 \brief Test case: TC_CoreFunc_PSP
381 \details
382 - Check if __get_PSP and __set_PSP intrinsic can be used to manipulate process stack pointer.
383 */
384 void TC_CoreFunc_PSP (void) {
385   // don't use stack for this variables
386   static uint32_t orig;
387   static uint32_t psp;
388   static uint32_t result;
389
390   orig = __get_PSP();
391
392   psp = orig + 0x12345678U;
393   __set_PSP(psp);
394
395   result = __get_PSP();
396
397   __set_PSP(orig);
398
399   ASSERT_TRUE(result == psp);
400 }
401
402 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
403 /**
404 \brief Test case: TC_CoreFunc_MSP
405 \details
406 - Check if __get_MSP and __set_MSP intrinsic can be used to manipulate main stack pointer.
407 */
408 void TC_CoreFunc_MSP (void) {
409   // don't use stack for this variables
410   static uint32_t orig;
411   static uint32_t msp;
412   static uint32_t result;
413   static uint32_t ctrl;
414
415   ctrl = __get_CONTROL();
416   orig = __get_MSP();
417   
418   __set_PSP(orig);
419   __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
420
421   msp = orig + 0x12345678U;
422   __set_MSP(msp);
423
424   result = __get_MSP();
425
426   __set_MSP(orig);
427
428   __set_CONTROL(ctrl);
429
430   ASSERT_TRUE(result == msp);
431 }
432
433 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
434 #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
435      (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1))    )
436
437 /**
438 \brief Test case: TC_CoreFunc_PSPLIM
439 \details
440 - Check if __get_PSPLIM and __set_PSPLIM intrinsic can be used to manipulate process stack pointer limit.
441 */
442 void TC_CoreFunc_PSPLIM (void) {
443   // don't use stack for this variables
444   static uint32_t orig;
445   static uint32_t psplim;
446   static uint32_t result;
447
448   orig = __get_PSPLIM();
449
450   psplim = orig + 0x12345678U;
451   __set_PSPLIM(psplim);
452
453   result = __get_PSPLIM();
454
455   __set_PSPLIM(orig);
456
457 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
458      (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3)))
459   // without main extensions, the non-secure PSPLIM is RAZ/WI
460   ASSERT_TRUE(result == 0U);
461 #else
462   ASSERT_TRUE(result == psplim);
463 #endif
464 }
465
466 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
467 /**
468 \brief Test case: TC_CoreFunc_PSPLIM_NS
469 \details
470 - Check if __TZ_get_PSPLIM_NS and __TZ_set_PSPLIM_NS intrinsic can be used to manipulate process stack pointer limit.
471 */
472 void TC_CoreFunc_PSPLIM_NS (void) {
473 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
474   uint32_t orig;
475   uint32_t psplim;
476   uint32_t result;
477
478   orig = __TZ_get_PSPLIM_NS();
479
480   psplim = orig + 0x12345678U;
481   __TZ_set_PSPLIM_NS(psplim);
482
483   result = __TZ_get_PSPLIM_NS();
484
485   __TZ_set_PSPLIM_NS(orig);
486
487 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
488   // without main extensions, the non-secure PSPLIM is RAZ/WI
489   ASSERT_TRUE(result == 0U);
490 #else
491   ASSERT_TRUE(result == psplim);
492 #endif
493 #endif
494 }
495
496 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
497 /**
498 \brief Test case: TC_CoreFunc_MSPLIM
499 \details
500 - Check if __get_MSPLIM and __set_MSPLIM intrinsic can be used to manipulate main stack pointer limit.
501 */
502 void TC_CoreFunc_MSPLIM (void) {
503   // don't use stack for this variables
504   static uint32_t orig;
505   static uint32_t msplim;
506   static uint32_t result;
507   static uint32_t ctrl;
508
509   ctrl = __get_CONTROL();
510   __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
511
512   orig = __get_MSPLIM();
513
514   msplim = orig + 0x12345678U;
515   __set_MSPLIM(msplim);
516
517   result = __get_MSPLIM();
518
519   __set_MSPLIM(orig);
520   
521   __set_CONTROL(ctrl);
522
523 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
524      (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3)))
525   // without main extensions, the non-secure MSPLIM is RAZ/WI
526   ASSERT_TRUE(result == 0U);
527 #else
528   ASSERT_TRUE(result == msplim);
529 #endif
530 }
531
532 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
533 /**
534 \brief Test case: TC_CoreFunc_MSPLIM_NS
535 \details
536 - Check if __TZ_get_MSPLIM_NS and __TZ_set_MSPLIM_NS intrinsic can be used to manipulate process stack pointer limit.
537 */
538 void TC_CoreFunc_MSPLIM_NS (void) {
539 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
540   uint32_t orig;
541   uint32_t msplim;
542   uint32_t result;
543
544   orig = __TZ_get_MSPLIM_NS();
545
546   msplim = orig + 0x12345678U;
547   __TZ_set_MSPLIM_NS(msplim);
548
549   result = __TZ_get_MSPLIM_NS();
550
551   __TZ_set_MSPLIM_NS(orig);
552
553 #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
554   // without main extensions, the non-secure MSPLIM is RAZ/WI
555   ASSERT_TRUE(result == 0U);
556 #else
557   ASSERT_TRUE(result == msplim);
558 #endif
559 #endif
560 }
561
562 #endif
563
564 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
565 /**
566 \brief Test case: TC_CoreFunc_PRIMASK
567 \details
568 - Check if __get_PRIMASK and __set_PRIMASK intrinsic can be used to manipulate PRIMASK.
569 - Check if __enable_irq and __disable_irq are reflected in PRIMASK.
570 */
571 void TC_CoreFunc_PRIMASK (void) {
572   uint32_t orig = __get_PRIMASK();
573
574   // toggle primask
575   uint32_t primask = (orig & ~0x01U) | (~orig & 0x01U);
576
577   __set_PRIMASK(primask);
578   uint32_t result = __get_PRIMASK();
579
580   ASSERT_TRUE(result == primask);
581
582   __disable_irq();
583   result = __get_PRIMASK();
584   ASSERT_TRUE((result & 0x01U) == 1U);
585
586   __enable_irq();
587   result = __get_PRIMASK();
588   ASSERT_TRUE((result & 0x01U) == 0U);
589
590   __disable_irq();
591   result = __get_PRIMASK();
592   ASSERT_TRUE((result & 0x01U) == 1U);
593
594   __set_PRIMASK(orig);
595 }
596
597 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
598 #if ((defined (__ARM_ARCH_7M__      ) && (__ARM_ARCH_7M__      == 1)) || \
599      (defined (__ARM_ARCH_7EM__     ) && (__ARM_ARCH_7EM__     == 1)) || \
600      (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))    )
601
602 /**
603 \brief Test case: TC_CoreFunc_FAULTMASK
604 \details
605 - Check if __get_FAULTMASK and __set_FAULTMASK intrinsic can be used to manipulate FAULTMASK.
606 - Check if __enable_fault_irq and __disable_fault_irq are reflected in FAULTMASK.
607 */
608 void TC_CoreFunc_FAULTMASK (void) {
609   uint32_t orig = __get_FAULTMASK();
610
611   // toggle faultmask
612   uint32_t faultmask = (orig & ~0x01U) | (~orig & 0x01U);
613
614   __set_FAULTMASK(faultmask);
615   uint32_t result = __get_FAULTMASK();
616
617   ASSERT_TRUE(result == faultmask);
618
619   __disable_fault_irq();
620   result = __get_FAULTMASK();
621   ASSERT_TRUE((result & 0x01U) == 1U);
622
623   __enable_fault_irq();
624   result = __get_FAULTMASK();
625   ASSERT_TRUE((result & 0x01U) == 0U);
626
627   __disable_fault_irq();
628   result = __get_FAULTMASK();
629   ASSERT_TRUE((result & 0x01U) == 1U);
630
631   __set_FAULTMASK(orig);
632 }
633
634 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
635 /**
636 \brief Test case: TC_CoreFunc_BASEPRI
637 \details
638 - Check if __get_BASEPRI and __set_BASEPRI intrinsic can be used to manipulate BASEPRI.
639 - Check if __set_BASEPRI_MAX intrinsic can be used to manipulate BASEPRI.
640 */
641 void TC_CoreFunc_BASEPRI(void) {
642   uint32_t orig = __get_BASEPRI();
643
644   uint32_t basepri = ~orig & 0x80U;
645   __set_BASEPRI(basepri);
646   uint32_t result = __get_BASEPRI();
647
648   ASSERT_TRUE(result == basepri);
649
650   __set_BASEPRI(orig);
651
652   __set_BASEPRI_MAX(basepri);
653   result = __get_BASEPRI();
654
655   ASSERT_TRUE(result == basepri);
656 }
657 #endif
658
659 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
660 /**
661 \brief Test case: TC_CoreFunc_FPUType
662 \details
663 Check SCB_GetFPUType returns information.
664 */
665 void TC_CoreFunc_FPUType(void) {
666   uint32_t fpuType = SCB_GetFPUType();
667 #if defined(__FPU_PRESENT) && (__FPU_PRESENT != 0)
668   ASSERT_TRUE(fpuType > 0U);
669 #else
670   ASSERT_TRUE(fpuType  == 0U);
671 #endif
672 }
673
674 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
675 /**
676 \brief Test case: TC_CoreFunc_FPSCR
677 \details
678 - Check if __get_FPSCR and __set_FPSCR intrinsics can be used
679 */
680 void TC_CoreFunc_FPSCR(void) {
681   uint32_t fpscr = __get_FPSCR();
682   __ISB();
683   __DSB();
684
685   __set_FPSCR(~fpscr);
686   __ISB();
687   __DSB();
688
689   uint32_t result = __get_FPSCR();
690
691   __set_FPSCR(fpscr);
692
693 #if (defined (__FPU_USED   ) && (__FPU_USED    == 1U))
694   ASSERT_TRUE(result != fpscr);
695 #else
696   ASSERT_TRUE(result == 0U);
697 #endif
698 }