Skip to content

Commit e016c49

Browse files
MirkoCovizzilemrey
authored andcommitted
lib: lite_buttons: add critical section enter/exit
Adds support for entering and exiting critical sections. Signed-off-by: Mirko Covizzi <[email protected]>
1 parent ca7504b commit e016c49

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

lib/lite_buttons/lite_buttons.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,78 @@
1313

1414
LOG_MODULE_REGISTER(lite_buttons, CONFIG_LITE_BUTTONS_LOG_LEVEL);
1515

16+
/* Local implementation of critical section enter/exit support. */
17+
18+
#include <stdint.h>
19+
#include <nrf.h>
20+
21+
static uint32_t inside_critical_section;
22+
23+
static void lite_irq_disable(void)
24+
{
25+
__disable_irq();
26+
inside_critical_section++;
27+
}
28+
29+
static void lite_irq_enable(void)
30+
{
31+
inside_critical_section--;
32+
if (inside_critical_section == 0) {
33+
__enable_irq();
34+
}
35+
}
36+
37+
static void lite_critical_section_enter(uint8_t *nested)
38+
{
39+
#if defined(CONFIG_SOFTDEVICE)
40+
/* return value can be safely ignored */
41+
(void) sd_nvic_critical_region_enter(nested);
42+
#else
43+
lite_irq_disable();
44+
#endif
45+
}
46+
47+
static void lite_critical_section_exit(uint8_t nested)
48+
{
49+
#if defined(CONFIG_SOFTDEVICE)
50+
/* return value can be safely ignored */
51+
(void) sd_nvic_critical_region_exit(nested);
52+
#else
53+
lite_irq_enable();
54+
#endif
55+
}
56+
57+
/**@brief Macro for entering a critical section.
58+
*
59+
* @note Due to implementation details, there must exist one and only one call to
60+
* CRITICAL_SECTION_EXIT() for each call to CRITICAL_SECTION_ENTER(), and they must be located
61+
* in the same scope.
62+
*/
63+
#ifdef SOFTDEVICE_PRESENT
64+
#define LITE_CRITICAL_SECTION_ENTER() \
65+
{ \
66+
uint8_t __CS_NESTED = 0; \
67+
lite_critical_section_enter(&__CS_NESTED);
68+
#else
69+
#define LITE_CRITICAL_SECTION_ENTER() lite_critical_section_enter(NULL)
70+
#endif
71+
72+
/**@brief Macro for leaving a critical section.
73+
*
74+
* @note Due to implementation details, there must exist one and only one call to
75+
* CRITICAL_SECTION_EXIT() for each call to CRITICAL_SECTION_ENTER(), and they must be located
76+
* in the same scope.
77+
*/
78+
#ifdef SOFTDEVICE_PRESENT
79+
#define LITE_CRITICAL_SECTION_EXIT() \
80+
lite_critical_section_exit(__CS_NESTED); \
81+
}
82+
#else
83+
#define LITE_CRITICAL_SECTION_EXIT() lite_critical_section_exit(0)
84+
#endif
85+
86+
/* End of local implementation of critical section enter/exit support. */
87+
1688
#define GPIOTE_INST 0
1789
#define IRQ_PRIO 3
1890
#define BITS_PER_PIN 4
@@ -114,7 +186,9 @@ static void evt_handle(uint8_t pin, uint8_t value)
114186
if (value) {
115187
LOG_DBG("Pin %d idle->armed", pin);
116188
state_set(pin, BUTTON_PRESS_ARMED);
189+
LITE_CRITICAL_SECTION_ENTER();
117190
global.pin_active |= 1ULL << pin;
191+
LITE_CRITICAL_SECTION_EXIT();
118192
} else {
119193
/* stay in IDLE */
120194
}
@@ -146,7 +220,9 @@ static void evt_handle(uint8_t pin, uint8_t value)
146220
} else {
147221
state_set(pin, BUTTON_IDLE);
148222
user_event(pin, LITE_BUTTONS_RELEASE);
223+
LITE_CRITICAL_SECTION_ENTER();
149224
global.pin_active &= ~(1ULL << pin);
225+
LITE_CRITICAL_SECTION_EXIT();
150226
}
151227
LOG_DBG("Pin %d release_detected->%s", pin, value ? "pressed" : "idle");
152228
break;
@@ -176,7 +252,9 @@ static int buttons_disable(void)
176252
nrfx_gpiote_trigger_enable(&gpio_instance, global.configs[i].pin_number, false);
177253
}
178254

255+
LITE_CRITICAL_SECTION_ENTER();
179256
global.pin_active = 0;
257+
LITE_CRITICAL_SECTION_EXIT();
180258

181259
return 0;
182260
}

0 commit comments

Comments
 (0)