Skip to content

Commit ae41c7d

Browse files
committed
Implementation of critical section primitives
which can be called from diferent contexts. Orginal nordic critical primitives must been called in pairs from exacly the same function. As mbed hal call it in separate methods, so they are not suitable here.
1 parent b084812 commit ae41c7d

File tree

1 file changed

+74
-3
lines changed

1 file changed

+74
-3
lines changed

targets/TARGET_NORDIC/TARGET_NRF5/nordic_critical.c

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,85 @@
1818
#include <stdint.h>
1919
#include "app_util_platform.h"
2020

21-
static uint8_t nordic_cr_nested = 0;
21+
#if defined(SOFTDEVICE_PRESENT)
22+
static volatile uint32_t nordic_cr_nested = 0;
23+
24+
static void nordic_nvic_critical_region_enter(void);
25+
static void nordic_nvic_critical_region_exit(void);
26+
#endif
2227

2328
void core_util_critical_section_enter()
2429
{
25-
app_util_critical_region_enter(&nordic_cr_nested);
30+
#ifdef NRF52
31+
ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get())
32+
#endif
33+
34+
#if defined(SOFTDEVICE_PRESENT)
35+
/* return value can be safely ignored */
36+
nordic_nvic_critical_region_enter();
37+
#else
38+
app_util_disable_irq();
39+
#endif
2640
}
2741

2842
void core_util_critical_section_exit()
2943
{
30-
app_util_critical_region_exit(nordic_cr_nested);
44+
#ifdef NRF52
45+
ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get())
46+
#endif
47+
48+
#if defined(SOFTDEVICE_PRESENT)
49+
/* return value can be safely ignored */
50+
nordic_nvic_critical_region_exit();
51+
#else
52+
app_util_enable_irq();
53+
#endif
54+
}
55+
56+
#if defined(SOFTDEVICE_PRESENT)
57+
/**@brief Enters critical region.
58+
*
59+
* @post Application interrupts will be disabled.
60+
* @sa nordic_nvic_critical_region_exit
61+
*/
62+
static inline void nordic_nvic_critical_region_enter(void)
63+
{
64+
int was_masked = __sd_nvic_irq_disable();
65+
66+
if (nordic_cr_nested == 0) {
67+
nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 );
68+
NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0;
69+
#ifdef NRF52
70+
nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 );
71+
NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1;
72+
#endif
73+
}
74+
75+
nordic_cr_nested++;
76+
77+
if (!was_masked) {
78+
__sd_nvic_irq_enable();
79+
}
80+
}
81+
82+
/**@brief Exit critical region.
83+
*
84+
* @pre Application has entered a critical region using ::nordic_nvic_critical_region_enter.
85+
* @post If not in a nested critical region, the application interrupts will restored to the state before ::nordic_nvic_critical_region_enter was called.
86+
*/
87+
static inline void nordic_nvic_critical_region_exit(void)
88+
{
89+
nordic_cr_nested--;
90+
91+
if (nordic_cr_nested == 0) {
92+
int was_masked = __sd_nvic_irq_disable();
93+
NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0];
94+
#ifdef NRF52
95+
NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1];
96+
#endif
97+
if (!was_masked) {
98+
__sd_nvic_irq_enable();
99+
}
100+
}
31101
}
102+
#endif

0 commit comments

Comments
 (0)