summaryrefslogtreecommitdiff
path: root/examples/host/cdc_msc_hid/src/cdc_app.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/host/cdc_msc_hid/src/cdc_app.c')
-rw-r--r--examples/host/cdc_msc_hid/src/cdc_app.c72
1 files changed, 39 insertions, 33 deletions
diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c
index 4c2c5e807..20033981e 100644
--- a/examples/host/cdc_msc_hid/src/cdc_app.c
+++ b/examples/host/cdc_msc_hid/src/cdc_app.c
@@ -28,11 +28,13 @@
#include "bsp/board_api.h"
#include "app.h"
-static size_t get_console_inputs(uint8_t* buf, size_t bufsize) {
+static size_t console_read(uint8_t *buf, size_t bufsize) {
size_t count = 0;
while (count < bufsize) {
- int ch = board_getchar();
- if (ch <= 0) { break; }
+ const int ch = board_getchar();
+ if (ch < 0) {
+ break;
+ }
buf[count] = (uint8_t) ch;
count++;
}
@@ -40,46 +42,50 @@ static size_t get_console_inputs(uint8_t* buf, size_t bufsize) {
return count;
}
+static size_t console_write(const uint8_t *buf, size_t bufsize) {
+ // Use board_uart_write directly for non-blocking behavior.
+ // board_putchar -> sys_write has a blocking retry loop that causes UART RX overrun.
+ int wr = board_uart_write(buf, (int) bufsize);
+ return (wr > 0) ? (size_t) wr : 0;
+}
+
+// forward from console to usbh
+static void console_to_usbh(uint8_t idx) {
+ uint8_t buf[64];
+ size_t count = console_read(buf, sizeof(buf));
+ if (count > 0) {
+ tuh_cdc_write(idx, buf, count);
+ }
+}
+
void cdc_app_task(void) {
- uint8_t buf[64 + 1]; // +1 for extra null character
- uint32_t const bufsize = sizeof(buf) - 1;
+ const uint8_t idx = 0;
+
+ // Bidirectional forwarding: console <-> host cdc interfaces
+ if (!tuh_cdc_mounted(idx)) {
+ return;
+ }
- uint32_t count = get_console_inputs(buf, bufsize);
- buf[count] = 0;
+ // usbh -> uart
+ uint8_t buf[64];
+ uint32_t count = tuh_cdc_read(idx, buf, sizeof(buf));
+ uint32_t wr = 0;
- // loop over all mounted interfaces
- for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) {
- if (tuh_cdc_mounted(idx)) {
- // console --> cdc interfaces
- if (count > 0) {
- tuh_cdc_write(idx, buf, count);
- tuh_cdc_write_flush(idx);
- }
+ do {
+ // uart write is slow, while waiting forward uart -> usbh else uart rx can be overflow
+ if (count) {
+ wr += console_write(buf + wr, count - wr);
}
- }
+ console_to_usbh(idx);
+ } while (wr < count);
+
+ tuh_cdc_write_flush(idx);
}
//--------------------------------------------------------------------+
// TinyUSB callbacks
//--------------------------------------------------------------------+
-// Invoked when received new data
-void tuh_cdc_rx_cb(uint8_t idx) {
- uint8_t buf[64 + 1]; // +1 for extra null character
- uint32_t const bufsize = sizeof(buf) - 1;
-
- // forward cdc interfaces -> console
- const uint32_t count = tuh_cdc_read(idx, buf, bufsize);
- if (count) {
- buf[count] = 0;
- printf("%s", (char*) buf);
-
- #ifndef __ICCARM__ // TODO IAR doesn't support stream control ?
- fflush(stdout);// flush right away, else nanolib will wait for newline
- #endif
- }
-}
-
// Invoked when a device with CDC interface is mounted
// idx is index of cdc interface in the internal pool.
void tuh_cdc_mount_cb(uint8_t idx) {