47
47
#include "mpconfigboard.h"
48
48
#include "supervisor/background_callback.h"
49
49
#include "supervisor/cpu.h"
50
+ #include "supervisor/filesystem.h"
50
51
#include "supervisor/memory.h"
51
52
#include "supervisor/port.h"
52
- #include "supervisor/filesystem .h"
53
+ #include "supervisor/serial .h"
53
54
#include "supervisor/shared/autoreload.h"
54
- #include "supervisor/shared/translate.h"
55
55
#include "supervisor/shared/rgb_led_status.h"
56
56
#include "supervisor/shared/safe_mode.h"
57
- #include "supervisor/shared/status_leds.h"
58
57
#include "supervisor/shared/stack.h"
58
+ #include "supervisor/shared/status_leds.h"
59
+ #include "supervisor/shared/translate.h"
59
60
#include "supervisor/shared/workflow.h"
60
- #include "supervisor/serial.h"
61
61
#include "supervisor/usb.h"
62
62
63
63
#include "shared-bindings/microcontroller/__init__.h"
66
66
67
67
#include "boards/board.h"
68
68
69
+ #include "esp_log.h"
70
+
69
71
#if CIRCUITPY_ALARM
70
72
#include "shared-bindings/alarm/__init__.h"
71
73
#endif
101
103
// How long to flash errors on the RGB status LED before going to sleep (secs)
102
104
#define CIRCUITPY_FLASH_ERROR_PERIOD 10
103
105
104
- void do_str (const char * src , mp_parse_input_kind_t input_kind ) {
105
- mp_lexer_t * lex = mp_lexer_new_from_str_len (MP_QSTR__lt_stdin_gt_ , src , strlen (src ), 0 );
106
- if (lex == NULL ) {
107
- //printf("MemoryError: lexer could not allocate memory\n");
108
- return ;
109
- }
110
-
111
- nlr_buf_t nlr ;
112
- if (nlr_push (& nlr ) == 0 ) {
113
- qstr source_name = lex -> source_name ;
114
- mp_parse_tree_t parse_tree = mp_parse (lex , input_kind );
115
- mp_obj_t module_fun = mp_compile (& parse_tree , source_name , MP_EMIT_OPT_NONE , true);
116
- mp_call_function_0 (module_fun );
117
- nlr_pop ();
118
- } else {
119
- // uncaught exception
120
- mp_obj_print_exception (& mp_plat_print , (mp_obj_t )nlr .ret_val );
121
- }
122
- }
123
-
124
106
#if MICROPY_ENABLE_PYSTACK
125
107
static size_t PLACE_IN_DTCM_BSS (_pystack [CIRCUITPY_PYSTACK_SIZE / sizeof (size_t )]);
126
108
#endif
@@ -131,9 +113,13 @@ static void reset_devices(void) {
131
113
#endif
132
114
}
133
115
134
- void start_mp (supervisor_allocation * heap ) {
116
+ STATIC void start_mp (supervisor_allocation * heap ) {
135
117
reset_status_led ();
136
118
autoreload_stop ();
119
+ supervisor_workflow_reset ();
120
+ #if CIRCUITPY_ALARM
121
+ alarm_reset ();
122
+ #endif
137
123
138
124
// Stack limit should be less than real stack size, so we have a chance
139
125
// to recover from limit hit. (Limit is measured in bytes.)
@@ -182,7 +168,7 @@ void start_mp(supervisor_allocation* heap) {
182
168
#endif
183
169
}
184
170
185
- void stop_mp (void ) {
171
+ STATIC void stop_mp (void ) {
186
172
#if CIRCUITPY_NETWORK
187
173
network_module_deinit ();
188
174
#endif
@@ -207,7 +193,7 @@ void stop_mp(void) {
207
193
208
194
// Look for the first file that exists in the list of filenames, using mp_import_stat().
209
195
// Return its index. If no file found, return -1.
210
- const char * first_existing_file_in_list (const char * const * filenames ) {
196
+ STATIC const char * first_existing_file_in_list (const char * const * filenames ) {
211
197
for (int i = 0 ; filenames [i ] != (char * )"" ; i ++ ) {
212
198
mp_import_stat_t stat = mp_import_stat (filenames [i ]);
213
199
if (stat == MP_IMPORT_STAT_FILE ) {
@@ -217,7 +203,7 @@ const char* first_existing_file_in_list(const char * const * filenames) {
217
203
return NULL ;
218
204
}
219
205
220
- bool maybe_run_list (const char * const * filenames , pyexec_result_t * exec_result ) {
206
+ STATIC bool maybe_run_list (const char * const * filenames , pyexec_result_t * exec_result ) {
221
207
const char * filename = first_existing_file_in_list (filenames );
222
208
if (filename == NULL ) {
223
209
return false;
@@ -231,7 +217,7 @@ bool maybe_run_list(const char * const * filenames, pyexec_result_t* exec_result
231
217
return true;
232
218
}
233
219
234
- void cleanup_after_vm (supervisor_allocation * heap ) {
220
+ STATIC void cleanup_after_vm (supervisor_allocation * heap ) {
235
221
// Reset port-independent devices, like CIRCUITPY_BLEIO_HCI.
236
222
reset_devices ();
237
223
// Turn off the display and flush the fileystem before the heap disappears.
@@ -260,7 +246,7 @@ void cleanup_after_vm(supervisor_allocation* heap) {
260
246
reset_status_led ();
261
247
}
262
248
263
- void print_code_py_status_message (safe_mode_t safe_mode ) {
249
+ STATIC void print_code_py_status_message (safe_mode_t safe_mode ) {
264
250
if (autoreload_is_enabled ()) {
265
251
serial_write_compressed (translate ("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n" ));
266
252
} else {
@@ -272,7 +258,7 @@ void print_code_py_status_message(safe_mode_t safe_mode) {
272
258
}
273
259
}
274
260
275
- bool run_code_py (safe_mode_t safe_mode ) {
261
+ STATIC bool run_code_py (safe_mode_t safe_mode ) {
276
262
bool serial_connected_at_start = serial_connected ();
277
263
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
278
264
if (serial_connected_at_start ) {
@@ -318,6 +304,8 @@ bool run_code_py(safe_mode_t safe_mode) {
318
304
}
319
305
}
320
306
307
+ // Program has finished running.
308
+
321
309
// Display a different completion message if the user has no USB attached (cannot save files)
322
310
if (!serial_connected_at_start ) {
323
311
serial_write_compressed (translate ("\nCode done running. Waiting for reload.\n" ));
@@ -329,11 +317,26 @@ bool run_code_py(safe_mode_t safe_mode) {
329
317
#endif
330
318
rgb_status_animation_t animation ;
331
319
bool ok = result .return_code != PYEXEC_EXCEPTION ;
332
- // If USB isn't enumerated then deep sleep.
333
- if (ok && !supervisor_workflow_active () && supervisor_ticks_ms64 () > CIRCUITPY_USB_ENUMERATION_DELAY * 1024 ) {
334
- common_hal_mcu_deep_sleep ();
335
- }
336
- // Show the animation every N seconds.
320
+
321
+ ESP_LOGI ("main" , "common_hal_alarm_enable_deep_sleep_alarms()" );
322
+ // Decide whether to deep sleep.
323
+ #if CIRCUITPY_ALARM
324
+ // Enable pin or time alarms before sleeping.
325
+ common_hal_alarm_enable_deep_sleep_alarms ();
326
+ #endif
327
+
328
+ // Normally we won't deep sleep if there was an error or if we are connected to a host
329
+ // but either of those can be enabled.
330
+ // *********DON'T SLEEP IF USB HASN'T HAD TIME TO ENUMERATE.
331
+ bool will_deep_sleep =
332
+ (ok || supervisor_workflow_get_allow_deep_sleep_on_error ()) &&
333
+ (!supervisor_workflow_active () || supervisor_workflow_get_allow_deep_sleep_when_connected ());
334
+
335
+ ESP_LOGI ("main" , "ok %d" , will_deep_sleep );
336
+ ESP_LOGI ("main" , "...on_error() %d" , supervisor_workflow_get_allow_deep_sleep_on_error ());
337
+ ESP_LOGI ("main" , "supervisor_workflow_active() %d" , supervisor_workflow_active ());
338
+ ESP_LOGI ("main" , "...when_connected() %d" , supervisor_workflow_get_allow_deep_sleep_when_connected ());
339
+ will_deep_sleep = false;
337
340
prep_rgb_status_animation (& result , found_main , safe_mode , & animation );
338
341
while (true) {
339
342
RUN_BACKGROUND_TASKS ;
@@ -356,9 +359,12 @@ bool run_code_py(safe_mode_t safe_mode) {
356
359
if (!serial_connected_at_start ) {
357
360
print_code_py_status_message (safe_mode );
358
361
}
359
- print_safe_mode_message (safe_mode );
360
- serial_write ("\n" );
361
- serial_write_compressed (translate ("Press any key to enter the REPL. Use CTRL-D to reload." ));
362
+ // We won't be going into the REPL if we're going to sleep.
363
+ if (!will_deep_sleep ) {
364
+ print_safe_mode_message (safe_mode );
365
+ serial_write ("\n" );
366
+ serial_write_compressed (translate ("Press any key to enter the REPL. Use CTRL-D to reload." ));
367
+ }
362
368
}
363
369
if (serial_connected_before_animation && !serial_connected ()) {
364
370
serial_connected_at_start = false;
@@ -371,16 +377,22 @@ bool run_code_py(safe_mode_t safe_mode) {
371
377
refreshed_epaper_display = maybe_refresh_epaperdisplay ();
372
378
}
373
379
#endif
374
- bool animation_done = tick_rgb_status_animation (& animation );
375
- if (animation_done && supervisor_workflow_active ()) {
376
- #if CIRCUITPY_ALARM
380
+
381
+ bool animation_done = false;
382
+ if (will_deep_sleep && ok ) {
383
+ // Skip animation if everything is OK.
384
+ animation_done = true;
385
+ } else {
386
+ animation_done = tick_rgb_status_animation (& animation );
387
+ }
388
+ // Do an error animation only once before deep-sleeping.
389
+ if (animation_done && will_deep_sleep ) {
377
390
int64_t remaining_enumeration_wait = CIRCUITPY_USB_ENUMERATION_DELAY * 1024 - supervisor_ticks_ms64 ();
378
391
// If USB isn't enumerated then deep sleep after our waiting period.
379
392
if (ok && remaining_enumeration_wait < 0 ) {
380
393
common_hal_mcu_deep_sleep ();
381
- return false; // Doesn't actually get here .
394
+ // Does not return .
382
395
}
383
- #endif
384
396
// Wake up every so often to flash the error code.
385
397
if (!ok ) {
386
398
port_interrupt_after_ticks (CIRCUITPY_FLASH_ERROR_PERIOD * 1024 );
@@ -394,7 +406,7 @@ bool run_code_py(safe_mode_t safe_mode) {
394
406
395
407
FIL * boot_output_file ;
396
408
397
- void __attribute__ ((noinline )) run_boot_py (safe_mode_t safe_mode ) {
409
+ STATIC void __attribute__ ((noinline )) run_boot_py (safe_mode_t safe_mode ) {
398
410
// If not in safe mode, run boot before initing USB and capture output in a
399
411
// file.
400
412
if (filesystem_present () && safe_mode == NO_SAFE_MODE && MP_STATE_VM (vfs_mount_table ) != NULL ) {
@@ -473,7 +485,7 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
473
485
}
474
486
}
475
487
476
- int run_repl (void ) {
488
+ STATIC int run_repl (void ) {
477
489
int exit_code = PYEXEC_FORCED_EXIT ;
478
490
stack_resize ();
479
491
filesystem_flush ();
0 commit comments