8000 shared/tinyusb: Add common cdc tx/rx functions. by andrewleech · Pull Request #14462 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content

shared/tinyusb: Add common cdc tx/rx functions. #14462

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ports/esp32/boards/ARDUINO_NANO_ESP32/mpconfigboard.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ set(SDKCONFIG_DEFAULTS
set(MICROPY_SOURCE_BOARD
${MICROPY_BOARD_DIR}/board_init.c
${MICROPY_BOARD_DIR}/double_tap.c
${MICROPY_DIR}/shared/tinyusb/mp_cdc_common.c
${MICROPY_DIR}/shared/tinyusb/mp_usbd_cdc.c
)

set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)
2 changes: 2 additions & 0 deletions ports/mimxrt/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ SHARED_SRC_C += \
shared/runtime/stdout_helpers.c \
shared/runtime/sys_stdio_mphal.c \
shared/timeutils/timeutils.c \
shared/tinyusb/mp_usbd.c \
shared/tinyusb/mp_usbd_cdc.c \

# Set flash driver name, base address and internal flash flag, based on the flash type.
ifeq ($(MICROPY_HW_FLASH_TYPE),$(filter $(MICROPY_HW_FLASH_TYPE),qspi_nor_flash))
Expand Down
1 change: 1 addition & 0 deletions ports/mimxrt/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ uint32_t trng_random_u32(void);
#endif

#define MICROPY_HW_ENABLE_USBDEV (1)
#define MICROPY_HW_USB_CDC (1)

// Hooks to add builtins

Expand Down
72 changes: 6 additions & 66 deletions ports/mimxrt/mphalport.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "py/mphal.h"
#include "shared/timeutils/timeutils.h"
#include "shared/runtime/interrupt_char.h"
#include "shared/tinyusb/mp_usbd_cdc.h"
#include "extmod/misc.h"
#include "ticks.h"
#include "tusb.h"
Expand All @@ -44,51 +45,9 @@
static uint8_t stdin_ringbuf_array[MICROPY_HW_STDIN_BUFFER_LEN];
ringbuf_t stdin_ringbuf = {stdin_ringbuf_array, sizeof(stdin_ringbuf_array), 0, 0};

uint8_t cdc_itf_pending; // keep track of cdc interfaces which need attention to poll

void poll_cdc_interfaces(void) {
// 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;
}
}
}

uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
uintptr_t ret = 0;
poll_cdc_interfaces();
if ((poll_flags & MP_STREAM_POLL_RD) && ringbuf_peek(&stdin_ringbuf) != -1) {
ret |= MP_STREAM_POLL_RD;
}
if ((poll_flags & MP_STREAM_POLL_WR) && tud_cdc_connected() && tud_cdc_write_available() > 0) {
ret |= MP_STREAM_POLL_WR;
}
ret |= mp_usbd_cdc_poll_interfaces(poll_flags);
#if MICROPY_PY_OS_DUPTERM
ret |= mp_os_dupterm_poll(poll_flags);
#endif
Expand All @@ -97,7 +56,7 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {

int mp_hal_stdin_rx_chr(void) {
for (;;) {
poll_cdc_interfaces();
mp_usbd_cdc_poll_interfaces(0);
int c = ringbuf_get(&stdin_ringbuf);
if (c != -1) {
return c;
Expand All @@ -115,29 +74,10 @@ int mp_hal_stdin_rx_chr(void) {
mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
mp_uint_t ret = len;
bool did_write = false;
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;
}
uint64_t timeout = ticks_us64() + (uint64_t)(MICROPY_HW_USB_CDC_TX_TIMEOUT * 1000);
// Wait with a max of USC_CDC_TIMEOUT ms
while (n > tud_cdc_write_available() && ticks_us64() < timeout) {
MICROPY_EVENT_POLL_HOOK
}
if (ticks_us64() >= timeout) {
ret = i;
break;
}

uint32_t n2 = tud_cdc_write(str + i, n);
tud_cdc_write_flush();
i += n2;
}
mp_uint_t cdc_res = mp_usbd_cdc_tx_strn(str, len);
if (cdc_res > 0) {
did_write = true;
ret = MIN(i, ret);
ret = MIN(cdc_res, ret);
}
#if MICROPY_PY_OS_DUPTERM
int dupterm_res = mp_os_dupterm_tx_strn(str, len);
Expand Down
1 change: 1 addition & 0 deletions ports/mimxrt/mphalport.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
#define MP_HAL_PIN_TRIGGER_RISE kGPIO_IntRisingEdge
#define MP_HAL_PIN_TRIGGER_RISE_FALL kGPIO_IntRisingOrFallingEdge

extern int mp_interrupt_char;
extern ringbuf_t stdin_ringbuf;

// Define an alias for systick_ms, because the shared softtimer.c uses
Expand Down
2 changes: 1 addition & 1 deletion ports/nrf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ SRC_SHARED_C += $(addprefix shared/,\
runtime/pyexec.c \
runtime/sys_stdio_mphal.c \
runtime/interrupt_char.c \
tinyusb/mp_cdc_common.c \
tinyusb/mp_usbd_cdc.c \
timeutils/timeutils.c \
)

Expand Down
2 changes: 1 addition & 1 deletion ports/renesas-ra/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ SHARED_SRC_C += $(addprefix shared/,\
runtime/stdout_helpers.c \
runtime/sys_stdio_mphal.c \
timeutils/timeutils.c \
tinyusb/mp_cdc_common.c \
tinyusb/mp_usbd.c \
tinyusb/mp_usbd_cdc.c \
tinyusb/mp_usbd_descriptor.c \
)

Expand Down
76 changes: 7 additions & 69 deletions ports/renesas-ra/mphalport.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "py/ringbuf.h"
#include "extmod/misc.h"
#include "shared/runtime/interrupt_char.h"
#include "shared/tinyusb/mp_usbd_cdc.h"
#include "tusb.h"
#include "uart.h"

Expand Down Expand Up @@ -64,62 +65,16 @@ NORETURN void mp_hal_raise(HAL_StatusTypeDef status) {
mp_raise_OSError(mp_hal_status_to_errno_table[status]);
}

#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) {
// 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
Expand All @@ -132,7 +87,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

#if MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE
Expand Down Expand Up @@ -165,27 +120,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) {
MICROPY_EVENT_POLL_HOOK
}
if (timeout >= MICROPY_HW_USB_CDC_TX_TIMEOUT) {
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

Expand Down
1 change: 1 addition & 0 deletions ports/renesas-ra/mphalport.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#define MICROPY_HW_USB_CDC_TX_TIMEOUT (500)

extern const unsigned char mp_hal_status_to_errno_table[4];
extern int mp_interrupt_char;
extern ringbuf_t stdin_ringbuf;

static inline int mp_hal_status_to_neg_errno(HAL_StatusTypeDef status) {
Expand Down
2 changes: 1 addition & 1 deletion ports/rp2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ set(MICROPY_SOURCE_LIB
${MICROPY_DIR}/shared/runtime/softtimer.c
${MICROPY_DIR}/shared/runtime/sys_stdio_mphal.c
${MICROPY_DIR}/shared/timeutils/timeutils.c
${MICROPY_DIR}/shared/tinyusb/mp_cdc_common.c
${MICROPY_DIR}/shared/tinyusb/mp_usbd.c
${MICROPY_DIR}/shared/tinyusb/mp_usbd_cdc.c
${MICROPY_DIR}/shared/tinyusb/mp_usbd_descriptor.c
${MICROPY_DIR}/shared/tinyusb/mp_usbd_runtime.c
)
Expand Down
Loading
Loading
0