From 581d43b7742628907e5a77115350e9eadd59092a Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 22 Oct 2020 11:54:38 +1100 Subject: [PATCH] stm32/usbd_cdc_interface: Check and handle CDC TX wrap-overflow. If the device is not connected over USB CDC to a host then all output to the CDC (eg initial boot messages) is written to the CDC TX buffer with wrapping, so that the most recent data is retained when the USB CDC is eventually connected (eg so the REPL banner is displayed upon connection). This commit fixes a bug in this behaviour, which was likely introduced in e4fcd216e02eef0b389c84ecd67be3114aac0a5d, where the initial data in the CDC TX buffer is repeated multiple times on first connection of the device to the host. Signed-off-by: Damien George --- ports/stm32/usbd_cdc_interface.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ports/stm32/usbd_cdc_interface.c b/ports/stm32/usbd_cdc_interface.c index 7a09128527..a8261a958a 100644 --- a/ports/stm32/usbd_cdc_interface.c +++ b/ports/stm32/usbd_cdc_interface.c @@ -196,9 +196,13 @@ static uint16_t usbd_cdc_tx_send_length(usbd_cdc_itf_t *cdc) { return MIN(usbd_cdc_tx_buffer_size(cdc), to_end); } -static void usbd_cdc_tx_buffer_put(usbd_cdc_itf_t *cdc, uint8_t data) { +static void usbd_cdc_tx_buffer_put(usbd_cdc_itf_t *cdc, uint8_t data, bool check_overflow) { cdc->tx_buf[usbd_cdc_tx_buffer_mask(cdc->tx_buf_ptr_in)] = data; cdc->tx_buf_ptr_in++; + if (check_overflow && usbd_cdc_tx_buffer_size(cdc) > USBD_CDC_TX_DATA_SIZE) { + cdc->tx_buf_ptr_out++; + cdc->tx_buf_ptr_out_next = cdc->tx_buf_ptr_out; + } } static uint8_t *usbd_cdc_tx_buffer_getp(usbd_cdc_itf_t *cdc, uint16_t len) { @@ -353,7 +357,7 @@ int usbd_cdc_tx(usbd_cdc_itf_t *cdc, const uint8_t *buf, uint32_t len, uint32_t } // Write data to device buffer - usbd_cdc_tx_buffer_put(cdc, buf[i]); + usbd_cdc_tx_buffer_put(cdc, buf[i], false); } usbd_cdc_try_tx(cdc); @@ -386,7 +390,7 @@ void usbd_cdc_tx_always(usbd_cdc_itf_t *cdc, const uint8_t *buf, uint32_t len) { } } - usbd_cdc_tx_buffer_put(cdc, buf[i]); + usbd_cdc_tx_buffer_put(cdc, buf[i], true); } usbd_cdc_try_tx(cdc); }