4747#include "mpconfigboard.h"
4848#include "supervisor/background_callback.h"
4949#include "supervisor/cpu.h"
50+ #include "supervisor/filesystem.h"
5051#include "supervisor/memory.h"
5152#include "supervisor/port.h"
52- #include "supervisor/filesystem .h"
53+ #include "supervisor/serial .h"
5354#include "supervisor/shared/autoreload.h"
54- #include "supervisor/shared/translate.h"
5555#include "supervisor/shared/rgb_led_status.h"
5656#include "supervisor/shared/safe_mode.h"
57- #include "supervisor/shared/status_leds.h"
5857#include "supervisor/shared/stack.h"
58+ #include "supervisor/shared/status_leds.h"
59+ #include "supervisor/shared/translate.h"
5960#include "supervisor/shared/workflow.h"
60- #include "supervisor/serial.h"
6161#include "supervisor/usb.h"
6262
6363#include "shared-bindings/microcontroller/__init__.h"
6666
6767#include "boards/board.h"
6868
69+ #include "esp_log.h"
70+
6971#if CIRCUITPY_ALARM
7072#include "shared-bindings/alarm/__init__.h"
7173#endif
101103// How long to flash errors on the RGB status LED before going to sleep (secs)
102104#define CIRCUITPY_FLASH_ERROR_PERIOD 10
103105
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-
124106#if MICROPY_ENABLE_PYSTACK
125107static size_t PLACE_IN_DTCM_BSS (_pystack [CIRCUITPY_PYSTACK_SIZE / sizeof (size_t )]);
126108#endif
@@ -131,9 +113,13 @@ static void reset_devices(void) {
131113#endif
132114}
133115
134- void start_mp (supervisor_allocation * heap ) {
116+ STATIC void start_mp (supervisor_allocation * heap ) {
135117 reset_status_led ();
136118 autoreload_stop ();
119+ supervisor_workflow_reset ();
120+ #if CIRCUITPY_ALARM
121+ alarm_reset ();
122+ #endif
137123
138124 // Stack limit should be less than real stack size, so we have a chance
139125 // to recover from limit hit. (Limit is measured in bytes.)
@@ -182,7 +168,7 @@ void start_mp(supervisor_allocation* heap) {
182168 #endif
183169}
184170
185- void stop_mp (void ) {
171+ STATIC void stop_mp (void ) {
186172 #if CIRCUITPY_NETWORK
187173 network_module_deinit ();
188174 #endif
@@ -207,7 +193,7 @@ void stop_mp(void) {
207193
208194// Look for the first file that exists in the list of filenames, using mp_import_stat().
209195// 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 ) {
211197 for (int i = 0 ; filenames [i ] != (char * )"" ; i ++ ) {
212198 mp_import_stat_t stat = mp_import_stat (filenames [i ]);
213199 if (stat == MP_IMPORT_STAT_FILE ) {
@@ -217,7 +203,7 @@ const char* first_existing_file_in_list(const char * const * filenames) {
217203 return NULL ;
218204}
219205
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 ) {
221207 const char * filename = first_existing_file_in_list (filenames );
222208 if (filename == NULL ) {
223209 return false;
@@ -231,7 +217,7 @@ bool maybe_run_list(const char * const * filenames, pyexec_result_t* exec_result
231217 return true;
232218}
233219
234- void cleanup_after_vm (supervisor_allocation * heap ) {
220+ STATIC void cleanup_after_vm (supervisor_allocation * heap ) {
235221 // Reset port-independent devices, like CIRCUITPY_BLEIO_HCI.
236222 reset_devices ();
237223 // Turn off the display and flush the fileystem before the heap disappears.
@@ -260,7 +246,7 @@ void cleanup_after_vm(supervisor_allocation* heap) {
260246 reset_status_led ();
261247}
262248
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 ) {
264250 if (autoreload_is_enabled ()) {
265251 serial_write_compressed (translate ("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n" ));
266252 } else {
@@ -272,7 +258,7 @@ void print_code_py_status_message(safe_mode_t safe_mode) {
272258 }
273259}
274260
275- bool run_code_py (safe_mode_t safe_mode ) {
261+ STATIC bool run_code_py (safe_mode_t safe_mode ) {
276262 bool serial_connected_at_start = serial_connected ();
277263 #if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
278264 if (serial_connected_at_start ) {
@@ -318,6 +304,8 @@ bool run_code_py(safe_mode_t safe_mode) {
318304 }
319305 }
320306
307+ // Program has finished running.
308+
321309 // Display a different completion message if the user has no USB attached (cannot save files)
322310 if (!serial_connected_at_start ) {
323311 serial_write_compressed (translate ("\nCode done running. Waiting for reload.\n" ));
@@ -329,11 +317,26 @@ bool run_code_py(safe_mode_t safe_mode) {
329317 #endif
330318 rgb_status_animation_t animation ;
331319 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;
337340 prep_rgb_status_animation (& result , found_main , safe_mode , & animation );
338341 while (true) {
339342 RUN_BACKGROUND_TASKS ;
@@ -356,9 +359,12 @@ bool run_code_py(safe_mode_t safe_mode) {
356359 if (!serial_connected_at_start ) {
357360 print_code_py_status_message (safe_mode );
358361 }
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+ }
362368 }
363369 if (serial_connected_before_animation && !serial_connected ()) {
364370 serial_connected_at_start = false;
@@ -371,16 +377,22 @@ bool run_code_py(safe_mode_t safe_mode) {
371377 refreshed_epaper_display = maybe_refresh_epaperdisplay ();
372378 }
373379 #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 ) {
377390 int64_t remaining_enumeration_wait = CIRCUITPY_USB_ENUMERATION_DELAY * 1024 - supervisor_ticks_ms64 ();
378391 // If USB isn't enumerated then deep sleep after our waiting period.
379392 if (ok && remaining_enumeration_wait < 0 ) {
380393 common_hal_mcu_deep_sleep ();
381- return false; // Doesn't actually get here .
394+ // Does not return .
382395 }
383- #endif
384396 // Wake up every so often to flash the error code.
385397 if (!ok ) {
386398 port_interrupt_after_ticks (CIRCUITPY_FLASH_ERROR_PERIOD * 1024 );
@@ -394,7 +406,7 @@ bool run_code_py(safe_mode_t safe_mode) {
394406
395407FIL * boot_output_file ;
396408
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 ) {
398410 // If not in safe mode, run boot before initing USB and capture output in a
399411 // file.
400412 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) {
473485 }
474486}
475487
476- int run_repl (void ) {
488+ STATIC int run_repl (void ) {
477489 int exit_code = PYEXEC_FORCED_EXIT ;
478490 stack_resize ();
479491 filesystem_flush ();
0 commit comments