diff --git a/main.c b/main.c index 8938d714af..f77bf41d84 100755 --- a/main.c +++ b/main.c @@ -61,6 +61,8 @@ #include "supervisor/usb.h" #include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "shared-bindings/supervisor/Runtime.h" #include "boards/board.h" @@ -327,24 +329,27 @@ bool run_code_py(safe_mode_t safe_mode) { #endif rgb_status_animation_t animation; bool ok = result.return_code != PYEXEC_EXCEPTION; - #if CIRCUITPY_ALARM // If USB isn't enumerated then deep sleep. if (ok && !supervisor_workflow_active() && supervisor_ticks_ms64() > CIRCUITPY_USB_ENUMERATION_DELAY * 1024) { - common_hal_alarm_restart_on_alarm(0, NULL); + common_hal_mcu_deep_sleep(); } - #endif // Show the animation every N seconds. prep_rgb_status_animation(&result, found_main, safe_mode, &animation); while (true) { RUN_BACKGROUND_TASKS; if (reload_requested) { + supervisor_set_run_reason(RUN_REASON_AUTO_RELOAD); reload_requested = false; return true; } if (serial_connected() && serial_bytes_available()) { // Skip REPL if reload was requested. - return (serial_read() == CHAR_CTRL_D); + bool ctrl_d = serial_read() == CHAR_CTRL_D; + if (ctrl_d) { + supervisor_set_run_reason(RUN_REASON_REPL_RELOAD); + } + return (ctrl_d); } if (!serial_connected_before_animation && serial_connected()) { @@ -521,6 +526,9 @@ int __attribute__((used)) main(void) { reset_devices(); reset_board(); + // This is first time we are running CircuitPython after a reset or power-up. + supervisor_set_run_reason(RUN_REASON_STARTUP); + // If not in safe mode turn on autoreload by default but before boot.py in case it wants to change it. if (safe_mode == NO_SAFE_MODE) { autoreload_enable(); diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c index 50a1ec038e..ca39f28386 100644 --- a/ports/atmel-samd/common-hal/microcontroller/__init__.c +++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c @@ -84,6 +84,10 @@ void common_hal_mcu_reset(void) { reset(); } +void common_hal_mcu_deep_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/cxd56/common-hal/microcontroller/__init__.c b/ports/cxd56/common-hal/microcontroller/__init__.c index 7aa3b839d7..57140dec70 100644 --- a/ports/cxd56/common-hal/microcontroller/__init__.c +++ b/ports/cxd56/common-hal/microcontroller/__init__.c @@ -81,6 +81,10 @@ void common_hal_mcu_reset(void) { boardctl(BOARDIOC_RESET, 0); } +void common_hal_mcu_deep_sleep(void) { + //deep sleep call here +} + STATIC const mp_rom_map_elem_t mcu_pin_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_UART2_RXD), MP_ROM_PTR(&pin_UART2_RXD) }, { MP_ROM_QSTR(MP_QSTR_UART2_TXD), MP_ROM_PTR(&pin_UART2_TXD) }, diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index e335345508..4a255c51cc 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -25,12 +25,20 @@ * THE SOFTWARE. */ +#include "py/objtuple.h" + #include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/alarm/time/DurationAlarm.h" #include "esp_sleep.h" +STATIC mp_obj_tuple_t *_deep_sleep_alarms; + +void alarm_reset(void) { + _deep_sleep_alarms = &mp_const_empty_tuple; +} + void common_hal_alarm_disable_all(void) { esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); } @@ -63,3 +71,38 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) { } return mp_const_none; } + +mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { + bool time_alarm_set = false; + for (size_t i = 0; i < n_alarms; i++) { + if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pin_alarm_type)) { + mp_raise_NotImplementedError(translate("PinAlarm deep sleep not yet implemented")); + } + if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_duration_alarm_type)) { + if (time_alarm_set) { + mp_raise_ValueError(translate("Only one alarm.time alarm can be set.")); + } + time_alarm_set = true; + } + } + + _deep_sleep_alarms = mp_obj_new_tuple(n_alarms, alarms); +} + +void common_hal_deep_sleep_with_alarms(void) { + for (size_t i = 0; i < _deep_sleep_alarms.len; i++) { + mp_obj_t alarm = _deep_sleep_alarms.items[i] + if (MP_OBJ_IS_TYPE(alarm, &alarm_time_duration_alarm_type)) { + alarm_time_duration_alarm_obj_t *duration_alarm = MP_OBJ_TO_PTR(alarm); + esp_sleep_enable_timer_wakeup( + (uint64_t) (duration_alarm->duration * 1000000.0f)); + } + // TODO: handle pin alarms + } + + common_hal_mcu_deep_sleep(); +} diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c index 6ac3d05f87..f26c8a179a 100644 --- a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c +++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c @@ -30,19 +30,24 @@ #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/microcontroller/Pin.h" -void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mcu_pin_obj_t *pin, bool level, bool edge, bool pull) { - self->pin = pin; - self->level = level; +void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mp_obj_t pins[], size_t num_pins, bool value, bool all_same_value, bool edge, bool pull) { + self->pins = mp_obj_new_tuple(num_pins, pins); + self->value = value; + self->all_same_value = all_same_value; self->edge = edge; self->pull = pull; } -const mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self) { - return self->pin; +const mp_obj_tuple_t *common_hal_alarm_pin_pin_alarm_get_pins(alarm_pin_pin_alarm_obj_t *self) { + return self->pins; } -bool common_hal_alarm_pin_pin_alarm_get_level(alarm_pin_pin_alarm_obj_t *self) { - return self->level; +bool common_hal_alarm_pin_pin_alarm_get_value(alarm_pin_pin_alarm_obj_t *self) { + return self->value; +} + +bool common_hal_alarm_pin_pin_alarm_get_all_same_value(alarm_pin_pin_alarm_obj_t *self) { + return self->all_same_value; } bool common_hal_alarm_pin_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self) { diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h index c6a760b96a..d7e7e2552a 100644 --- a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h +++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h @@ -24,13 +24,14 @@ * THE SOFTWARE. */ - #include "py/obj.h" +#include "py/objtuple.h" typedef struct { mp_obj_base_t base; - const mcu_pin_obj_t *pin; - bool level; + mp_obj_tuple_t *pins; + bool value; + bool all_same_value; bool edge; bool pull; } alarm_pin_pin_alarm_obj_t; diff --git a/ports/esp32s2/common-hal/microcontroller/Processor.c b/ports/esp32s2/common-hal/microcontroller/Processor.c index bd625dc6e2..fffd1a1b19 100644 --- a/ports/esp32s2/common-hal/microcontroller/Processor.c +++ b/ports/esp32s2/common-hal/microcontroller/Processor.c @@ -31,8 +31,12 @@ #include "py/runtime.h" #include "common-hal/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/ResetReason.h" #include "supervisor/shared/translate.h" +#include "esp_sleep.h" +#include "esp_system.h" + #include "soc/efuse_reg.h" #include "components/driver/esp32s2/include/driver/temp_sensor.h" @@ -77,21 +81,42 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - switch (esp_sleep_get_wakeup_cause()) { - case ESP_SLEEP_WAKEUP_TIMER: - return RESET_REASON_DEEP_SLEEP_ALARM; + switch (esp_reset_reason()) { + case ESP_RST_POWERON: + return RESET_REASON_POWER_ON; - case ESP_SLEEP_WAKEUP_EXT0: - return RESET_REASON_DEEP_SLEEP_ALARM; + case ESP_RST_SW: + case ESP_RST_PANIC: + return RESET_REASON_SOFTWARE; - case ESP_SLEEP_WAKEUP_TOUCHPAD: - //TODO: implement TouchIO - case ESP_SLEEP_WAKEUP_UNDEFINED: + case ESP_RST_INT_WDT: + case ESP_RST_TASK_WDT: + case ESP_RST_WDT: + return RESET_REASON_WATCHDOG; + + case ESP_RST_BROWNOUT: + return RESET_REASON_BROWNOUT; + + case ESP_RST_SDIO: + case ESP_RST_EXT: + return RESET_REASON_RESET_PIN; + + case ESP_RST_DEEPSLEEP: + switch (esp_sleep_get_wakeup_cause()) { + case ESP_SLEEP_WAKEUP_TIMER: + case ESP_SLEEP_WAKEUP_EXT0: + case ESP_SLEEP_WAKEUP_EXT1: + case ESP_SLEEP_WAKEUP_TOUCHPAD: + return RESET_REASON_DEEP_SLEEP_ALARM; + + case ESP_SLEEP_WAKEUP_UNDEFINED: + default: + return RESET_REASON_UNKNOWN; + } + + case ESP_RST_UNKNOWN: default: - return RESET_REASON_POWER_APPLIED; + return RESET_REASON_UNKNOWN; + } } - -mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_POWER_ON; -} diff --git a/ports/esp32s2/common-hal/microcontroller/Processor.h b/ports/esp32s2/common-hal/microcontroller/Processor.h index f6636b333c..641a11d555 100644 --- a/ports/esp32s2/common-hal/microcontroller/Processor.h +++ b/ports/esp32s2/common-hal/microcontroller/Processor.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_LITEX_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H -#define MICROPY_INCLUDED_LITEX_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H #define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 6 @@ -36,4 +36,4 @@ typedef struct { // Stores no state currently. } mcu_processor_obj_t; -#endif // MICROPY_INCLUDED_LITEX_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index 3056c65655..fdfbd65fad 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -79,6 +79,14 @@ void common_hal_mcu_reset(void) { while(1); } +void common_hal_mcu_deep_sleep(void) { + // Shut down wifi cleanly. + esp_wifi_stop(); + + // Does not return. + esp_deep_sleep_start(); +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/esp32s2/common-hal/rtc/RTC.h b/ports/esp32s2/common-hal/rtc/RTC.h index e51f1f7848..233cde3fd2 100644 --- a/ports/esp32s2/common-hal/rtc/RTC.h +++ b/ports/esp32s2/common-hal/rtc/RTC.h @@ -24,11 +24,11 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_RTC_RTC_H -#define MICROPY_INCLUDED_NRF_COMMON_HAL_RTC_RTC_H +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_RTC_RTC_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_RTC_RTC_H extern void rtc_init(void); extern void rtc_reset(void); extern void common_hal_rtc_init(void); -#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_RTC_RTC_H +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_RTC_RTC_H diff --git a/ports/esp32s2/common-hal/supervisor/Runtime.h b/ports/esp32s2/common-hal/supervisor/Runtime.h index d1fe246211..840ce1bbb3 100644 --- a/ports/esp32s2/common-hal/supervisor/Runtime.h +++ b/ports/esp32s2/common-hal/supervisor/Runtime.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_LITEX_COMMON_HAL_SUPERVISOR_RUNTIME_H -#define MICROPY_INCLUDED_LITEX_COMMON_HAL_SUPERVISOR_RUNTIME_H +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SUPERVISOR_RUNTIME_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SUPERVISOR_RUNTIME_H #include "py/obj.h" @@ -34,4 +34,4 @@ typedef struct { // Stores no state currently. } super_runtime_obj_t; -#endif // MICROPY_INCLUDED_LITEX_COMMON_HAL_SUPERVISOR_RUNTIME_H +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SUPERVISOR_RUNTIME_H diff --git a/ports/esp32s2/supervisor/internal_flash_root_pointers.h b/ports/esp32s2/supervisor/internal_flash_root_pointers.h index ae3e45e14c..a9a8c2a22e 100644 --- a/ports/esp32s2/supervisor/internal_flash_root_pointers.h +++ b/ports/esp32s2/supervisor/internal_flash_root_pointers.h @@ -23,9 +23,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_LITEX_INTERNAL_FLASH_ROOT_POINTERS_H -#define MICROPY_INCLUDED_LITEX_INTERNAL_FLASH_ROOT_POINTERS_H +#ifndef MICROPY_INCLUDED_ESP32S2_INTERNAL_FLASH_ROOT_POINTERS_H +#define MICROPY_INCLUDED_ESP32S2_INTERNAL_FLASH_ROOT_POINTERS_H #define FLASH_ROOT_POINTERS -#endif // MICROPY_INCLUDED_LITEX_INTERNAL_FLASH_ROOT_POINTERS_H +#endif // MICROPY_INCLUDED_ESP32S2_INTERNAL_FLASH_ROOT_POINTERS_H diff --git a/ports/litex/common-hal/microcontroller/__init__.c b/ports/litex/common-hal/microcontroller/__init__.c index 3c91661144..e6f50ed5a6 100644 --- a/ports/litex/common-hal/microcontroller/__init__.c +++ b/ports/litex/common-hal/microcontroller/__init__.c @@ -89,6 +89,10 @@ void common_hal_mcu_reset(void) { while(1); } +void common_hal_mcu_deep_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c index 6a8537e2da..0329ced69b 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c @@ -86,6 +86,10 @@ void common_hal_mcu_reset(void) { NVIC_SystemReset(); } +void common_hal_mcu_deep_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h index c3f04a0490..c50d73294b 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1011_PERIPH_H -#define MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1011_PERIPH_H +#ifndef MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1011_PERIPHERALS_MIMXRT1011_PERIPH_H +#define MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1011_PERIPHERALS_MIMXRT1011_PERIPH_H extern LPI2C_Type *mcu_i2c_banks[2]; @@ -47,4 +47,4 @@ extern const mcu_periph_obj_t mcu_uart_cts_list[4]; extern const mcu_pwm_obj_t mcu_pwm_list[20]; -#endif // MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1011_PERIP_H +#endif // MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1011_PERIPHERALS_MIMXRT1011_PERIPH_H diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h index 4f6ab6261e..067c05d0d0 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1011_PERIPH_H -#define MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1011_PERIPH_H +#ifndef MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1062_PERIPHERALS_MIMXRT1011_PERIPH_H +#define MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1062_PERIPHERALS_MIMXRT1011_PERIPH_H extern LPI2C_Type *mcu_i2c_banks[4]; @@ -47,4 +47,4 @@ extern const mcu_periph_obj_t mcu_uart_cts_list[9]; extern const mcu_pwm_obj_t mcu_pwm_list[67]; -#endif // MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1011_PERIPH_H +#endif // MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1062_PERIPHERALS_MIMXRT1011_PERIPH_H diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c index 06aac9409d..9911896bff 100644 --- a/ports/nrf/common-hal/microcontroller/__init__.c +++ b/ports/nrf/common-hal/microcontroller/__init__.c @@ -95,6 +95,10 @@ void common_hal_mcu_reset(void) { reset_cpu(); } +void common_hal_mcu_deep_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/nrf/common-hal/rgbmatrix/RGBMatrix.h b/ports/nrf/common-hal/rgbmatrix/RGBMatrix.h index 48de4dcb21..24d86f1779 100644 --- a/ports/nrf/common-hal/rgbmatrix/RGBMatrix.h +++ b/ports/nrf/common-hal/rgbmatrix/RGBMatrix.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_RGBMATRIX_RGBMATRIX_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_RGBMATRIX_RGBMATRIX_H void *common_hal_rgbmatrix_timer_allocate(void); void common_hal_rgbmatrix_timer_enable(void*); diff --git a/ports/stm/common-hal/microcontroller/__init__.c b/ports/stm/common-hal/microcontroller/__init__.c index a827399ccb..bc81b0e4f5 100644 --- a/ports/stm/common-hal/microcontroller/__init__.c +++ b/ports/stm/common-hal/microcontroller/__init__.c @@ -81,6 +81,10 @@ void common_hal_mcu_reset(void) { NVIC_SystemReset(); } +void common_hal_mcu_deep_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/stm/common-hal/rgbmatrix/RGBMatrix.h b/ports/stm/common-hal/rgbmatrix/RGBMatrix.h index 48de4dcb21..323878d202 100644 --- a/ports/stm/common-hal/rgbmatrix/RGBMatrix.h +++ b/ports/stm/common-hal/rgbmatrix/RGBMatrix.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H +#ifndef MICROPY_INCLUDED_STM_COMMON_HAL_RGBMATRIX_RGBMATRIX_H +#define MICROPY_INCLUDED_STM_COMMON_HAL_RGBMATRIX_RGBMATRIX_H void *common_hal_rgbmatrix_timer_allocate(void); void common_hal_rgbmatrix_timer_enable(void*); diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 9345442164..22b2e7f6ab 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -28,7 +28,6 @@ #include "py/runtime.h" #include "shared-bindings/alarm/__init__.h" -#include "shared-bindings/alarm/ResetReason.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/alarm/time/DurationAlarm.h" @@ -44,42 +43,61 @@ //| //| Deep sleep shuts down power to nearly all of the chip including the CPU and RAM. This can save //| a more significant amount of power, but CircuitPython must start ``code.py`` from the beginning when woken -//| up. CircuitPython will enter deep sleep automatically when the current program exits without error -//| or calls ``sys.exit(0)``. -//| If an error causes CircuitPython to exit, error LED error flashes will be done periodically. -//| An error includes an uncaught exception, or sys.exit called with a non-zero argumetn. +//| up. If the board is not actively connected to a host computer (usually via USB), +//| CircuitPython will enter deep sleep automatically when the current program finishes its last statement +//| or calls ``sys.exit()``. +//| If the board is connected, the board will not enter deep sleep unless `supervisor.exit_and_deep_sleep()` +//| is called explicitly. +//| +//| An error includes an uncaught exception, or sys.exit() called with a non-zero argument +//| //| To set alarms for deep sleep use `alarm.restart_on_alarm()` they will apply to next deep sleep only.""" //| //| wake_alarm: Alarm //| """The most recent alarm to wake us up from a sleep (light or deep.)""" //| -//| def sleep_until_alarm(*alarms: Alarm) -> Alarm: -//| """Performs a light sleep until woken by one of the alarms. The alarm that triggers the wake +void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) { + for (size_t i = 0; i < n_args; i++) { + if (MP_OBJ_IS_TYPE(objs[i], &alarm_pin_pin_alarm_type) || + MP_OBJ_IS_TYPE(objs[i], &alarm_time_duration_alarm_type)) { + continue; + } + mp_raise_TypeError_varg(translate("Expected an alarm")); + } +} + +//| def sleep_until_alarms(*alarms: Alarm) -> Alarm: +//| """Performs a light sleep until woken by one of the alarms. The alarm caused the wake-up //| is returned, and is also available as `alarm.wake_alarm` //| """ //| ... //| -STATIC mp_obj_t alarm_sleep_until_alarm(size_t n_args, const mp_obj_t *args) { - // TODO - common_hal_alarm_sleep_until_alarm(size_t n_args, const mp_obj_t *args); +STATIC mp_obj_t alarm_sleep_until_alarms(size_t n_args, const mp_obj_t *args) { + validate_objs_are_alarms(n_args, args); + common_hal_alarm_sleep_until_alarms(n_args, args); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_sleep_until_alarm); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_sleep_until_alarms); -//| def restart_on_alarm(*alarms: Alarm) -> None: +//| def set_deep_sleep_alarms(*alarms: Alarm) -> None: //| """Set one or more alarms to wake up from a deep sleep. -//| When awakened, ``code.py`` will restart from the beginning. -//| The last alarm to wake us up is available as `alarm.wake_alarm`. +//| +//| When awakened, the microcontroller will restart and run ``boot.py`` and ``code.py`` +//| from the beginning. +//| +//| The alarm that caused the wake-up is available as `alarm.wake_alarm`. +//| +//| If you call this routine more than once, only the last set of alarms given will be used. //| """ //| ... //| -STATIC mp_obj_t alarm_restart_on_alarm(size_t n_args, const mp_obj_t *args) { - // TODO - common_hal_alarm_restart_on_alarm(size_t n_args, const mp_obj_t *args); +STATIC mp_obj_t alarm_set_deep_sleep_alarms(size_t n_args, const mp_obj_t *args) { + validate_objs_are_alarms(n_args, args); + common_hal_alarm_set_deep_sleep_alarms(n_args, args); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_restart_on_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_restart_on_alarm); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_set_deep_sleep_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_set_deep_sleep_alarms); //| """The `alarm.pin` module contains alarm attributes and classes related to pins. //| """ @@ -116,11 +134,11 @@ STATIC const mp_obj_module_t alarm_time_module = { STATIC mp_map_elem_t alarm_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm) }, - // wake_alarm and reset_reason are mutable attributes. + // wake_alarm is a mutable attribute. { MP_ROM_QSTR(MP_QSTR_wake_alarm), mp_const_none }, - { MP_ROM_QSTR(MP_QSTR_sleep_until_alarm), MP_OBJ_FROM_PTR(&alarm_sleep_until_alarm_obj) }, - { MP_ROM_QSTR(MP_QSTR_restart_on_alarm), MP_OBJ_FROM_PTR(&alarm_restart_on_alarm_obj) }, + { MP_ROM_QSTR(MP_QSTR_sleep_until_alarms), MP_OBJ_FROM_PTR(&alarm_sleep_until_alarms_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_deep_sleep_alarms), MP_OBJ_FROM_PTR(&alarm_set_deep_sleep_alarms_obj) }, { MP_ROM_QSTR(MP_QSTR_pin), MP_OBJ_FROM_PTR(&alarm_pin_module) }, { MP_ROM_QSTR(MP_QSTR_time), MP_OBJ_FROM_PTR(&alarm_time_module) } diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index 29be8716c5..4df12175d4 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -29,9 +29,10 @@ #include "py/obj.h" +extern mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms); +extern mp_obj_t common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms); + +// Used by wake-up code. extern void common_hal_alarm_set_wake_alarm(mp_obj_t alarm); -extern mp_obj_t common_hal_alarm_restart_on_alarm(size_t n_alarms, const mp_obj_t *alarms); -extern mp_obj_t alarm_sleep_until_alarm(size_t n_alarms, const mp_obj_t *alarms); - #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index 835a5be5ce..a2d2e0ab7a 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -37,23 +37,25 @@ //| class PinAlarm: //| """Trigger an alarm when a pin changes state.""" //| -//| def __init__(self, pin: microcontroller.Pin, level: bool, *, edge: bool = False, pull: bool = False) -> None: +//| def __init__(self, *pins: microcontroller.Pin, value: bool, all_same_value: bool = False, edge: bool = False, pull: bool = False) -> None: //| """Create an alarm triggered by a `~microcontroller.Pin` level. The alarm is not active //| until it is listed in an `alarm`-enabling function, such as `alarm.sleep_until_alarm()` or //| `alarm.restart_on_alarm()`. //| -//| :param ~microcontroller.Pin pin: The pin to monitor. On some ports, the choice of pin +//| :param pins: The pins to monitor. On some ports, the choice of pins //| may be limited due to hardware restrictions, particularly for deep-sleep alarms. -//| :param bool level: When active, trigger when the level is high (``True``) or low (``False``). -//| On some ports, multiple `PinAlarm` objects may need to have coordinated levels +//| :param bool value: When active, trigger when the pin value is high (``True``) or low (``False``). +//| On some ports, multiple `PinAlarm` objects may need to have coordinated values //| for deep-sleep alarms. +//| :param bool all_same_value: If ``True``, all pins listed must be at `value` to trigger the alarm. +//| If ``False``, any one of the pins going to `value` will trigger the alarm. //| :param bool edge: If ``True``, trigger only when there is a transition to the specified -//| value of `level`. If ``True``, if the alarm becomes active when the pin level already -//| matches `level`, the alarm is not triggered: the pin must transition from ``not level`` -//| to ``level`` to trigger the alarm. On some ports, edge-triggering may not be available, +//| value of `value`. If ``True``, if the alarm becomes active when the pin value already +//| matches `value`, the alarm is not triggered: the pin must transition from ``not value`` +//| to ``value`` to trigger the alarm. On some ports, edge-triggering may not be available, //| particularly for deep-sleep alarms. -//| :param bool pull: Enable a pull-up or pull-down which pulls the pin to level opposite -//| opposite that of `level`. For instance, if `level` is set to ``True``, setting `pull` +//| :param bool pull: Enable a pull-up or pull-down which pulls the pin to value opposite +//| opposite that of `value`. For instance, if `value` is set to ``True``, setting `pull` //| to ``True`` will enable a pull-down, to hold the pin low normally until an outside signal //| pulls it high. //| """ @@ -62,51 +64,30 @@ STATIC mp_obj_t alarm_pin_pin_alarm_make_new(const mp_obj_type_t *type, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { alarm_pin_pin_alarm_obj_t *self = m_new_obj(alarm_pin_pin_alarm_obj_t); self->base.type = &alarm_pin_pin_alarm_type; - enum { ARG_pin, ARG_level, ARG_edge, ARG_pull }; + enum { ARG_value, ARG_all_same_value, ARG_edge, ARG_pull }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_level, MP_ARG_REQUIRED | MP_ARG_BOOL }, + { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_BOOL }, + { MP_QSTR_all_same_value, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_edge, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_pull, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + mp_arg_parse_all(0, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t* pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); + for (size_t i = 0; i < n_args; i ++) { + validate_obj_is_free_pin(pos_args[i]); + } common_hal_alarm_pin_pin_alarm_construct( - self, pin, args[ARG_level].u_bool, args[ARG_edge].u_bool, args[ARG_pull].u_bool); + self, pos_args, n_args, + args[ARG_value].u_bool, + args[ARG_all_same_value].u_bool, + args[ARG_edge].u_bool, + args[ARG_pull].u_bool); return MP_OBJ_FROM_PTR(self); } -//| def __eq__(self, other: object) -> bool: -//| """Two PinAlarm objects are equal if their durations are the same if their pin, -//| level, edge, and pull attributes are all the same.""" -//| ... -//| -STATIC mp_obj_t alarm_pin_pin_alarm_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { - switch (op) { - case MP_BINARY_OP_EQUAL: - if (MP_OBJ_IS_TYPE(rhs_in, &alarm_pin_pin_alarm_type)) { - // Pins are singletons, so we can compare them directly. - return mp_obj_new_bool( - common_hal_alarm_pin_pin_alarm_get_pin(lhs_in) == - common_hal_alarm_pin_pin_alarm_get_pin(rhs_in) && - common_hal_alarm_pin_pin_alarm_get_level(lhs_in) == - common_hal_alarm_pin_pin_alarm_get_level(rhs_in) && - common_hal_alarm_pin_pin_alarm_get_edge(lhs_in) == - common_hal_alarm_pin_pin_alarm_get_edge(rhs_in) && - common_hal_alarm_pin_pin_alarm_get_pull(lhs_in) == - common_hal_alarm_pin_pin_alarm_get_pull(rhs_in)); - } - return mp_const_false; - - default: - return MP_OBJ_NULL; // op not supported - } -} - STATIC const mp_rom_map_elem_t alarm_pin_pin_alarm_locals_dict_table[] = { }; @@ -116,6 +97,5 @@ const mp_obj_type_t alarm_pin_pin_alarm_type = { { &mp_type_type }, .name = MP_QSTR_PinAlarm, .make_new = alarm_pin_pin_alarm_make_new, - .binary_op = alarm_pin_pin_alarm_binary_op, .locals_dict = (mp_obj_t)&alarm_pin_pin_alarm_locals_dict, }; diff --git a/shared-bindings/alarm/pin/PinAlarm.h b/shared-bindings/alarm/pin/PinAlarm.h index 978ceaad56..bbf3018b5d 100644 --- a/shared-bindings/alarm/pin/PinAlarm.h +++ b/shared-bindings/alarm/pin/PinAlarm.h @@ -28,13 +28,14 @@ #define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H #include "py/obj.h" +#include "py/objtuple.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/alarm/pin/PinAlarm.h" extern const mp_obj_type_t alarm_pin_pin_alarm_type; -extern void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mcu_pin_obj_t *pin, bool level, bool edge, bool pull); -extern const mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self); +void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mp_obj_t pins[], size_t num_pins, bool value, bool all_same_value, bool edge, bool pull); +extern const mp_obj_tuple_t *common_hal_alarm_pin_pin_alarm_get_pins(alarm_pin_pin_alarm_obj_t *self); extern bool common_hal_alarm_pin_pin_alarm_get_level(alarm_pin_pin_alarm_obj_t *self); extern bool common_hal_alarm_pin_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self); extern bool common_hal_alarm_pin_pin_alarm_get_pull(alarm_pin_pin_alarm_obj_t *self); diff --git a/shared-bindings/audiopwmio/__init__.h b/shared-bindings/audiopwmio/__init__.h index e4b7067d11..d7956d31e6 100644 --- a/shared-bindings/audiopwmio/__init__.h +++ b/shared-bindings/audiopwmio/__init__.h @@ -24,11 +24,11 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOPWMIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOPWMIO___INIT___H #include "py/obj.h" // Nothing now. -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOPWMIO___INIT___H diff --git a/shared-bindings/microcontroller/Processor.c b/shared-bindings/microcontroller/Processor.c index b0ab842f4c..ea43688213 100644 --- a/shared-bindings/microcontroller/Processor.c +++ b/shared-bindings/microcontroller/Processor.c @@ -76,9 +76,9 @@ STATIC mp_obj_t mcu_processor_get_reset_reason(mp_obj_t self) { MP_DEFINE_CONST_FUN_OBJ_1(mcu_processor_get_reset_reason_obj, mcu_processor_get_reset_reason); -const mp_obj_property_t mcu_reset_reason_obj = { +const mp_obj_property_t mcu_processor_reset_reason_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&mcu_processor_get_reason_reason_obj, // getter + .proxy = {(mp_obj_t)&mcu_processor_get_reset_reason_obj, // getter (mp_obj_t)&mp_const_none_obj, // no setter (mp_obj_t)&mp_const_none_obj, // no deleter }, diff --git a/shared-bindings/microcontroller/Processor.h b/shared-bindings/microcontroller/Processor.h index a842e06f32..98d4790876 100644 --- a/shared-bindings/microcontroller/Processor.h +++ b/shared-bindings/microcontroller/Processor.h @@ -29,6 +29,7 @@ #include "py/obj.h" +#include "common-hal/microcontroller/Processor.h" #include "shared-bindings/microcontroller/ResetReason.h" extern const mp_obj_type_t mcu_processor_type; diff --git a/shared-bindings/microcontroller/ResetReason.c b/shared-bindings/microcontroller/ResetReason.c index 151fcf3159..61891934ae 100644 --- a/shared-bindings/microcontroller/ResetReason.c +++ b/shared-bindings/microcontroller/ResetReason.c @@ -35,6 +35,7 @@ MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, SOFTWARE, RESET_REASON_SOFT MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, RESET_REASON_DEEP_SLEEP_ALARM); MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, RESET_PIN, RESET_REASON_RESET_PIN); MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, WATCHDOG, RESET_REASON_WATCHDOG); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, UNKNOWN, RESET_REASON_UNKNOWN); //| class ResetReason: //| """The reason the microntroller was last reset""" @@ -55,7 +56,10 @@ MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, WATCHDOG, RESET_REASON_WATC //| """The microntroller was reset by a signal on its reset pin. The pin might be connected to a reset button.""" //| //| WATCHDOG: object -//| """The chip microcontroller reset by its watchdog timer.""" +//| """The microcontroller was reset by its watchdog timer.""" +//| +//| UNKNOWN: object +//| """The microntroller restarted for an unknown reason.""" //| MAKE_ENUM_MAP(mcu_reset_reason) { MAKE_ENUM_MAP_ENTRY(reset_reason, POWER_ON), @@ -64,6 +68,7 @@ MAKE_ENUM_MAP(mcu_reset_reason) { MAKE_ENUM_MAP_ENTRY(reset_reason, DEEP_SLEEP_ALARM), MAKE_ENUM_MAP_ENTRY(reset_reason, RESET_PIN), MAKE_ENUM_MAP_ENTRY(reset_reason, WATCHDOG), + MAKE_ENUM_MAP_ENTRY(reset_reason, UNKNOWN), }; STATIC MP_DEFINE_CONST_DICT(mcu_reset_reason_locals_dict, mcu_reset_reason_locals_table); diff --git a/shared-bindings/microcontroller/ResetReason.h b/shared-bindings/microcontroller/ResetReason.h index df1abf266e..8ed5e48315 100644 --- a/shared-bindings/microcontroller/ResetReason.h +++ b/shared-bindings/microcontroller/ResetReason.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MCU__RESET_REASON__H -#define MICROPY_INCLUDED_SHARED_BINDINGS_MCU__RESET_REASON__H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MCU_RESET_REASON__H +#define MICROPY_INCLUDED_SHARED_BINDINGS_MCU_RESET_REASON__H #include "py/obj.h" #include "py/enum.h" @@ -37,15 +37,9 @@ typedef enum { RESET_REASON_DEEP_SLEEP_ALARM, RESET_REASON_RESET_PIN, RESET_REASON_WATCHDOG, + RESET_REASON_UNKNOWN, } mcu_reset_reason_t; -extern const cp_enum_obj_t reset_reason_POWER_ON_obj; -extern const cp_enum_obj_t reset_reason_BROWNOUT_obj; -extern const cp_enum_obj_t reset_reason_SOFTWARE_obj; -extern const cp_enum_obj_t reset_reason_DEEP_SLEEP_ALARM_obj; -extern const cp_enum_obj_t reset_reason_RESET_PIN_obj; -extern const cp_enum_obj_t reset_reason_WATCHDOG_obj; - extern const mp_obj_type_t mcu_reset_reason_type; -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MCU__RESET_REASON__H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MCU_RESET_REASON__H diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index d09cf8f445..d6ce323c58 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -56,6 +56,19 @@ //| This object is the sole instance of `microcontroller.Processor`.""" //| +//| def deep_sleep() -> None: +//| Go into deep sleep. If the board is connected via USB, disconnect USB first. +//| +//| The board will awake from deep sleep only if the reset button is pressed +//| or it is awoken by an alarm set by `alarm.set_deep_sleep_alarms()`. +//| ... +//| +STATIC mp_obj_t mcu_deep_sleep(void){ + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(mcu_deep_sleep_obj, mcu_deep_sleep); + //| def delay_us(delay: int) -> None: //| """Dedicated delay method used for very short delays. **Do not** do long delays //| because this stops all other functions from completing. Think of this as an empty @@ -164,6 +177,7 @@ const mp_obj_module_t mcu_pin_module = { STATIC const mp_rom_map_elem_t mcu_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_microcontroller) }, { MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&common_hal_mcu_processor_obj) }, + { MP_ROM_QSTR(MP_QSTR_deep_sleep), MP_ROM_PTR(&mcu_deep_sleep_obj) }, { MP_ROM_QSTR(MP_QSTR_delay_us), MP_ROM_PTR(&mcu_delay_us_obj) }, { MP_ROM_QSTR(MP_QSTR_disable_interrupts), MP_ROM_PTR(&mcu_disable_interrupts_obj) }, { MP_ROM_QSTR(MP_QSTR_enable_interrupts), MP_ROM_PTR(&mcu_enable_interrupts_obj) }, diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h index ac71de4247..c6ccccea72 100644 --- a/shared-bindings/microcontroller/__init__.h +++ b/shared-bindings/microcontroller/__init__.h @@ -43,6 +43,8 @@ extern void common_hal_mcu_enable_interrupts(void); extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode); extern void common_hal_mcu_reset(void); +extern void common_hal_mcu_deep_sleep(void); + extern const mp_obj_dict_t mcu_pin_globals; extern const mcu_processor_obj_t common_hal_mcu_processor_obj; diff --git a/shared-bindings/supervisor/RunReason.c b/shared-bindings/supervisor/RunReason.c index ee08f6d71b..7e7a74d2f4 100644 --- a/shared-bindings/supervisor/RunReason.c +++ b/shared-bindings/supervisor/RunReason.c @@ -29,7 +29,7 @@ #include "shared-bindings/supervisor/RunReason.h" MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, STARTUP, RUN_REASON_STARTUP); -MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, AUTORELOAD, RUN_REASON_AUTORELOAD); +MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, AUTORELOAD, RUN_REASON_AUTO_RELOAD); MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, SUPERVISOR_RELOAD, RUN_REASON_SUPERVISOR_RELOAD); MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, REPL_RELOAD, RUN_REASON_REPL_RELOAD); @@ -40,8 +40,8 @@ MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, REPL_RELOAD, RUN_REASON_ //| """CircuitPython started the microcontroller started up. See `microcontroller.cpu.reset_reason` //| for more detail on why the microcontroller was started.""" //| -//| AUTORELOAD: object -//| """CircuitPython restarted due to a USB write to the filesystem.""" +//| AUTO_RELOAD: object +//| """CircuitPython restarted due to an external write to the filesystem.""" //| //| SUPERVISOR_RELOAD: object //| """CircuitPython restarted due to a call to `supervisor.reload()`.""" @@ -51,7 +51,7 @@ MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, REPL_RELOAD, RUN_REASON_ //| MAKE_ENUM_MAP(run_reason) { MAKE_ENUM_MAP_ENTRY(run_reason, STARTUP), - MAKE_ENUM_MAP_ENTRY(run_reason, AUTORELOAD), + MAKE_ENUM_MAP_ENTRY(run_reason, AUTO_RELOAD), MAKE_ENUM_MAP_ENTRY(run_reason, SUPERVISOR_RELOAD), MAKE_ENUM_MAP_ENTRY(run_reason, REPL_RELOAD), }; diff --git a/shared-bindings/supervisor/RunReason.h b/shared-bindings/supervisor/RunReason.h index 934c72fd8c..391e6d3064 100644 --- a/shared-bindings/supervisor/RunReason.h +++ b/shared-bindings/supervisor/RunReason.h @@ -28,7 +28,7 @@ typedef enum { RUN_REASON_STARTUP, - RUN_REASON_AUTORELOAD, + RUN_REASON_AUTO_RELOAD, RUN_REASON_SUPERVISOR_RELOAD, RUN_REASON_REPL_RELOAD, } supervisor_run_reason_t; diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index 6500dadd59..67193e051e 100755 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -25,9 +25,13 @@ */ #include +#include "py/enum.h" #include "py/objproperty.h" +#include "shared-bindings/supervisor/RunReason.h" #include "shared-bindings/supervisor/Runtime.h" +STATIC supervisor_run_reason_t _run_reason; + //TODO: add USB, REPL to description once they're operational //| class Runtime: //| """Current status of runtime objects. @@ -94,8 +98,7 @@ const mp_obj_property_t supervisor_serial_bytes_available_obj = { //| """Returns why CircuitPython started running this particular time. //| STATIC mp_obj_t supervisor_get_run_reason(mp_obj_t self) { - mp_raise_NotImplementedError(NULL); - return mp_const_none; + return cp_enum_find(&supervisor_run_reason_type, _run_reason); } MP_DEFINE_CONST_FUN_OBJ_1(supervisor_get_run_reason_obj, supervisor_get_run_reason); @@ -106,6 +109,9 @@ const mp_obj_property_t supervisor_run_reason_obj = { (mp_obj_t)&mp_const_none_obj}, }; +void supervisor_set_run_reason(supervisor_run_reason_t run_reason) { + _run_reason = run_reason; +} STATIC const mp_rom_map_elem_t supervisor_runtime_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_serial_connected), MP_ROM_PTR(&supervisor_serial_connected_obj) }, diff --git a/shared-bindings/supervisor/Runtime.h b/shared-bindings/supervisor/Runtime.h index 2dc59c3ab6..51ed7604df 100755 --- a/shared-bindings/supervisor/Runtime.h +++ b/shared-bindings/supervisor/Runtime.h @@ -30,9 +30,12 @@ #include #include "py/obj.h" +#include "shared-bindings/supervisor/RunReason.h" extern const mp_obj_type_t supervisor_runtime_type; +void supervisor_set_run_reason(supervisor_run_reason_t run_reason); + bool common_hal_get_serial_connected(void); bool common_hal_get_serial_bytes_available(void); diff --git a/shared-bindings/supervisor/__init__.c b/shared-bindings/supervisor/__init__.c index bc6fdbff5a..4d2d6db309 100644 --- a/shared-bindings/supervisor/__init__.c +++ b/shared-bindings/supervisor/__init__.c @@ -88,6 +88,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(supervisor_set_rgb_status_brightness_obj, supervisor_s //| STATIC mp_obj_t supervisor_reload(void) { reload_requested = true; + supervisor_set_run_reason(RUN_REASON_SUPERVISOR_RELOAD); mp_raise_reload_exception(); return mp_const_none; } diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 3d76e7000a..ff08ade18a 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -106,25 +106,21 @@ void usb_irq_handler(void) { // Invoked when device is mounted void tud_mount_cb(void) { usb_msc_mount(); - _workflow_active = true; } // Invoked when device is unmounted void tud_umount_cb(void) { usb_msc_umount(); - _workflow_active = false; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allows us to perform remote wakeup // 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) { - _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 index cd19d3aa25..41af22eb70 100644 --- a/supervisor/shared/workflow.c +++ b/supervisor/shared/workflow.c @@ -25,10 +25,10 @@ */ #include - -// Set by the shared USB code. -volatile bool _workflow_active; +#include "tusb.h" bool supervisor_workflow_active(void) { - return _workflow_active; + // Eventually there might be other non-USB workflows, such as BLE. + // tud_ready() checks for usb mounted and not suspended. + return tud_ready(); }