30
30
#include "supervisor/board.h"
31
31
#include "supervisor/port.h"
32
32
33
+ #include "supervisor/samd_prevent_sleep.h"
34
+
33
35
// ASF 4
34
36
#include "atmel_start_pins.h"
35
37
#include "peripheral_clk_config.h"
114
116
#if CIRCUITPY_PEW
115
117
#include "common-hal/_pew/PewPew.h"
116
118
#endif
117
- static volatile bool sleep_ok = true ;
119
+ static volatile size_t sleep_disable_count = 0 ;
118
120
119
121
#ifdef SAMD21
120
122
static uint8_t _tick_event_channel = EVSYS_SYNCH_NUM ;
@@ -126,12 +128,16 @@ static bool tick_enabled(void) {
126
128
// Sleeping requires a register write that can stall interrupt handling. Turning
127
129
// off sleeps allows for more accurate interrupt timing. (Python still thinks
128
130
// it is sleeping though.)
129
- void rtc_start_pulse (void ) {
130
- sleep_ok = false ;
131
+ void samd_prevent_sleep (void ) {
132
+ sleep_disable_count ++ ;
131
133
}
132
134
133
- void rtc_end_pulse (void ) {
134
- sleep_ok = true;
135
+ void samd_allow_sleep (void ) {
136
+ if (sleep_disable_count == 0 ) {
137
+ // We should never reach this!
138
+ return ;
139
+ }
140
+ sleep_disable_count -- ;
135
141
}
136
142
#endif // SAMD21
137
143
@@ -651,7 +657,11 @@ void port_interrupt_after_ticks(uint32_t ticks) {
651
657
return ;
652
658
}
653
659
#ifdef SAMD21
654
- if (!sleep_ok ) {
660
+ if (sleep_disable_count > 0 ) {
661
+ // "wake" immediately even if sleep_disable_count is set to 0 between
662
+ // now and when port_idle_until_interrupt is called. Otherwise we may
663
+ // sleep too long.
664
+ _woken_up = true;
655
665
return ;
656
666
}
657
667
#endif
@@ -687,7 +697,7 @@ void port_idle_until_interrupt(void) {
687
697
}
688
698
#endif
689
699
common_hal_mcu_disable_interrupts ();
690
- if (!background_callback_pending () && sleep_ok && !_woken_up ) {
700
+ if (!background_callback_pending () && sleep_disable_count == 0 && !_woken_up ) {
691
701
__DSB ();
692
702
__WFI ();
693
703
}
0 commit comments