Skip to content

Commit 9e94d7e

Browse files
authored
Merge pull request #7196 from dhalbert/rp2-pin-alarm-race
RP2040: ignore pin changes before deep sleep
2 parents f76351d + 983502d commit 9e94d7e

File tree

3 files changed

+20
-12
lines changed

3 files changed

+20
-12
lines changed

ports/raspberrypi/common-hal/alarm/__init__.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ void NORETURN common_hal_alarm_enter_deep_sleep(void) {
234234

235235
// Reset uses the watchdog. Use scratch registers to store wake reason
236236
watchdog_hw->scratch[RP_WKUP_SCRATCH_REG] = _get_wakeup_cause();
237+
238+
// Just before reset, enable the pinalarm interrupt.
239+
alarm_pin_pinalarm_entering_deep_sleep();
237240
reset_cpu();
238241
}
239242

ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,29 @@
3838
STATIC bool woke_up;
3939
STATIC uint64_t alarm_triggered_pins; // 36 actual pins
4040
STATIC uint64_t alarm_reserved_pins; // 36 actual pins
41-
STATIC bool _pinalarm_set = false;
41+
STATIC bool _not_yet_deep_sleeping = false;
4242

4343
#define GPIO_IRQ_ALL_EVENTS 0x15u
4444

4545
STATIC void gpio_callback(uint gpio, uint32_t events) {
4646
alarm_triggered_pins |= (1 << gpio);
4747
woke_up = true;
4848

49-
// does this need to be called, to prevent IRQ from constantly going off?
50-
gpio_acknowledge_irq(gpio, events);
49+
// gpio_acknowledge_irq(gpio, events) is called automatically, before this callback is called.
5150

52-
// Disable IRQ automatically
53-
gpio_set_irq_enabled(gpio, events, false);
54-
gpio_set_dormant_irq_enabled(gpio, events, false);
51+
if (_not_yet_deep_sleeping) {
52+
// Event went off prematurely, before we went to sleep, so set it again.
53+
gpio_set_irq_enabled(gpio, events, false);
54+
} else {
55+
// Went off during sleep.
56+
// Disable IRQ automatically.
57+
gpio_set_irq_enabled(gpio, events, false);
58+
gpio_set_dormant_irq_enabled(gpio, events, false);
59+
}
60+
}
61+
62+
void alarm_pin_pinalarm_entering_deep_sleep() {
63+
_not_yet_deep_sleeping = false;
5564
}
5665

5766
void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, const mcu_pin_obj_t *pin, bool value, bool edge, bool pull) {
@@ -156,11 +165,7 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob
156165
gpio_set_dormant_irq_enabled((uint)alarm->pin->number, event, true);
157166
}
158167

159-
_pinalarm_set = true;
168+
_not_yet_deep_sleeping = true;
160169
}
161170
}
162171
}
163-
164-
bool alarm_pin_pinalarm_is_set(void) {
165-
return _pinalarm_set;
166-
}

ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ void alarm_pin_pinalarm_reset(void);
4646
void alarm_pin_pinalarm_light_reset(void);
4747
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
4848
bool alarm_pin_pinalarm_woke_this_cycle(void);
49-
bool alarm_pin_pinalarm_is_set(void);
49+
void alarm_pin_pinalarm_entering_deep_sleep(void);

0 commit comments

Comments
 (0)