Skip to content

Commit 9307b62

Browse files
committed
wip
1 parent 3e75c9a commit 9307b62

File tree

38 files changed

+159
-101
lines changed

38 files changed

+159
-101
lines changed

main.c

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ static void reset_devices(void) {
132132
#endif
133133
}
134134

135-
STATIC void start_mp(supervisor_allocation *heap, bool first_run) {
135+
STATIC void start_mp(supervisor_allocation *heap) {
136136
supervisor_workflow_reset();
137137

138138
// Stack limit should be less than real stack size, so we have a chance
@@ -176,14 +176,6 @@ STATIC void start_mp(supervisor_allocation *heap, bool first_run) {
176176
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib));
177177

178178
mp_obj_list_init((mp_obj_list_t *)mp_sys_argv, 0);
179-
180-
#if CIRCUITPY_ALARM
181-
// Record which alarm woke us up, if any. An object may be created so the heap must be functional.
182-
// There is no alarm if this is not the first time code.py or the REPL has been run.
183-
shared_alarm_save_wake_alarm(first_run ? common_hal_alarm_create_wake_alarm() : mp_const_none);
184-
// Reset alarm module only after we retrieved the wakeup alarm.
185-
alarm_reset();
186-
#endif
187179
}
188180

189181
STATIC void stop_mp(void) {
@@ -373,7 +365,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
373365
}
374366
}
375367

376-
STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_reset) {
368+
STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) {
377369
bool serial_connected_at_start = serial_connected();
378370
bool printed_safe_mode_message = false;
379371
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
@@ -409,8 +401,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
409401

410402
supervisor_allocation *heap = allocate_remaining_memory();
411403

412-
// Prepare the VM state. Includes an alarm check/reset for sleep.
413-
start_mp(heap, first_run);
404+
// Prepare the VM state.
405+
start_mp(heap);
414406

415407
#if CIRCUITPY_USB
416408
usb_setup_with_vm();
@@ -853,12 +845,12 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
853845
#endif
854846
}
855847

856-
STATIC int run_repl(bool first_run) {
848+
STATIC int run_repl(void) {
857849
int exit_code = PYEXEC_FORCED_EXIT;
858850
stack_resize();
859851
filesystem_flush();
860852
supervisor_allocation *heap = allocate_remaining_memory();
861-
start_mp(heap, first_run);
853+
start_mp(heap);
862854

863855
#if CIRCUITPY_USB
864856
usb_setup_with_vm();
@@ -968,6 +960,12 @@ int __attribute__((used)) main(void) {
968960
safe_mode = NO_CIRCUITPY;
969961
}
970962

963+
#if CIRCUITPY_ALARM
964+
// Record which alarm woke us up, if any.
965+
// common_hal_alarm_record_wake_alarm() should return a static, non-heap object
966+
shared_alarm_save_wake_alarm(common_hal_alarm_record_wake_alarm());
967+
#endif
968+
971969
// Reset everything and prep MicroPython to run boot.py.
972970
reset_port();
973971
// Port-independent devices, like CIRCUITPY_BLEIO_HCI.
@@ -1001,20 +999,18 @@ int __attribute__((used)) main(void) {
1001999
// Boot script is finished, so now go into REPL or run code.py.
10021000
int exit_code = PYEXEC_FORCED_EXIT;
10031001
bool skip_repl = true;
1004-
bool first_run = true;
1005-
bool simulate_reset;
1002+
bool simulate_reset = true;
10061003
for (;;) {
1007-
simulate_reset = false;
10081004
if (!skip_repl) {
1009-
exit_code = run_repl(first_run);
1005+
exit_code = run_repl();
10101006
supervisor_set_run_reason(RUN_REASON_REPL_RELOAD);
10111007
}
10121008
if (exit_code == PYEXEC_FORCED_EXIT) {
1013-
if (!first_run) {
1009+
if (!simulate_reset) {
10141010
serial_write_compressed(translate("soft reboot\n"));
10151011
}
10161012
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) {
1017-
skip_repl = run_code_py(safe_mode, first_run, &simulate_reset);
1013+
skip_repl = run_code_py(safe_mode, &simulate_reset);
10181014
} else {
10191015
skip_repl = false;
10201016
}
@@ -1025,7 +1021,11 @@ int __attribute__((used)) main(void) {
10251021
// Either the REPL or code.py has run and finished.
10261022
// If code.py did a fake deep sleep, pretend that we are running code.py for
10271023
// the first time after a hard reset. This will preserve any alarm information.
1028-
first_run = simulate_reset;
1024+
if (!simulate_reset) {
1025+
#if CIRCUITPY_ALARM
1026+
shared_alarm_save_wake_alarm(mp_const_none);
1027+
#endif
1028+
}
10291029
}
10301030
mp_deinit();
10311031
return 0;

ports/atmel-samd/common-hal/alarm/__init__.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
4848
},
4949
};
5050

51+
// Static alarm object recording alarm (if any) that woke up CircuitPython after light or deep sleep.
52+
// This object lives across VM instantiations, so none of these objects can contain references to the heap.
53+
static union {
54+
alarm_pin_pinalarm_obj_t pin_alarm;
55+
alarm_time_timealarm_obj_t time_alarm;
56+
} wake_alarm;
57+
5158
void alarm_reset(void) {
5259
// Reset the alarm flag
5360
alarm_pin_pinalarm_reset();
@@ -57,7 +64,7 @@ void alarm_reset(void) {
5764
void alarm_get_wakeup_cause(void) {
5865
// Called from rtc_init, just before SWRST of RTC. It is called
5966
// at an early stage of main(), to save TAMPID from SWRST. Later,
60-
// common_hal_alarm_create_wake_alarm is called to make a wakeup
67+
// common_hal_alarm_record_wake_alarm is called to make a wakeup
6168
// alarm from the deep sleep.
6269

6370
TAMPID = RTC->MODE0.TAMPID.reg;
@@ -67,7 +74,7 @@ bool common_hal_alarm_woken_from_sleep(void) {
6774
return alarm_pin_pinalarm_woke_this_cycle() || alarm_time_timealarm_woke_this_cycle();
6875
}
6976

70-
mp_obj_t common_hal_alarm_create_wake_alarm(void) {
77+
mp_obj_t common_hal_alarm_record_wake_alarm(void) {
7178
// Called from main.c on the first start up, just before alarm_reset.
7279
// Return a copy of wakeup alarm from deep sleep / fake deep sleep.
7380
// In case of fake sleep, status should be left in TimeAlarm/PinAlarm.
@@ -76,13 +83,13 @@ mp_obj_t common_hal_alarm_create_wake_alarm(void) {
7683
if (alarm_pin_pinalarm_woke_this_cycle()) {
7784
TAMPID = RTC->MODE0.TAMPID.reg;
7885
RTC->MODE0.TAMPID.reg = TAMPID; // clear register
79-
return alarm_pin_pinalarm_create_wakeup_alarm(TAMPID);
86+
return alarm_pin_pinalarm_record_wakeup_alarm(&wake_alarm.pin_alarm, TAMPID);
8087
}
8188
if (alarm_time_timealarm_woke_this_cycle() || (true_deep && TAMPID == 0)) {
82-
return alarm_time_timealarm_create_wakeup_alarm();
89+
return alarm_time_timealarm_record_wakeup_alarm(&wake_alarm.time_alarm);
8390
}
8491
if (true_deep) {
85-
return alarm_pin_pinalarm_create_wakeup_alarm(TAMPID);
92+
return alarm_pin_pinalarm_record_wakeup_alarm(&wake_alarm.pin_alarm, TAMPID);
8693
}
8794
return mp_const_none;
8895
}

ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,11 @@ mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t
128128
return mp_const_none;
129129
}
130130

131-
mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(uint32_t TAMPID) {
131+
mp_obj_t alarm_pin_pinalarm_record_wakeup_alarm(alarm_pin_pinalarm_obj_t *alarm, uint32_t TAMPID) {
132132
// Create tamper alarm that caused wakeup from deep sleep
133133

134134
for (samd_tamper_pin_t *t = TAMPER_PINS; t->n >= 0; t++) {
135135
if (TAMPID & (1 << t->n)) {
136-
alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t);
137136
alarm->base.type = &alarm_pin_pinalarm_type;
138137
alarm->pin = t->pin;
139138
return alarm;

ports/atmel-samd/common-hal/alarm/pin/PinAlarm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ typedef struct {
3939
} alarm_pin_pinalarm_obj_t;
4040

4141
mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms);
42-
mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(uint32_t TAMPID);
42+
mp_obj_t alarm_pin_pinalarm_record_wakeup_alarm(alarm_pin_pinalarm_obj_t *alarm, uint32_t TAMPID);
4343

4444
void pin_alarm_callback(uint8_t num);
4545
void alarm_pin_pinalarm_reset(void);

ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,12 @@ mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj
5858
return mp_const_none;
5959
}
6060

61-
mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void) {
62-
alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t);
63-
timer->base.type = &alarm_time_timealarm_type;
61+
mp_obj_t alarm_time_timealarm_record_wakeup_alarm(alarm_time_timealarm_obj_t *alarm) {
62+
alarm->base.type = &alarm_time_timealarm_type;
6463
// TODO: Set monotonic_time based on the RTC state.
6564
// Or don't, most of the other ports don't have this either.
66-
timer->monotonic_time = 0.0f;
67-
return timer;
65+
alarm->monotonic_time = 0.0f;
66+
return alarm;
6867
}
6968

7069
void time_alarm_callback(void) {

ports/atmel-samd/common-hal/alarm/time/TimeAlarm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ typedef struct {
3535
} alarm_time_timealarm_obj_t;
3636

3737
mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms);
38-
mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void);
38+
mp_obj_t alarm_time_timealarm_record_wakeup_alarm(alarm_time_timealarm_obj_t *alarm);
3939
void time_alarm_callback(void);
4040
bool alarm_time_timealarm_woke_this_cycle(void);
4141
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);

ports/atmel-samd/supervisor/port.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,10 @@ safe_mode_t port_init(void) {
385385
}
386386

387387
void reset_port(void) {
388+
#if CIRCUITPY_ALARM
389+
alarm_reset();
390+
#endif
391+
388392
#if CIRCUITPY_BUSIO
389393
reset_sercoms();
390394
#endif

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
5858
},
5959
};
6060

61+
// Static alarm object recording alarm (if any) that woke up CircuitPython after light or deep sleep.
62+
// This object lives across VM instantiations, so none of these objects can contain references to the heap.
63+
static union {
64+
alarm_pin_pinalarm_obj_t pin_alarm;
65+
alarm_time_timealarm_obj_t time_alarm;
66+
alarm_touch_touchalarm_obj_t touch_alarm;
67+
alarm_coproc_coprocalarm_obj_t coproc_alarm;
68+
} wake_alarm;
69+
6170
void alarm_reset(void) {
6271
alarm_sleep_memory_reset();
6372
alarm_pin_pinalarm_reset();
@@ -90,27 +99,27 @@ bool common_hal_alarm_woken_from_sleep(void) {
9099
return _get_wakeup_cause() != ESP_SLEEP_WAKEUP_UNDEFINED;
91100
}
92101

93-
mp_obj_t common_hal_alarm_create_wake_alarm(void) {
102+
mp_obj_t common_hal_alarm_record_wake_alarm(void) {
94103
// If woken from deep sleep, create a copy alarm similar to what would have
95104
// been passed in originally. Otherwise, just return none
96105
esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
97106
switch (cause) {
98107
case ESP_SLEEP_WAKEUP_TIMER: {
99-
return alarm_time_timealarm_create_wakeup_alarm();
108+
return alarm_time_timealarm_record_wakeup_alarm(&wake_alarm.time_alarm);
100109
}
101110

102111
case ESP_SLEEP_WAKEUP_GPIO:
103112
case ESP_SLEEP_WAKEUP_EXT0:
104113
case ESP_SLEEP_WAKEUP_EXT1: {
105-
return alarm_pin_pinalarm_create_wakeup_alarm();
114+
return alarm_pin_pinalarm_record_wakeup_alarm(&wake_alarm.pin_alarm);
106115
}
107116

108117
case ESP_SLEEP_WAKEUP_TOUCHPAD: {
109-
return alarm_touch_touchalarm_create_wakeup_alarm();
118+
return alarm_touch_touchalarm_record_wakeup_alarm(&wake_alarm.touch_alarm);
110119
}
111120

112121
case ESP_SLEEP_WAKEUP_ULP: {
113-
return alarm_coproc_coprocalarm_create_wakeup_alarm();
122+
return alarm_coproc_coprocalarm_record_wakeup_alarm(&wake_alarm.coproc_alarm);
114123
}
115124

116125
case ESP_SLEEP_WAKEUP_UNDEFINED:

ports/espressif/common-hal/alarm/coproc/CoprocAlarm.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ mp_obj_t alarm_coproc_coprocalarm_find_triggered_alarm(const size_t n_alarms, co
4747
return mp_const_none;
4848
}
4949

50-
mp_obj_t alarm_coproc_coprocalarm_create_wakeup_alarm(void) {
51-
// Create CoprocAlarm object.
52-
alarm_coproc_coprocalarm_obj_t *alarm = m_new_obj(alarm_coproc_coprocalarm_obj_t);
50+
mp_obj_t alarm_coproc_coprocalarm_record_wakeup_alarm(alarm_coproc_coprocalarm_obj_t *alarm) {
5351
alarm->base.type = &alarm_coproc_coprocalarm_type;
5452
return alarm;
5553
}
@@ -111,7 +109,7 @@ mp_obj_t alarm_coproc_coprocalarm_find_triggered_alarm(const size_t n_alarms, co
111109
return mp_const_none;
112110
}
113111

114-
mp_obj_t alarm_coproc_coprocalarm_create_wakeup_alarm(void) {
112+
mp_obj_t alarm_coproc_coprocalarm_record_wakeup_alarm(void) {
115113
return mp_const_none;
116114
}
117115

ports/espressif/common-hal/alarm/coproc/CoprocAlarm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ typedef struct {
3838
} alarm_coproc_coprocalarm_obj_t;
3939

4040
mp_obj_t alarm_coproc_coprocalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms);
41-
mp_obj_t alarm_coproc_coprocalarm_create_wakeup_alarm(void);
41+
mp_obj_t alarm_coproc_coprocalarm_record_wakeup_alarm(void);
4242

4343
void alarm_coproc_coprocalarm_prepare_for_deep_sleep(void);
4444
void alarm_coproc_coprocalarm_reset(void);

0 commit comments

Comments
 (0)