rp2: Switch rp2 and drivers to use new event functions.

This commit changes all uses in the rp2 port, and drivers that are
optionally supported by that port.

The old MICROPY_EVENT_POLL_HOOK and MICROPY_EVENT_POLL_HOOK_FAST macros are
no longer used for rp2 builds and are removed (C user code will need to be
changed to suit).

Also take the opportunity to change some timeouts that used 64-bit
arithmetic to 32-bit, to hopefully claw back a little code size.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
pull/13096/head
Angus Gratton 2023-11-30 14:34:07 +11:00 zatwierdzone przez Damien George
rodzic df3948d3c2
commit 28529351ae
8 zmienionych plików z 59 dodań i 52 usunięć

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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();

Wyświetl plik

@ -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

Wyświetl plik

@ -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 {

Wyświetl plik

@ -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)

Wyświetl plik

@ -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));
}

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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);
}