From 73879734d9954477607199e92fe945537c3c3745 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 7 Dec 2023 10:05:39 +1100 Subject: [PATCH] esp8266: Update port to use new event functions. This is necessary to avoid watchdog timeout in long i2c.scan(), as previously machine_i2c.c would call MICROPY_EVENT_POLL_HOOK if MICROPY_EVENT_POLL_HOOK_FAST was not available. Compared to previous implementation, this implementation removes the ets_event_poll() function and calls the SDK function ets_loop_iter() from MICROPY_INTERNAL_EVENT_HOOK instead. This allows using the port-agnostic functions in more places. There is a small behaviour change, which is that the event loop gets iterated in a few more places (i.e. anywhere that mp_event_handle_nowait() is called). However, this looks like maybe only modselect.c - and is probably good to process Wi-Fi events in that polling loop. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton --- ports/esp8266/esp_mphal.c | 7 +------ ports/esp8266/esp_mphal.h | 3 --- ports/esp8266/machine_uart.c | 2 +- ports/esp8266/modespnow.c | 2 +- ports/esp8266/modmachine.c | 4 ++-- ports/esp8266/mpconfigport.h | 20 +++++++++++++++++--- ports/esp8266/uart.c | 3 ++- 7 files changed, 24 insertions(+), 17 deletions(-) diff --git a/ports/esp8266/esp_mphal.c b/ports/esp8266/esp_mphal.c index afa934e00c..956cb2e649 100644 --- a/ports/esp8266/esp_mphal.c +++ b/ports/esp8266/esp_mphal.c @@ -53,7 +53,7 @@ void mp_hal_init(void) { void MP_FASTCODE(mp_hal_delay_us)(uint32_t us) { uint32_t start = system_get_time(); while (system_get_time() - start < us) { - ets_event_poll(); + mp_event_handle_nowait(); } } @@ -122,11 +122,6 @@ uint64_t mp_hal_time_ns(void) { return pyb_rtc_get_us_since_epoch() * 1000ULL; } -void ets_event_poll(void) { - ets_loop_iter(); - mp_handle_pending(true); -} - void __assert_func(const char *file, int line, const char *func, const char *expr) { printf("assert:%s:%d:%s: %s\n", file, line, func, expr); mp_raise_msg(&mp_type_AssertionError, MP_ERROR_TEXT("C-level assert")); diff --git a/ports/esp8266/esp_mphal.h b/ports/esp8266/esp_mphal.h index 73a36a4b65..6fea6554b0 100644 --- a/ports/esp8266/esp_mphal.h +++ b/ports/esp8266/esp_mphal.h @@ -72,9 +72,6 @@ void dupterm_task_init(); uint32_t esp_disable_irq(void); void esp_enable_irq(uint32_t state); -void ets_event_poll(void); -#define ETS_POLL_WHILE(cond) { while (cond) ets_event_poll(); } - // needed for machine.I2C #include "osapi.h" #define mp_hal_delay_us_fast(us) os_delay_us(us) diff --git a/ports/esp8266/machine_uart.c b/ports/esp8266/machine_uart.c index f38858b0c2..eaaa8ac865 100644 --- a/ports/esp8266/machine_uart.c +++ b/ports/esp8266/machine_uart.c @@ -300,7 +300,7 @@ STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uint if (mp_machine_uart_txdone(self)) { return 0; } - MICROPY_EVENT_POLL_HOOK + mp_event_wait_ms(1); } while (system_get_time() < timeout); *errcode = MP_ETIMEDOUT; diff --git a/ports/esp8266/modespnow.c b/ports/esp8266/modespnow.c index 9aa5fdf9d8..170e488c10 100644 --- a/ports/esp8266/modespnow.c +++ b/ports/esp8266/modespnow.c @@ -285,7 +285,7 @@ static int ringbuf_get_bytes_wait(ringbuf_t *r, uint8_t *data, size_t len, mp_in int status = 0; while (((status = ringbuf_get_bytes(r, data, len)) == -1) && (timeout_ms < 0 || (mp_uint_t)(mp_hal_ticks_ms() - start) < (mp_uint_t)timeout_ms)) { - MICROPY_EVENT_POLL_HOOK; + mp_event_wait_ms(1); } return status; } diff --git a/ports/esp8266/modmachine.c b/ports/esp8266/modmachine.c index f41c84e14d..3cf5e3dd3b 100644 --- a/ports/esp8266/modmachine.c +++ b/ports/esp8266/modmachine.c @@ -91,7 +91,7 @@ STATIC mp_obj_t mp_machine_unique_id(void) { STATIC void mp_machine_idle(void) { asm ("waiti 0"); - ets_event_poll(); // handle any events after possibly a long wait (eg feed WDT) + mp_event_handle_nowait(); // handle any events after possibly a long wait (eg feed WDT) } STATIC void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) { @@ -106,7 +106,7 @@ STATIC void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) { uint32_t wifi_mode = wifi_get_opmode(); uint32_t start = system_get_time(); while (system_get_time() - start <= max_us) { - ets_event_poll(); + mp_event_handle_nowait(); if (wifi_mode == NULL_MODE) { // Can only idle if the wifi is off asm ("waiti 0"); diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index 07586a0ea5..bbfab64fba 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -7,6 +7,7 @@ // Board-specific definitions #include "mpconfigboard.h" +#include #include // Set the rom feature level. @@ -116,13 +117,26 @@ #define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ #define MICROPY_ESP8266_APA102 (1) -#define MICROPY_EVENT_POLL_HOOK {ets_event_poll();} +// No blocking wait-for-event on ESP8266, only non-blocking pump of the "OS" event +// loop +// +// TODO: When TIMEOUT_MS==-1, it may be possible to have MICROPY_INTERNAL_WFE() call the "waiti" instruction. +// See mp_machine_idle() and mp_machine_lightsleep() in esp8266/modmachine.c +// +// Note: We have to scope the declaration of ets_loop_iter() here as there are multiple incompatible +// definitions at compile time between the SDK and axTLS! +#define MICROPY_INTERNAL_WFE(TIMEOUT_MS) +#define MICROPY_INTERNAL_EVENT_HOOK \ + do { \ + extern bool ets_loop_iter(void); \ + ets_loop_iter(); \ + } while (0) + #define MICROPY_VM_HOOK_COUNT (10) #define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT; #define MICROPY_VM_HOOK_POLL if (--vm_hook_divisor == 0) { \ vm_hook_divisor = MICROPY_VM_HOOK_COUNT; \ - extern void ets_loop_iter(void); \ - ets_loop_iter(); \ + MICROPY_INTERNAL_EVENT_HOOK; \ } #define MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_POLL #define MICROPY_VM_HOOK_RETURN MICROPY_VM_HOOK_POLL diff --git a/ports/esp8266/uart.c b/ports/esp8266/uart.c index c0a33acb57..80ae5e6171 100644 --- a/ports/esp8266/uart.c +++ b/ports/esp8266/uart.c @@ -18,6 +18,7 @@ #include "c_types.h" #include "user_interface.h" #include "py/mphal.h" +#include "py/runtime.h" // seems that this is missing in the Espressif SDK #define FUNC_U0RXD 0 @@ -218,7 +219,7 @@ bool ICACHE_FLASH_ATTR uart_rx_wait(uint32_t timeout_us) { if (system_get_time() - start >= timeout_us) { return false; // timeout } - ets_event_poll(); + mp_event_handle_nowait(); } }