summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/rp2/CMakeLists.txt1
-rw-r--r--ports/rp2/mphalport.c80
2 files changed, 46 insertions, 35 deletions
diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt
index d58fb5687..a5e421734 100644
--- a/ports/rp2/CMakeLists.txt
+++ b/ports/rp2/CMakeLists.txt
@@ -72,6 +72,7 @@ set(MICROPY_SOURCE_LIB
${MICROPY_DIR}/shared/readline/readline.c
${MICROPY_DIR}/shared/runtime/gchelper_m0.s
${MICROPY_DIR}/shared/runtime/gchelper_native.c
+ ${MICROPY_DIR}/shared/runtime/interrupt_char.c
${MICROPY_DIR}/shared/runtime/mpirq.c
${MICROPY_DIR}/shared/runtime/pyexec.c
${MICROPY_DIR}/shared/runtime/stdout_helpers.c
diff --git a/ports/rp2/mphalport.c b/ports/rp2/mphalport.c
index c4169fb66..4a5221cae 100644
--- a/ports/rp2/mphalport.c
+++ b/ports/rp2/mphalport.c
@@ -28,50 +28,69 @@
#include "py/stream.h"
#include "py/mphal.h"
#include "extmod/misc.h"
+#include "shared/runtime/interrupt_char.h"
#include "shared/timeutils/timeutils.h"
#include "tusb.h"
#include "uart.h"
#include "hardware/rtc.h"
-#if MICROPY_HW_ENABLE_UART_REPL
+#if MICROPY_HW_ENABLE_UART_REPL || MICROPY_HW_ENABLE_USBDEV
-#ifndef UART_BUFFER_LEN
-// reasonably big so we can paste
-#define UART_BUFFER_LEN 256
+#ifndef MICROPY_HW_STDIN_BUFFER_LEN
+#define MICROPY_HW_STDIN_BUFFER_LEN 512
#endif
-STATIC uint8_t stdin_ringbuf_array[UART_BUFFER_LEN];
+STATIC uint8_t stdin_ringbuf_array[MICROPY_HW_STDIN_BUFFER_LEN];
ringbuf_t stdin_ringbuf = { stdin_ringbuf_array, sizeof(stdin_ringbuf_array) };
#endif
-#if MICROPY_KBD_EXCEPTION
+#if MICROPY_HW_ENABLE_USBDEV
-int mp_interrupt_char = -1;
+uint8_t cdc_itf_pending; // keep track of cdc interfaces which need attention to poll
-void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) {
- (void)itf;
- (void)wanted_char;
- tud_cdc_read_char(); // discard interrupt char
- mp_sched_keyboard_interrupt();
+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 mp_hal_set_interrupt_char(int c) {
- mp_interrupt_char = c;
- tud_cdc_set_wanted_char(c);
+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_ENABLE_UART_REPL
- if ((poll_flags & MP_STREAM_POLL_RD) && ringbuf_peek(&stdin_ringbuf) != -1) {
- ret |= MP_STREAM_POLL_RD;
- }
- #endif
#if MICROPY_HW_ENABLE_USBDEV
- if (tud_cdc_connected() && tud_cdc_available()) {
+ poll_cdc_interfaces();
+ #endif
+ #if MICROPY_HW_ENABLE_UART_REPL || MICROPY_HW_ENABLE_USBDEV
+ if ((poll_flags & MP_STREAM_POLL_RD) && ringbuf_peek(&stdin_ringbuf) != -1) {
ret |= MP_STREAM_POLL_RD;
}
#endif
@@ -84,21 +103,14 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
// Receive single character
int mp_hal_stdin_rx_chr(void) {
for (;;) {
- #if MICROPY_HW_ENABLE_UART_REPL
+ #if MICROPY_HW_ENABLE_USBDEV
+ poll_cdc_interfaces();
+ #endif
+
int c = ringbuf_get(&stdin_ringbuf);
if (c != -1) {
return c;
}
- #endif
- #if MICROPY_HW_ENABLE_USBDEV
- if (tud_cdc_connected() && tud_cdc_available()) {
- uint8_t buf[1];
- uint32_t count = tud_cdc_read(buf, sizeof(buf));
- if (count) {
- return buf[0];
- }
- }
- #endif
#if MICROPY_PY_OS_DUPTERM
int dupterm_c = mp_uos_dupterm_rx_chr();
if (dupterm_c >= 0) {
@@ -123,11 +135,9 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
n = CFG_TUD_CDC_EP_BUFSIZE;
}
while (n > tud_cdc_write_available()) {
- tud_task();
- tud_cdc_write_flush();
+ MICROPY_EVENT_POLL_HOOK
}
uint32_t n2 = tud_cdc_write(str + i, n);
- tud_task();
tud_cdc_write_flush();
i += n2;
}