diff --git a/main.c b/main.c index 328c3bbcba..1854a14071 100755 --- a/main.c +++ b/main.c @@ -88,6 +88,10 @@ #include "common-hal/canio/CAN.h" #endif +#if CIRCUITPY_SLEEPIO +#include "shared-bindings/sleepio/__init__.h" +#endif + void do_str(const char *src, mp_parse_input_kind_t input_kind) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { @@ -303,19 +307,6 @@ bool run_code_py(safe_mode_t safe_mode) { } } - for (uint8_t i = 0; i<=100; i++) { - if (!usb_msc_ejected()) { - //Go into light sleep - break; - } - mp_hal_delay_ms(10); - } - - if (usb_msc_ejected()) { - //Go into deep sleep - common_hal_mcu_deep_sleep(); - } - // Display a different completion message if the user has no USB attached (cannot save files) if (!serial_connected_at_start) { serial_write_compressed(translate("\nCode done running. Waiting for reload.\n")); @@ -326,6 +317,14 @@ bool run_code_py(safe_mode_t safe_mode) { bool refreshed_epaper_display = false; #endif rgb_status_animation_t animation; + bool ok = result->return_code != PYEXEC_EXCEPTION; + #if CIRCUITPY_SLEEPIO + // If USB isn't enumerated then deep sleep. + if (ok && !supervisor_workflow_active() && supervisor_ticks_ms64() > CIRCUITPY_USB_ENUMERATION_DELAY * 1024) { + common_hal_sleepio_deep_sleep(); + } + #endif + // Show the animation every N seconds. prep_rgb_status_animation(&result, found_main, safe_mode, &animation); while (true) { RUN_BACKGROUND_TASKS; @@ -358,8 +357,24 @@ bool run_code_py(safe_mode_t safe_mode) { refreshed_epaper_display = maybe_refresh_epaperdisplay(); } #endif - - tick_rgb_status_animation(&animation); + bool animation_done = tick_rgb_status_animation(&animation); + if (animation_done && supervisor_workflow_active()) { + #if CIRCUITPY_SLEEPIO + int64_t remaining_enumeration_wait = CIRCUITPY_USB_ENUMERATION_DELAY * 1024 - supervisor_ticks_ms64(); + // If USB isn't enumerated then deep sleep after our waiting period. + if (ok && remaining_enumeration_wait < 0) { + common_hal_sleepio_deep_sleep(); + return; // Doesn't actually get here. + } + #endif + // Wake up every so often to flash the error code. + if (!ok) { + port_interrupt_after_ticks(CIRCUITPY_FLASH_ERROR_PERIOD * 1024); + } else { + port_interrupt_after_ticks(remaining_enumeration_wait); + } + port_sleep_until_interrupt(); + } } } @@ -406,7 +421,9 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { if (!skip_boot_output) { // Wait 1.5 seconds before opening CIRCUITPY_BOOT_OUTPUT_FILE for write, // in case power is momentary or will fail shortly due to, say a low, battery. - mp_hal_delay_ms(1500); + if (common_hal_sleepio_get_reset_reason() == RESET_REASON_POWER_VALID) { + mp_hal_delay_ms(1500); + } // USB isn't up, so we can write the file. filesystem_set_internal_writable_by_usb(false); diff --git a/ports/esp32s2/common-hal/alarm_touch/__init__.c b/ports/esp32s2/common-hal/alarm_touch/__init__.c deleted file mode 100644 index df32b26930..0000000000 --- a/ports/esp32s2/common-hal/alarm_touch/__init__.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "esp_sleep.h" - -#include "shared-bindings/alarm_touch/__init__.h" - -void common_hal_alarm_touch_disable (void) { - esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TOUCHPAD); -} diff --git a/shared-bindings/alarm_touch/__init__.c b/shared-bindings/alarm_touch/__init__.c deleted file mode 100644 index 5f5a156d80..0000000000 --- a/shared-bindings/alarm_touch/__init__.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "py/obj.h" -#include "shared-bindings/alarm_touch/__init__.h" - -//| """alarm_touch module -//| -//| The `alarm_touch` module implements deep sleep.""" - -STATIC mp_obj_t alarm_touch_disable(void) { - common_hal_alarm_touch_disable(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_touch_disable_obj, alarm_touch_disable); - -STATIC const mp_rom_map_elem_t alarm_touch_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm_touch) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&alarm_touch_disable_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(alarm_touch_module_globals, alarm_touch_module_globals_table); - -const mp_obj_module_t alarm_touch_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&alarm_touch_module_globals, -}; - -const mp_obj_type_t alarm_touch_type = { - { &mp_type_type }, - .name = MP_QSTR_touchAlarm, -}; diff --git a/shared-bindings/alarm_touch/__init__.h b/shared-bindings/alarm_touch/__init__.h deleted file mode 100644 index 600587d247..0000000000 --- a/shared-bindings/alarm_touch/__init__.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TOUCH___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TOUCH___INIT___H - -#include "py/runtime.h" - -typedef struct { - mp_obj_base_t base; -} alarm_touch_obj_t; - -extern const mp_obj_type_t alarm_touch_type; - -extern void common_hal_alarm_touch_disable (void); - -#endif //MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TOUCH___INIT___H diff --git a/shared-bindings/sleepio/ResetReason.c b/shared-bindings/sleepio/ResetReason.c new file mode 100644 index 0000000000..095f4bed0d --- /dev/null +++ b/shared-bindings/sleepio/ResetReason.c @@ -0,0 +1,61 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/enum.h" + +#include "shared-bindings/sleepio/ResetReason.h" + +MAKE_ENUM_VALUE(sleepio_reset_reason_type, reset_reason, POWER_VALID, RESET_REASON_POWER_VALID); +MAKE_ENUM_VALUE(sleepio_reset_reason_type, reset_reason, SOFTWARE, RESET_REASON_SOFTWARE); +MAKE_ENUM_VALUE(sleepio_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, RESET_REASON_DEEP_SLEEP_ALARM); +MAKE_ENUM_VALUE(sleepio_reset_reason_type, reset_reason, EXTERNAL, RESET_REASON_EXTERNAL); + +//| class ResetReason: +//| """The reason the chip was last reset""" +//| +//| POWER_VALID: object +//| """The chip was reset and started once power levels were valid.""" +//| +//| SOFTWARE: object +//| """The chip was reset from software.""" +//| +//| DEEP_SLEEP_ALARM: object +//| """The chip was reset for deep sleep and started by an alarm.""" +//| +//| EXTERNAL: object +//| """The chip was reset by an external input such as a button.""" +//| +MAKE_ENUM_MAP(sleepio_reset_reason) { + MAKE_ENUM_MAP_ENTRY(reset_reason, POWER_VALID), + MAKE_ENUM_MAP_ENTRY(reset_reason, SOFTWARE), + MAKE_ENUM_MAP_ENTRY(reset_reason, DEEP_SLEEP_ALARM), + MAKE_ENUM_MAP_ENTRY(reset_reason, EXTERNAL), +}; +STATIC MP_DEFINE_CONST_DICT(sleepio_reset_reason_locals_dict, sleepio_reset_reason_locals_table); + +MAKE_PRINTER(sleepio, sleepio_reset_reason); + +MAKE_ENUM_TYPE(sleepio, ResetReason, sleepio_reset_reason); diff --git a/shared-bindings/sleepio/ResetReason.h b/shared-bindings/sleepio/ResetReason.h new file mode 100644 index 0000000000..50b8d002aa --- /dev/null +++ b/shared-bindings/sleepio/ResetReason.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +typedef enum { + RESET_REASON_POWER_APPLIED, + RESET_REASON_SOFTWARE, + RESET_REASON_DEEP_SLEEP_ALARM, + RESET_REASON_BUTTON, +} sleepio_reset_reason_t; + +extern const mp_obj_type_t sleepio_reset_reason_type; diff --git a/shared-bindings/sleepio/__init__.c b/shared-bindings/sleepio/__init__.c index 2d5db18f0a..9793c1b502 100644 --- a/shared-bindings/sleepio/__init__.c +++ b/shared-bindings/sleepio/__init__.c @@ -47,6 +47,10 @@ //| """The most recent alarm to wake us up from a sleep (light or deep.)""" //| +//| reset_reason: ResetReason +//| """The reason the chip started up from reset state. This can may be power up or due to an alarm.""" +//| + //| def sleep_until_alarm(alarm: Alarm, ...) -> Alarm: //| """Performs a light sleep until woken by one of the alarms. The alarm that woke us up is //| returned.""" @@ -54,14 +58,6 @@ //| STATIC mp_obj_t sleepio_sleep_until_alarm(size_t n_args, const mp_obj_t *args) { - // mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0])); - // vstr_t vstr; - // vstr_init_len(&vstr, size); - // byte *p = (byte*)vstr.buf; - // memset(p, 0, size); - // byte *end_p = &p[size]; - // shared_modules_struct_pack_into(args[0], p, end_p, n_args - 1, &args[1]); - // return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sleepio_sleep_until_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, sleepio_sleep_until_alarm); @@ -71,14 +67,6 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sleepio_sleep_until_alarm_obj, 1, MP_OBJ_FUN //| ... //| STATIC mp_obj_t sleepio_set_alarms(size_t n_args, const mp_obj_t *args) { - // mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0])); - // vstr_t vstr; - // vstr_init_len(&vstr, size); - // byte *p = (byte*)vstr.buf; - // memset(p, 0, size); - // byte *end_p = &p[size]; - // shared_modules_struct_pack_into(args[0], p, end_p, n_args - 1, &args[1]); - // return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sleepio_set_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, sleepio_set_alarms); @@ -87,16 +75,23 @@ mp_map_elem_t sleepio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sleepio) }, { MP_ROM_QSTR(MP_QSTR_wake_alarm), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_reset_reason), mp_const_none }, { MP_ROM_QSTR(MP_QSTR_sleep_until_alarm), sleepio_sleep_until_alarm_obj }, { MP_ROM_QSTR(MP_QSTR_set_alarms), sleepio_set_alarms_obj }, }; STATIC MP_DEFINE_CONST_DICT(sleepio_module_globals, sleepio_module_globals_table); +// These are called from common hal code to set the current wake alarm. void common_hal_sleepio_set_wake_alarm(mp_obj_t alarm) { // sleepio_module_globals_table[1].value = alarm; } +// These are called from common hal code to set the current wake alarm. +void common_hal_sleepio_set_reset_reason(mp_obj_t reset_reason) { + // sleepio_module_globals_table[1].value = alarm; +} + const mp_obj_module_t sleepio_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&sleepio_module_globals, diff --git a/shared-bindings/sleepio/__init__.h b/shared-bindings/sleepio/__init__.h index ccd3bf4a02..6ea538055a 100644 --- a/shared-bindings/sleepio/__init__.h +++ b/shared-bindings/sleepio/__init__.h @@ -3,8 +3,7 @@ #include "py/obj.h" -// This is implemented by shared-bindings so that implementations can set the -// newest alarm source. -extern void common_hal_sleepio_set_wake_alarm(mp_obj_t alarm); +extern mp_obj_t common_hal_sleepio_get_wake_alarm(void); +extern sleepio_reset_reason_t common_hal_sleepio_get_reset_reason(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SLEEPIO___INIT___H diff --git a/supervisor/serial.h b/supervisor/serial.h index 9c2d44737a..066886303e 100644 --- a/supervisor/serial.h +++ b/supervisor/serial.h @@ -47,5 +47,4 @@ char serial_read(void); bool serial_bytes_available(void); bool serial_connected(void); -extern volatile bool _serial_connected; #endif // MICROPY_INCLUDED_SUPERVISOR_SERIAL_H diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c index 283b9da123..bff74a1f0e 100644 --- a/supervisor/shared/rgb_led_status.c +++ b/supervisor/shared/rgb_led_status.c @@ -367,6 +367,7 @@ void prep_rgb_status_animation(const pyexec_result_t* result, status->found_main = found_main; status->total_exception_cycle = 0; status->ok = result->return_code != PYEXEC_EXCEPTION; + status->cycles = 0; if (status->ok) { // If this isn't an exception, skip exception sorting and handling return; @@ -411,14 +412,16 @@ void prep_rgb_status_animation(const pyexec_result_t* result, #endif } -void tick_rgb_status_animation(rgb_status_animation_t* status) { +bool tick_rgb_status_animation(rgb_status_animation_t* status) { #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED)) uint32_t tick_diff = supervisor_ticks_ms32() - status->pattern_start; if (status->ok) { // All is good. Ramp ALL_DONE up and down. if (tick_diff > ALL_GOOD_CYCLE_MS) { status->pattern_start = supervisor_ticks_ms32(); - tick_diff = 0; + status->cycles++; + new_status_color(BLACK); + return status->cycles; } uint16_t brightness = tick_diff * 255 / (ALL_GOOD_CYCLE_MS / 2); @@ -433,7 +436,8 @@ void tick_rgb_status_animation(rgb_status_animation_t* status) { } else { if (tick_diff > status->total_exception_cycle) { status->pattern_start = supervisor_ticks_ms32(); - tick_diff = 0; + status->cycles++; + return; } // First flash the file color. if (tick_diff < EXCEPTION_TYPE_LENGTH_MS) { diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index d59e754ed4..fa871eeebf 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -52,6 +52,10 @@ safe_mode_t wait_for_safe_mode_reset(void) { current_safe_mode = safe_mode; return safe_mode; } + if (common_hal_sleepio_get_reset_reason() != RESET_REASON_POWER_VALID && + common_hal_sleepio_get_reset_reason() != RESET_REASON_BUTTON) { + return NO_SAFE_MODE; + } port_set_saved_word(SAFE_MODE_DATA_GUARD | (MANUAL_SAFE_MODE << 8)); // Wait for a while to allow for reset. temp_status_color(SAFE_MODE); diff --git a/supervisor/shared/serial.h b/supervisor/shared/serial.h new file mode 100644 index 0000000000..84f92c337c --- /dev/null +++ b/supervisor/shared/serial.h @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +extern volatile bool _serial_connected; diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 89fbf56f37..7fbc5cbe6a 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -30,6 +30,7 @@ #include "supervisor/background_callback.h" #include "supervisor/port.h" #include "supervisor/serial.h" +#include "supervisor/shared/serial.h" #include "supervisor/usb.h" #include "lib/utils/interrupt_char.h" #include "lib/mp-readline/readline.h" @@ -102,14 +103,16 @@ void usb_irq_handler(void) { // tinyusb callbacks //--------------------------------------------------------------------+ -// Invoked when device is mounted +// Invoked when device is plugged into a host void tud_mount_cb(void) { usb_msc_mount(); + _workflow_active = true; } -// Invoked when device is unmounted +// Invoked when device is unplugged from the host void tud_umount_cb(void) { usb_msc_umount(); + _workflow_active = false; } // Invoked when usb bus is suspended @@ -117,10 +120,12 @@ void tud_umount_cb(void) { // USB Specs: Within 7ms, device must draw an average current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { _serial_connected = false; + _workflow_active = false; } // Invoked when usb bus is resumed void tud_resume_cb(void) { + _workflow_active = true; } // Invoked when cdc when line state changed e.g connected/disconnected diff --git a/supervisor/shared/workflow.c b/supervisor/shared/workflow.c new file mode 100644 index 0000000000..adcffb319a --- /dev/null +++ b/supervisor/shared/workflow.c @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Set by the shared USB code. +volatile bool _workflow_active; + +bool workflow_active(void) { + return _workflow_active; +} diff --git a/supervisor/shared/workflow.h b/supervisor/shared/workflow.h new file mode 100644 index 0000000000..4a138332a7 --- /dev/null +++ b/supervisor/shared/workflow.h @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +extern volatile bool _workflow_active; diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index e81c51a88c..a59e99e3de 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -75,6 +75,7 @@ else lib/tinyusb/src/class/cdc/cdc_device.c \ lib/tinyusb/src/tusb.c \ supervisor/shared/serial.c \ + supervisor/shared/workflow.c \ supervisor/usb.c \ supervisor/shared/usb/usb_desc.c \ supervisor/shared/usb/usb.c \ diff --git a/supervisor/workflow.h b/supervisor/workflow.h new file mode 100755 index 0000000000..4008b83a11 --- /dev/null +++ b/supervisor/workflow.h @@ -0,0 +1,30 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// True when the user could be actively iterating on their code. +bool workflow_active(void);