diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 5216c69d0f..dda2cbd02c 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -193,6 +193,7 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/espressif/common-hal/coproc/Coproc.c #: ports/nrf/common-hal/pulseio/PulseIn.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c @@ -485,6 +486,7 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/common-hal/coproc/__init__.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -1015,7 +1017,7 @@ msgstr "" msgid "Firmware is invalid" msgstr "" -#: ports/espressif/common-hal/coproc/__init__.c +#: ports/espressif/common-hal/coproc/Coproc.c #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is too big" msgstr "" diff --git a/ports/espressif/common-hal/alarm/coproc/CoprocAlarm.c b/ports/espressif/common-hal/alarm/coproc/CoprocAlarm.c index 3e0cff1c4c..aa49e13a2a 100644 --- a/ports/espressif/common-hal/alarm/coproc/CoprocAlarm.c +++ b/ports/espressif/common-hal/alarm/coproc/CoprocAlarm.c @@ -27,9 +27,16 @@ #include "shared-bindings/alarm/coproc/CoprocAlarm.h" #include "shared-bindings/coproc/__init__.h" +#if CIRCUITPY_COPROC + +#include "supervisor/port.h" + +#include "driver/rtc_cntl.h" +#include "soc/rtc_cntl_reg.h" + #include "esp_sleep.h" -#if CIRCUITPY_COPROC +static volatile bool woke_up = false; mp_obj_t alarm_coproc_coprocalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms) { for (size_t i = 0; i < n_alarms; i++) { @@ -47,6 +54,13 @@ mp_obj_t alarm_coproc_coprocalarm_create_wakeup_alarm(void) { return alarm; } +// This is used to wake the main CircuitPython task. +STATIC void coproc_interrupt(void *arg) { + (void)arg; + woke_up = true; + port_wake_main_task_from_isr(); +} + void alarm_coproc_coprocalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms) { bool coproc_alarm_set = false; alarm_coproc_coprocalarm_obj_t *coproc_alarm = MP_OBJ_NULL; @@ -65,13 +79,18 @@ void alarm_coproc_coprocalarm_set_alarm(const bool deep_sleep, const size_t n_al return; } - // load coproc program - common_hal_coproc_load(coproc_alarm->coproc); + // enable coproc interrupt + rtc_isr_register(&coproc_interrupt, NULL, RTC_CNTL_COCPU_INT_ST); + REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_COCPU_INT_ENA); + + // start coproc program + common_hal_coproc_run(coproc_alarm->coproc); } void alarm_coproc_coprocalarm_prepare_for_deep_sleep(void) { - // start coproc program - common_hal_coproc_run(NULL); + // disbale coproc interrupt + rtc_isr_deregister(&coproc_interrupt, NULL); + REG_CLR_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_COCPU_INT_ENA); // enable coproc wakeup esp_sleep_enable_ulp_wakeup(); @@ -79,10 +98,11 @@ void alarm_coproc_coprocalarm_prepare_for_deep_sleep(void) { } bool alarm_coproc_coprocalarm_woke_this_cycle(void) { - return false; + return woke_up; } void alarm_coproc_coprocalarm_reset(void) { + woke_up = false; } #else // CIRCUITPY_COPROC diff --git a/ports/espressif/common-hal/coproc/Coproc.c b/ports/espressif/common-hal/coproc/Coproc.c index 1216b5dde3..c2115c1e94 100644 --- a/ports/espressif/common-hal/coproc/Coproc.c +++ b/ports/espressif/common-hal/coproc/Coproc.c @@ -27,12 +27,33 @@ #include "shared-bindings/coproc/Coproc.h" #include "shared-bindings/coproc/CoprocMemory.h" +#include "py/runtime.h" + +#if defined(CONFIG_IDF_TARGET_ESP32S2) +#include "esp32s2/ulp.h" +#define ULP_COPROC_RESERVE_MEM (CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM) +#elif defined(CONFIG_IDF_TARGET_ESP32S3) +#include "esp32s3/ulp.h" +#define ULP_COPROC_RESERVE_MEM (CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM) +#endif + +#define RTC_SLOW_MEM_END ((uint32_t)RTC_SLOW_MEM + ULP_COPROC_RESERVE_MEM) + void common_hal_coproc_coproc_construct(coproc_coproc_obj_t *self, const uint8_t *buf, const size_t buf_len, coproc_memory_obj_t *coproc_memory) { // set CoprocMemory object + if (coproc_memory != NULL) { + if (coproc_memory->address < ((uint32_t)RTC_SLOW_MEM + buf_len) || + coproc_memory->address > (RTC_SLOW_MEM_END - coproc_memory->len)) { + mp_raise_ValueError_varg(translate("%q out of range"), MP_QSTR_CoprocMemory); + } + } self->coproc_memory = coproc_memory; // load buffer + if (buf_len > ULP_COPROC_RESERVE_MEM) { + mp_raise_RuntimeError(translate("Firmware is too big")); + } self->buf_len = buf_len; self->buf = (uint8_t *)m_malloc(self->buf_len, false); memcpy(self->buf, buf, self->buf_len); diff --git a/ports/espressif/common-hal/coproc/__init__.c b/ports/espressif/common-hal/coproc/__init__.c index 9fce6afcdf..e372bfa235 100644 --- a/ports/espressif/common-hal/coproc/__init__.c +++ b/ports/espressif/common-hal/coproc/__init__.c @@ -40,6 +40,14 @@ #include "soc/rtc_cntl_reg.h" void common_hal_coproc_run(coproc_coproc_obj_t *self) { + if (GET_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN)) { + mp_raise_RuntimeError(translate("Already running")); + } + + ulp_riscv_load_binary(self->buf, self->buf_len); + m_free(self->buf); + self->buf = (uint8_t *)RTC_SLOW_MEM; + ulp_riscv_run(); } @@ -55,18 +63,10 @@ void common_hal_coproc_halt(coproc_coproc_obj_t *self) { CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN); // suspends the ulp operation SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_DONE); - // Resets the processor + // resets the processor SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN); } -void common_hal_coproc_load(coproc_coproc_obj_t *self) { - if (ulp_riscv_load_binary(self->buf, self->buf_len) != ESP_OK) { - mp_raise_RuntimeError(translate("Firmware is too big")); - } - m_free(self->buf); - self->buf = (uint8_t *)RTC_SLOW_MEM; -} - mp_obj_t common_hal_coproc_memory(coproc_coproc_obj_t *self) { return (self->coproc_memory) ? MP_OBJ_FROM_PTR(self->coproc_memory) : mp_const_none; } diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults index d96a6c5366..bfd64ef90e 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults @@ -42,7 +42,7 @@ CONFIG_ESP32S2_DATA_CACHE_LINE_32B=y # CONFIG_ESP32S2_TRAX is not set CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM=0x0 CONFIG_ESP32S2_ULP_COPROC_ENABLED=y -CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=4096 +CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=8176 CONFIG_ESP32S2_ULP_COPROC_RISCV=y CONFIG_ESP32S2_DEBUG_OCDAWARE=y # CONFIG_ESP32S2_DEBUG_STUBS_ENABLE is not set diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults index 30a71c6a44..f6fb80c752 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults @@ -68,7 +68,7 @@ CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32 # CONFIG_ESP32S3_TRAX is not set CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM=0x0 CONFIG_ESP32S3_ULP_COPROC_ENABLED=y -CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=4096 +CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=8176 CONFIG_ESP32S3_ULP_COPROC_RISCV=y CONFIG_ESP32S3_BROWNOUT_DET=y CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y diff --git a/shared-bindings/coproc/__init__.c b/shared-bindings/coproc/__init__.c index 1709e9b203..06b196d8be 100644 --- a/shared-bindings/coproc/__init__.c +++ b/shared-bindings/coproc/__init__.c @@ -68,9 +68,7 @@ STATIC coproc_coproc_obj_t *get_coproc_obj(mp_obj_t *self_in) { //| ... //| STATIC mp_obj_t coproc_run(mp_obj_t self_in) { - coproc_coproc_obj_t *self = get_coproc_obj(&self_in); - common_hal_coproc_load(self); - common_hal_coproc_run(self); + common_hal_coproc_run(get_coproc_obj(&self_in)); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(coproc_run_obj, coproc_run); diff --git a/shared-bindings/coproc/__init__.h b/shared-bindings/coproc/__init__.h index 0609bf827b..6f2b2a56ae 100644 --- a/shared-bindings/coproc/__init__.h +++ b/shared-bindings/coproc/__init__.h @@ -32,7 +32,6 @@ extern void common_hal_coproc_run(coproc_coproc_obj_t *self); extern void common_hal_coproc_halt(coproc_coproc_obj_t *self); -extern void common_hal_coproc_load(coproc_coproc_obj_t *self); extern mp_obj_t common_hal_coproc_memory(coproc_coproc_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_COPROC___INIT___H