diff --git a/drivers/cyw43/cywbt.c b/drivers/cyw43/cywbt.c index d1b19382c5..3f454485ab 100644 --- a/drivers/cyw43/cywbt.c +++ b/drivers/cyw43/cywbt.c @@ -68,7 +68,7 @@ STATIC int cywbt_hci_cmd_raw(size_t len, uint8_t *buf) { mp_bluetooth_hci_uart_write((void *)buf, len); for (int c, i = 0; i < 6; ++i) { while ((c = mp_bluetooth_hci_uart_readchar()) == -1) { - MICROPY_EVENT_POLL_HOOK + mp_event_wait_indefinite(); } buf[i] = c; } @@ -88,7 +88,7 @@ STATIC int cywbt_hci_cmd_raw(size_t len, uint8_t *buf) { int sz = buf[2] - 3; for (int c, i = 0; i < sz; ++i) { while ((c = mp_bluetooth_hci_uart_readchar()) == -1) { - MICROPY_EVENT_POLL_HOOK + mp_event_wait_indefinite(); } buf[i] = c; } diff --git a/drivers/ninaw10/nina_bt_hci.c b/drivers/ninaw10/nina_bt_hci.c index 754e99ed76..f0d1b9bc89 100644 --- a/drivers/ninaw10/nina_bt_hci.c +++ b/drivers/ninaw10/nina_bt_hci.c @@ -75,12 +75,13 @@ static int nina_hci_cmd(int ogf, int ocf, size_t param_len, const uint8_t *param // Receive HCI event packet, initially reading 3 bytes (HCI Event, Event code, Plen). for (mp_uint_t start = mp_hal_ticks_ms(), size = 3, i = 0; i < size;) { while (!mp_bluetooth_hci_uart_any()) { - MICROPY_EVENT_POLL_HOOK + mp_uint_t elapsed = mp_hal_ticks_ms() - start; // Timeout. - if ((mp_hal_ticks_ms() - start) > HCI_COMMAND_TIMEOUT) { + if (elapsed > HCI_COMMAND_TIMEOUT) { error_printf("timeout waiting for HCI packet\n"); return -1; } + mp_event_wait_ms(HCI_COMMAND_TIMEOUT - elapsed); } buf[i] = mp_bluetooth_hci_uart_readchar(); diff --git a/ports/rp2/cyw43_configport.h b/ports/rp2/cyw43_configport.h index 96324ee5ec..b69cfbc263 100644 --- a/ports/rp2/cyw43_configport.h +++ b/ports/rp2/cyw43_configport.h @@ -30,6 +30,7 @@ #include "py/mpconfig.h" #include "py/mperrno.h" #include "py/mphal.h" +#include "py/runtime.h" #include "extmod/modnetwork.h" #include "pendsv.h" @@ -119,6 +120,6 @@ static inline void cyw43_delay_ms(uint32_t ms) { mp_hal_delay_ms(ms); } -#define CYW43_EVENT_POLL_HOOK MICROPY_EVENT_POLL_HOOK_FAST +#define CYW43_EVENT_POLL_HOOK mp_event_handle_nowait() #endif // MICROPY_INCLUDED_RP2_CYW43_CONFIGPORT_H diff --git a/ports/rp2/machine_uart.c b/ports/rp2/machine_uart.c index dae57012a8..e48924f09a 100644 --- a/ports/rp2/machine_uart.c +++ b/ports/rp2/machine_uart.c @@ -454,8 +454,8 @@ STATIC void mp_machine_uart_sendbreak(machine_uart_obj_t *self) { STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint64_t t = time_us_64() + (uint64_t)self->timeout * 1000; - uint64_t timeout_char_us = (uint64_t)self->timeout_char * 1000; + mp_uint_t start = mp_hal_ticks_ms(); + mp_uint_t timeout = self->timeout; uint8_t *dest = buf_in; for (size_t i = 0; i < size; i++) { @@ -466,7 +466,8 @@ STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t uart_drain_rx_fifo(self); break; } - if (time_us_64() > t) { // timed out + mp_uint_t elapsed = mp_hal_ticks_ms() - start; + if (elapsed > timeout) { // timed out if (i <= 0) { *errcode = MP_EAGAIN; return MP_STREAM_ERROR; @@ -474,18 +475,19 @@ STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t return i; } } - MICROPY_EVENT_POLL_HOOK + mp_event_wait_ms(timeout - elapsed); } *dest++ = ringbuf_get(&(self->read_buffer)); - t = time_us_64() + timeout_char_us; + start = mp_hal_ticks_ms(); // Inter-character timeout + timeout = self->timeout_char; } return size; } STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint64_t t = time_us_64() + (uint64_t)self->timeout * 1000; - uint64_t timeout_char_us = (uint64_t)self->timeout_char * 1000; + mp_uint_t start = mp_hal_ticks_ms(); + mp_uint_t timeout = self->timeout; const uint8_t *src = buf_in; size_t i = 0; @@ -502,7 +504,8 @@ STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_ while (i < size) { // Wait for the first/next character to be sent. while (ringbuf_free(&(self->write_buffer)) == 0) { - if (time_us_64() > t) { // timed out + mp_uint_t elapsed = mp_hal_ticks_ms() - start; + if (elapsed > timeout) { // timed out if (i <= 0) { *errcode = MP_EAGAIN; return MP_STREAM_ERROR; @@ -510,11 +513,12 @@ STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_ return i; } } - MICROPY_EVENT_POLL_HOOK + mp_event_wait_ms(timeout - elapsed); } ringbuf_put(&(self->write_buffer), *src++); ++i; - t = time_us_64() + timeout_char_us; + start = mp_hal_ticks_ms(); // Inter-character timeout + timeout = self->timeout_char; uart_fill_tx_fifo(self); } @@ -539,12 +543,16 @@ STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uint // Take the worst case assumptions at 13 bit symbol size times 2. uint64_t timeout = time_us_64() + (uint64_t)(33 + self->write_buffer.size) * 13000000ll * 2 / self->baudrate; - do { + while (1) { if (mp_machine_uart_txdone(self)) { return 0; } - MICROPY_EVENT_POLL_HOOK - } while (time_us_64() < timeout); + uint64_t now = time_us_64(); + if (now >= timeout) { + break; + } + mp_event_wait_ms((timeout - now) / 1000); + } *errcode = MP_ETIMEDOUT; ret = MP_STREAM_ERROR; } else { diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 5ff384c923..b349e0d67b 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -249,18 +249,19 @@ extern const struct _mp_obj_type_t mod_network_nic_type_wiznet5k; #define MICROPY_PY_LWIP_REENTER lwip_lock_acquire(); #define MICROPY_PY_LWIP_EXIT lwip_lock_release(); -#define MICROPY_EVENT_POLL_HOOK_FAST \ - do { \ - extern void mp_handle_pending(bool); \ - mp_handle_pending(true); \ +// Port level Wait-for-Event macro +// +// Do not use this macro directly, include py/runtime.h and +// call mp_event_wait_indefinite() or mp_event_wait_ms(timeout) +#define MICROPY_INTERNAL_WFE(TIMEOUT_MS) \ + do { \ + if ((TIMEOUT_MS) < 0) { \ + __wfe(); \ + } else { \ + best_effort_wfe_or_timeout(make_timeout_time_ms(TIMEOUT_MS)); \ + } \ } while (0) -#define MICROPY_EVENT_POLL_HOOK \ - do { \ - MICROPY_EVENT_POLL_HOOK_FAST; \ - __wfe(); \ - } while (0); - #define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1)) #define MP_SSIZE_MAX (0x7fffffff) diff --git a/ports/rp2/mphalport.c b/ports/rp2/mphalport.c index 1fb833f2e5..1c784fd737 100644 --- a/ports/rp2/mphalport.c +++ b/ports/rp2/mphalport.c @@ -59,24 +59,17 @@ ringbuf_t stdin_ringbuf = { stdin_ringbuf_array, sizeof(stdin_ringbuf_array) }; #endif -#if MICROPY_HW_USB_CDC -// Explicitly run the USB stack in case the scheduler is locked (eg we are in an -// interrupt handler) and there is in/out data pending on the USB CDC interface. -#define MICROPY_EVENT_POLL_HOOK_WITH_USB \ - do { \ - MICROPY_EVENT_POLL_HOOK; \ - mp_usbd_task(); \ - } while (0) - -#else -#define MICROPY_EVENT_POLL_HOOK_WITH_USB MICROPY_EVENT_POLL_HOOK -#endif - #if MICROPY_HW_USB_CDC uint8_t cdc_itf_pending; // keep track of cdc interfaces which need attention to poll void poll_cdc_interfaces(void) { + if (!cdc_itf_pending) { + // Explicitly run the USB stack as the scheduler may be locked (eg we are in + // an interrupt handler) while there is data pending. + mp_usbd_task(); + } + // any CDC interfaces left to poll? if (cdc_itf_pending && ringbuf_free(&stdin_ringbuf)) { for (uint8_t itf = 0; itf < 8; ++itf) { @@ -153,7 +146,7 @@ int mp_hal_stdin_rx_chr(void) { return dupterm_c; } #endif - MICROPY_EVENT_POLL_HOOK_WITH_USB; + mp_event_wait_indefinite(); } } @@ -173,7 +166,11 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { int timeout = 0; // Wait with a max of USC_CDC_TIMEOUT ms while (n > tud_cdc_write_available() && timeout++ < MICROPY_HW_USB_CDC_TX_TIMEOUT) { - MICROPY_EVENT_POLL_HOOK_WITH_USB; + mp_event_wait_ms(1); + + // Explicitly run the USB stack as the scheduler may be locked (eg we + // are in an interrupt handler), while there is data pending. + mp_usbd_task(); } if (timeout >= MICROPY_HW_USB_CDC_TX_TIMEOUT) { break; @@ -193,7 +190,7 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { void mp_hal_delay_ms(mp_uint_t ms) { absolute_time_t t = make_timeout_time_ms(ms); do { - MICROPY_EVENT_POLL_HOOK_FAST; + mp_event_handle_nowait(); } while (!best_effort_wfe_or_timeout(t)); } diff --git a/ports/rp2/rp2_flash.c b/ports/rp2/rp2_flash.c index bc284cd976..b1afe1cbd1 100644 --- a/ports/rp2/rp2_flash.c +++ b/ports/rp2/rp2_flash.c @@ -121,11 +121,10 @@ STATIC mp_obj_t rp2_flash_readblocks(size_t n_args, const mp_obj_t *args) { offset += mp_obj_get_int(args[3]); } memcpy(bufinfo.buf, (void *)(XIP_BASE + self->flash_base + offset), bufinfo.len); - // MICROPY_EVENT_POLL_HOOK_FAST is called here to avoid a fail in registering + // mp_event_handle_nowait() is called here to avoid a fail in registering // USB at boot time, if the board is busy loading files or scanning the file - // system. MICROPY_EVENT_POLL_HOOK_FAST calls tud_task(). As the alternative - // tud_task() should be called in the USB IRQ. See discussion in PR #10423. - MICROPY_EVENT_POLL_HOOK_FAST; + // system. mp_event_handle_nowait() will call the TinyUSB task if needed. + mp_event_handle_nowait(); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rp2_flash_readblocks_obj, 3, 4, rp2_flash_readblocks); @@ -140,7 +139,7 @@ STATIC mp_obj_t rp2_flash_writeblocks(size_t n_args, const mp_obj_t *args) { mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); flash_range_erase(self->flash_base + offset, bufinfo.len); MICROPY_END_ATOMIC_SECTION(atomic_state); - MICROPY_EVENT_POLL_HOOK_FAST; + mp_event_handle_nowait(); // TODO check return value } else { offset += mp_obj_get_int(args[3]); @@ -149,7 +148,7 @@ STATIC mp_obj_t rp2_flash_writeblocks(size_t n_args, const mp_obj_t *args) { mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); flash_range_program(self->flash_base + offset, bufinfo.buf, bufinfo.len); MICROPY_END_ATOMIC_SECTION(atomic_state); - MICROPY_EVENT_POLL_HOOK_FAST; + mp_event_handle_nowait(); // TODO check return value return mp_const_none; } diff --git a/ports/rp2/rp2_pio.c b/ports/rp2/rp2_pio.c index 2e30475257..3a0ab844ea 100644 --- a/ports/rp2/rp2_pio.c +++ b/ports/rp2/rp2_pio.c @@ -729,7 +729,7 @@ STATIC mp_obj_t rp2_state_machine_get(size_t n_args, const mp_obj_t *args) { for (;;) { while (pio_sm_is_rx_fifo_empty(self->pio, self->sm)) { // This delay must be fast. - MICROPY_EVENT_POLL_HOOK_FAST; + mp_event_handle_nowait(); } uint32_t value = pio_sm_get(self->pio, self->sm) >> shift; if (dest == NULL) { @@ -787,7 +787,7 @@ STATIC mp_obj_t rp2_state_machine_put(size_t n_args, const mp_obj_t *args) { } while (pio_sm_is_tx_fifo_full(self->pio, self->sm)) { // This delay must be fast. - MICROPY_EVENT_POLL_HOOK_FAST; + mp_event_handle_nowait(); } pio_sm_put(self->pio, self->sm, value << shift); }