esp32/usb: Add USB host connection detection for CDC serial output.

This callback allows detecting if there is a USB host connected to the CDC
or not, in which case the stdout_tx should skip CDC TX writing and
flushing or the system will block.

Fixes issue #7820.
This commit is contained in:
Seon Rozenblum 2021-09-20 14:04:08 +10:00 committed by Damien George
parent 7bf466a281
commit 35fb90bd57
1 changed files with 16 additions and 1 deletions

View File

@ -36,6 +36,7 @@
#define CDC_ITF TINYUSB_CDC_ACM_0 #define CDC_ITF TINYUSB_CDC_ACM_0
static uint8_t usb_rx_buf[CONFIG_USB_CDC_RX_BUFSIZE]; static uint8_t usb_rx_buf[CONFIG_USB_CDC_RX_BUFSIZE];
static uint8_t usb_cdc_connected;
static void usb_callback_rx(int itf, cdcacm_event_t *event) { static void usb_callback_rx(int itf, cdcacm_event_t *event) {
// TODO: what happens if more chars come in during this function, are they lost? // TODO: what happens if more chars come in during this function, are they lost?
@ -58,6 +59,13 @@ static void usb_callback_rx(int itf, cdcacm_event_t *event) {
} }
} }
void usb_callback_line_state_changed(int itf, cdcacm_event_t *event) {
int dtr = event->line_state_changed_data.dtr;
int rts = event->line_state_changed_data.rts;
// If dtr && rts are both true, the CDC is connected to a HOST.
usb_cdc_connected = dtr && rts;
}
void usb_init(void) { void usb_init(void) {
// Initialise the USB with defaults. // Initialise the USB with defaults.
tinyusb_config_t tusb_cfg = {0}; tinyusb_config_t tusb_cfg = {0};
@ -70,13 +78,20 @@ void usb_init(void) {
.rx_unread_buf_sz = 256, .rx_unread_buf_sz = 256,
.callback_rx = &usb_callback_rx, .callback_rx = &usb_callback_rx,
.callback_rx_wanted_char = NULL, .callback_rx_wanted_char = NULL,
.callback_line_state_changed = NULL, .callback_line_state_changed = &usb_callback_line_state_changed,
.callback_line_coding_changed = NULL .callback_line_coding_changed = NULL
}; };
usb_cdc_connected = 0;
ESP_ERROR_CHECK(tusb_cdc_acm_init(&amc_cfg)); ESP_ERROR_CHECK(tusb_cdc_acm_init(&amc_cfg));
} }
void usb_tx_strn(const char *str, size_t len) { void usb_tx_strn(const char *str, size_t len) {
// If no HOST is connected, we can exit this early.
if (usb_cdc_connected == 0) {
return;
}
while (len) { while (len) {
size_t l = len; size_t l = len;
if (l > CONFIG_USB_CDC_TX_BUFSIZE) { if (l > CONFIG_USB_CDC_TX_BUFSIZE) {