8000 Add STM32 and NRF52 compatibility · adafruit/circuitpython@715f7ee · GitHub
[go: up one dir, main page]

Skip to content

Commit 715f7ee

Browse files
committed
Add STM32 and NRF52 compatibility
1 parent 295103b commit 715f7ee

File tree

12 files changed

+110
-77
lines changed

12 files changed

+110
-77
lines changed

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

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,18 @@ void alarm_reset(void) {
6969

7070
extern uint32_t reset_reason_saved;
7171
STATIC nrf_sleep_source_t _get_wakeup_cause(void) {
72-
if (alarm_pin_pinalarm_woke_us_up()) {
72+
// First check if the modules remember what last woke up
73+
if (alarm_pin_pinalarm_woke_this_cycle()) {
7374
return NRF_SLEEP_WAKEUP_GPIO;
7475
}
75-
if (alarm_time_timealarm_woke_us_up()) {
76+
if (alarm_time_timealarm_woke_this_cycle()) {
7677
return NRF_SLEEP_WAKEUP_TIMER;
7778
}
78-
if (alarm_touch_touchalarm_woke_us_up()) {
79+
if (alarm_touch_touchalarm_woke_this_cycle()) {
7980
return NRF_SLEEP_WAKEUP_TOUCHPAD;
8081
}
82+
// If waking from true deep sleep, modules will have lost their state,
83+
// so check the deep wakeup cause manually
8184
if (reset_reason_saved & NRF_POWER_RESETREAS_RESETPIN_MASK) {
8285
return NRF_SLEEP_WAKEUP_RESETPIN;
8386
} else if (reset_reason_saved & NRF_POWER_RESETREAS_OFF_MASK) {
@@ -116,29 +119,26 @@ bool common_hal_alarm_woken_from_sleep(void) {
116119
|| cause == NRF_SLEEP_WAKEUP_TOUCHPAD;
117120
}
118121

119-
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
122+
mp_obj_t common_hal_alarm_create_wake_alarm(void) {
123+
// If woken from deep sleep, create a copy alarm similar to what would have
124+
// been passed in originally. Otherwise, just return none
120125
nrf_sleep_source_t cause = _get_wakeup_cause();
121126
switch (cause) {
122127
case NRF_SLEEP_WAKEUP_TIMER: {
123-
return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
128+
return alarm_time_timealarm_create_wakeup_alarm();
124129
}
125130
case NRF_SLEEP_WAKEUP_TOUCHPAD: {
126-
return alarm_touch_touchalarm_get_wakeup_alarm(n_alarms, alarms);
131+
return alarm_touch_touchalarm_create_wakeup_alarm();
127132
}
128133
case NRF_SLEEP_WAKEUP_GPIO: {
129-
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
134+
return alarm_pin_pinalarm_create_wakeup_alarm();
130135
}
131136
default:
132137
break;
133138
}
134139
return mp_const_none;
135140
}
136141

137-
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
138-
mp_obj_t obj = _get_wake_alarm(0, NULL);
139-
return obj;
140-
}
141-
142142
// Set up light sleep or deep sleep alarms.
143143
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
144144
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
@@ -257,7 +257,7 @@ void system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) {
257257
}
258258

259259
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
260-
mp_obj_t wake_alarm;
260+
mp_obj_t wake_alarm = mp_const_none;
261261
alarm_time_timealarm_clear_wakeup_time();
262262
_setup_sleep_alarms(false, n_alarms, alarms);
263263

@@ -271,7 +271,23 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj
271271
if (mp_hal_is_interrupted()) {
272272
wake_alarm = mp_const_none;
273273
} else {
274-
wake_alarm = _get_wake_alarm(n_alarms, alarms);
274+
if (common_hal_alarm_woken_from_sleep()) {
275+
nrf_sleep_source_t cause = _get_wakeup_cause();
276+
switch (cause) {
277+
case NRF_SLEEP_WAKEUP_TIMER: {
278+
wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms);
279+
break;
280+
}
281+
case NRF_SLEEP_WAKEUP_GPIO: {
282+
wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms,alarms);
283+
break;
284+
}
285+
default:
286+
// Should not reach this, if all light sleep types are covered correctly
287+
break;
288+
}
289+
shared_alarm_save_wake_alarm(wake_alarm);
290+
}
275291
}
276292
alarm_reset();
277293
return wake_alarm;

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,12 @@ static void pinalarm_gpiote_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t
8585
sleepmem_wakeup_pin = pin & 0xFF;
8686
}
8787

88-
bool alarm_pin_pinalarm_woke_us_up(void) {
88+
bool alarm_pin_pinalarm_woke_this_cycle(void) {
8989
return sleepmem_wakeup_event == SLEEPMEM_WAKEUP_BY_PIN &&
9090
sleepmem_wakeup_pin != WAKEUP_PIN_UNDEF;
9191
}
9292

93-
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
93+
mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms) {
9494
// First, check to see if we match any given alarms.
9595
for (size_t i = 0; i < n_alarms; i++) {
9696
if (!mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) {
@@ -101,6 +101,10 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al
101101
return alarms[i];
102102
}
103103
}
104+
return mp_const_none;
105+
}
106+
107+
mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void) {
104108
alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t);
105109
alarm->base.type = &alarm_pin_pinalarm_type;
106110
alarm->pin = NULL;

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ typedef struct {
3434
bool pull;
3535
} alarm_pin_pinalarm_obj_t;
3636

37+
mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms);
38+
mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void);
39+
3740
void alarm_pin_pinalarm_reset(void);
3841
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
3942
void alarm_pin_pinalarm_prepare_for_deep_sleep(void);
40-
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
41-
bool alarm_pin_pinalarm_woke_us_up(void);
43+
bool alarm_pin_pinalarm_woke_this_cycle(void);

ports/nrf/common-hal/alarm/time/TimeAlarm.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,24 @@ mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timeala
4040
return self->monotonic_time;
4141
}
4242

43-
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
44-
// First, check to see if we match
43+
mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms) {
4544
for (size_t i = 0; i < n_alarms; i++) {
4645
if (mp_obj_is_type(alarms[i], &alarm_time_timealarm_type)) {
4746
return alarms[i];
4847
}
4948
}
49+
return mp_const_none;
50+
}
51+
52+
mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void) {
5053
alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t);
5154
timer->base.type = &alarm_time_timealarm_type;
5255
// TODO: Set monotonic_time based on the RTC state.
5356
timer->monotonic_time = 0.0f;
5457
return timer;
5558
}
5659

57-
bool alarm_time_timealarm_woke_us_up(void) {
60+
bool alarm_time_timealarm_woke_this_cycle(void) {
5861
return sleepmem_wakeup_event == SLEEPMEM_WAKEUP_BY_TIMER;
5962
}
6063

ports/nrf/common-hal/alarm/time/TimeAlarm.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ extern volatile int rtc_woke_up_counter;
3636
extern void port_disable_interrupt_after_ticks_ch(uint32_t channel);
3737
extern void port_interrupt_after_ticks_ch(uint32_t channel, uint32_t ticks);
3838

39-
// Find the alarm object that caused us to wake up or create an equivalent one.
40-
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
39+
mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms);
40+
mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void);
41+
4142
// Check for the wake up alarm from pretend deep sleep.
42-
bool alarm_time_timealarm_woke_us_up(void);
43+
bool alarm_time_timealarm_woke_this_cycle(void);
4344
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
4445
void alarm_time_timealarm_reset(void);
4546

ports/nrf/common-hal/alarm/touch/TouchAlarm.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *s
3535
(void)pin;
3636
}
3737

38-
mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms) {
38+
mp_obj_t alarm_touch_touchalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms) {
39+
return mp_const_none;
40+
}
41+
42+
mp_obj_t alarm_touch_touchalarm_create_wakeup_alarm(void) {
3943
return mp_const_none;
4044
}
4145

@@ -45,7 +49,7 @@ void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alar
4549
void alarm_touch_touchalarm_prepare_for_deep_sleep(void) {
4650
}
4751

48-
bool alarm_touch_touchalarm_woke_us_up(void) {
52+
bool alarm_touch_touchalarm_woke_this_cycle(void) {
4953
return false;
5054
}
5155

ports/nrf/common-hal/alarm/touch/TouchAlarm.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,12 @@ typedef struct {
3636
} alarm_touch_touchalarm_obj_t;
3737

3838
// Find the alarm object that caused us to wake up or create an equivalent one.
39-
mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms);
39+
mp_obj_t alarm_touch_touchalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms);
40+
mp_obj_t alarm_touch_touchalarm_create_wakeup_alarm(void);
4041
// Check for the wake up alarm from pretend deep sleep.
4142
void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms);
4243
void alarm_touch_touchalarm_prepare_for_deep_sleep(void);
43-
bool alarm_touch_touchalarm_woke_us_up(void);
44+
bool alarm_touch_touchalarm_woke_this_cycle(void);
4445
void alarm_touch_touchalarm_reset(void);
4546

4647
#endif // MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H

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

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,8 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
4848
};
4949

5050
STATIC stm_sleep_source_t true_deep_wake_reason;
51-
STATIC mp_obj_t most_recent_alarm;
5251

5352
void alarm_reset(void) {
54-
most_recent_alarm = NULL;
5553
// Reset the alarm flag
5654
STM_ALARM_FLAG = 0x00;
5755
alarm_pin_pinalarm_reset();
@@ -66,10 +64,10 @@ void alarm_set_wakeup_reason(stm_sleep_source_t reason) {
6664

6765
STATIC stm_sleep_source_t _get_wakeup_cause(void) {
6866
// If in light/fake sleep, check modules
69-
if (alarm_pin_pinalarm_woke_us_up()) {
67+
if (alarm_pin_pinalarm_woke_this_cycle()) {
7068
return STM_WAKEUP_GPIO;
7169
}
72-
if (alarm_time_timealarm_woke_us_up()) {
70+
if (alarm_time_timealarm_woke_this_cycle()) {
7371
return STM_WAKEUP_RTC;
7472
}
7573
// Check to see if we woke from deep sleep (reason set in port_init)
@@ -83,14 +81,16 @@ bool common_hal_alarm_woken_from_sleep(void) {
8381
return _get_wakeup_cause() != STM_WAKEUP_UNDEF;
8482
}
8583

86-
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
84+
mp_obj_t common_hal_alarm_create_wake_alarm(void) {
85+
// If woken from deep sleep, create a copy alarm similar to what would have
86+
// been passed in originally. Otherwise, just return none
8787
stm_sleep_source_t cause = _get_wakeup_cause();
8888
switch (cause) {
8989
case STM_WAKEUP_RTC: {
90-
return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
90+
return alarm_time_timealarm_create_wakeup_alarm();
9191
}
9292
case STM_WAKEUP_GPIO: {
93-
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
93+
return alarm_pin_pinalarm_create_wakeup_alarm();
9494
}
9595
case STM_WAKEUP_UNDEF:
9696
default:
@@ -100,58 +100,51 @@ STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
100100
return mp_const_none;
101101
}
102102

103-
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
104-
// If we woke from light sleep, override with that alarm
105-
if (most_recent_alarm != NULL) {
106-
return most_recent_alarm;
107-
}
108-
return _get_wake_alarm(0, NULL);
109-
}
110-
111103
// Set up light sleep or deep sleep alarms.
112104
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
113105
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
114106
alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
115107
}
116108

117-
STATIC void _idle_until_alarm(void) {
118-
// Poll for alarms.
109+
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
110+
_setup_sleep_alarms(false, n_alarms, alarms);
111+
mp_obj_t wake_alarm = mp_const_none;
112+
113+
// TODO: add more dynamic clock shutdown/restart logic
119114
while (!mp_hal_is_interrupted()) {
120115
RUN_BACKGROUND_TASKS;
121116
// Detect if interrupt was alarm or ctrl-C interrupt.
122117
if (common_hal_alarm_woken_from_sleep()) {
123-
return;
118+
stm_sleep_source_t cause = _get_wakeup_cause();
119+
switch (cause) {
120+
case STM_WAKEUP_RTC: {
121+
wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms);
122+
break;
123+
}
124+
case STM_WAKEUP_GPIO: {
125+
wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms,alarms);
126+
break;
127+
}
128+
default:
129+
// Should not reach this, if all light sleep types are covered correctly
130+
break;
131+
}
132+
shared_alarm_save_wake_alarm(wake_alarm);
133+
break;
124134
}
135+
// HAL_PWR_EnterSLEEPMode is just a WFI anyway so don't bother
125136
port_idle_until_interrupt();
126137
}
127-
}
128138

129-
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
130-
// If USB is active, only pretend to sleep. Otherwise, light sleep
131-
if (supervisor_workflow_active()) {
132-
_setup_sleep_alarms(false, n_alarms, alarms);
133-
_idle_until_alarm();
134-
} else {
135-
_setup_sleep_alarms(false, n_alarms, alarms);
136-
port_disable_tick();
137-
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
138-
port_enable_tick();
139+
if (mp_hal_is_interrupted()) {
140+
return mp_const_none; // Shouldn't be given to python code because exception handling should kick in.
139141
}
140142

141-
mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms);
142-
143-
// TODO: make assignment to global array less roundabout
144-
most_recent_alarm = wake_alarm;
145-
shared_alarm_save_wake_alarm();
146-
147-
// Can't use alarm_reset since it resets most_recent_alarm
148-
alarm_pin_pinalarm_reset();
149-
alarm_time_timealarm_reset();
143+
alarm_reset();
150144
return wake_alarm;
151145
}
152146

153147
void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) {
154-
most_recent_alarm = NULL;
155148
_setup_sleep_alarms(true, n_alarms, alarms);
156149
}
157150

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,11 @@ bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self) {
8585
return self->pull;
8686
}
8787

88-
bool alarm_pin_pinalarm_woke_us_up(void) {
88+
bool alarm_pin_pinalarm_woke_this_cycle(void) {
8989
return woke_up;
9090
}
9191

92-
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
92+
mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms) {
9393
for (size_t i = 0; i < n_alarms; i++) {
9494
if (!mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) {
9595
continue;
@@ -99,8 +99,10 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al
9999
return alarms[i];
100100
}
101101
}
102+
return mp_const_none;
103+
}
102104

103-
// If the above isn't true, we woke from deep sleep, so create a new alarm
105+
mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void) {
104106
alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t);
105107
alarm->base.type = &alarm_pin_pinalarm_type;
106108
// TODO: replace this if/when other WKUP pins are supported

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@ typedef struct {
3737
bool pull;
3838
} alarm_pin_pinalarm_obj_t;
3939

40+
mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms);
41+
mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void);
42+
4043
void alarm_pin_pinalarm_reset(void);
4144
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
4245
void alarm_pin_pinalarm_prepare_for_deep_sleep(void);
43-
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
44-
bool alarm_pin_pinalarm_woke_us_up(void);
46+
bool alarm_pin_pinalarm_woke_this_cycle(void);
4547

4648
#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_PINALARM_H

0 commit comments

Comments
 (0)
0