16
16
#include "sleep_api.h"
17
17
#include "cmsis.h"
18
18
#include "mbed_interface.h"
19
+ #include "softdevice_handler.h"
19
20
#include "nrf_soc.h"
20
- #include "nrf_sdm.h"
21
21
22
22
// Mask of reserved bits of the register ICSR in the System Control Block peripheral
23
23
// In this case, bits which are equal to 0 are the bits reserved in this register
@@ -27,29 +27,27 @@ void sleep(void)
27
27
{
28
28
// ensure debug is disconnected if semihost is enabled....
29
29
30
- SCB -> SCR |= SCB_SCR_SEVONPEND_Msk ; /* send an event when an interrupt is pending.
31
- * This helps with the wakeup from the following app_evt_wait(). */
30
+ // Trigger an event when an interrupt is pending. This allows to wake up
31
+ // the processor from disabled interrupts.
32
+ SCB -> SCR |= SCB_SCR_SEVONPEND_Msk ;
32
33
33
- uint8_t sd_enabled ;
34
-
35
- // look if exceptions are enabled or not, if they are, it is possible to make an SVC call
36
- // and check if the soft device is running
37
- if ((__get_PRIMASK () == 0 ) && (sd_softdevice_is_enabled (& sd_enabled ) == NRF_SUCCESS ) && (sd_enabled == 1 )) {
38
- // soft device is enabled, use the primitives from the soft device to go to sleep
34
+ // If the SoftDevice is enabled, its API must be used to go to sleep.
35
+ if (softdevice_handler_isEnabled ())
36
+ {
39
37
sd_power_mode_set (NRF_POWER_MODE_LOWPWR );
40
38
sd_app_evt_wait ();
41
- } else {
39
+ }
40
+ else
41
+ {
42
42
NRF_POWER -> TASKS_LOWPWR = 1 ;
43
43
44
- // Note: it is not possible to just use WFE at this stage because WFE
45
- // will read the event register (not accessible) and if an event occured,
46
- // in the past, it will just clear the event register and continue execution.
47
- // SVC call like sd_softdevice_is_enabled set the event register to 1.
48
- // This means that a making an SVC call followed by WFE will never put the
49
- // CPU to sleep.
50
- // Our startegy here is to clear the event register then, if there is any
51
- // interrupt, return from here. If no interrupts are pending, just call
52
- // WFE.
44
+ // Note: it is not sufficient to just use WFE here, since the internal
45
+ // event register may be already set from an event that occurred in the
46
+ // past (like an SVC call to the SoftDevice) and in such case WFE will
47
+ // just clear the register and continue execution.
48
+ // Therefore, the strategy here is to first clear the event register
49
+ // by using SEV/WFE pair, and then execute WFE again, unless there is
50
+ // a pending interrupt.
53
51
54
52
// Set an event and wake up whatsoever, this will clear the event
55
53
// register from all previous events set (SVC call included)
0 commit comments