mirror of
https://github.com/W3SLAV/micropython.git
synced 2025-06-19 03:55:44 -04:00
rp2/mphalport: Refactor to use shared TinyUSB CDC functions.
Signed-off-by: Andrew Leech <andrew@alelec.net>
This commit is contained in:
parent
c98789a6d8
commit
1eaa562fdf
@ -32,6 +32,7 @@
|
||||
#include "shared/runtime/softtimer.h"
|
||||
#include "shared/timeutils/timeutils.h"
|
||||
#include "shared/tinyusb/mp_usbd.h"
|
||||
#include "shared/tinyusb/mp_usbd_cdc.h"
|
||||
#include "pendsv.h"
|
||||
#include "tusb.h"
|
||||
#include "uart.h"
|
||||
@ -58,68 +59,14 @@ ringbuf_t stdin_ringbuf = { stdin_ringbuf_array, sizeof(stdin_ringbuf_array) };
|
||||
|
||||
#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) {
|
||||
if (cdc_itf_pending & (1 << itf)) {
|
||||
tud_cdc_rx_cb(itf);
|
||||
if (!cdc_itf_pending) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tud_cdc_rx_cb(uint8_t itf) {
|
||||
// consume pending USB data immediately to free usb buffer and keep the endpoint from stalling.
|
||||
// in case the ringbuffer is full, mark the CDC interface that need attention later on for polling
|
||||
cdc_itf_pending &= ~(1 << itf);
|
||||
for (uint32_t bytes_avail = tud_cdc_n_available(itf); bytes_avail > 0; --bytes_avail) {
|
||||
if (ringbuf_free(&stdin_ringbuf)) {
|
||||
int data_char = tud_cdc_read_char();
|
||||
if (data_char == mp_interrupt_char) {
|
||||
mp_sched_keyboard_interrupt();
|
||||
} else {
|
||||
ringbuf_put(&stdin_ringbuf, data_char);
|
||||
}
|
||||
} else {
|
||||
cdc_itf_pending |= (1 << itf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
|
||||
uintptr_t ret = 0;
|
||||
#if MICROPY_HW_USB_CDC
|
||||
poll_cdc_interfaces();
|
||||
ret |= mp_usbd_cdc_poll_interfaces(poll_flags);
|
||||
#endif
|
||||
#if MICROPY_HW_ENABLE_UART_REPL || MICROPY_HW_USB_CDC
|
||||
if ((poll_flags & MP_STREAM_POLL_RD) && ringbuf_peek(&stdin_ringbuf) != -1) {
|
||||
ret |= MP_STREAM_POLL_RD;
|
||||
}
|
||||
#if MICROPY_HW_ENABLE_UART_REPL
|
||||
if (poll_flags & MP_STREAM_POLL_WR) {
|
||||
#if MICROPY_HW_ENABLE_UART_REPL
|
||||
ret |= MP_STREAM_POLL_WR;
|
||||
#else
|
||||
if (tud_cdc_connected() && tud_cdc_write_available() > 0) {
|
||||
ret |= MP_STREAM_POLL_WR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
@ -132,7 +79,7 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
|
||||
int mp_hal_stdin_rx_chr(void) {
|
||||
for (;;) {
|
||||
#if MICROPY_HW_USB_CDC
|
||||
poll_cdc_interfaces();
|
||||
mp_usbd_cdc_poll_interfaces(0);
|
||||
#endif
|
||||
|
||||
int c = ringbuf_get(&stdin_ringbuf);
|
||||
@ -159,32 +106,10 @@ mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_USB_CDC
|
||||
if (tud_cdc_connected()) {
|
||||
size_t i = 0;
|
||||
while (i < len) {
|
||||
uint32_t n = len - i;
|
||||
if (n > CFG_TUD_CDC_EP_BUFSIZE) {
|
||||
n = CFG_TUD_CDC_EP_BUFSIZE;
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
ret = i;
|
||||
break;
|
||||
}
|
||||
uint32_t n2 = tud_cdc_write(str + i, n);
|
||||
tud_cdc_write_flush();
|
||||
i += n2;
|
||||
}
|
||||
ret = MIN(i, ret);
|
||||
mp_uint_t cdc_res = mp_usbd_cdc_tx_strn(str, len);
|
||||
if (cdc_res > 0) {
|
||||
did_write = true;
|
||||
ret = MIN(cdc_res, ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user