Hi, I'm working on an application that transmits data via USB CDC/ACM class.
I'm trying to improve the robustness of the application, and I realised that if the USB cable is unplugged during data transmission, my next transmission gets corrupted.
In the cddc_acm implementation, a large ringbuffer (1KB) is used to store the data that is then sent to the usb endpoint. I suspect some data from the previous transmission is still stored in the buffer, but it seems there is no way to reset it.
I'm sure there is an alternative solution to avoid this issue, I would appreciate some pointers :)
PS: Here is the code that I'm currently using in the interrupt callback to transmit the data. The additional semaphore is used for synchronization purposes by the application.
static void interrupt_handler(const struct device *dev, void *user_data){
struct context *tx = (struct context*)user_data;
if (uart_irq_update(dev) && uart_irq_is_pending(dev)) {
if(uart_irq_tx_ready(dev) > 0 && tx->len > 0){
LOG_DBG("ISR TX ready, len %d", tx->len);
int sent = uart_fifo_fill(dev, tx->data, tx->len);
if(sent > 0){
tx->data = tx->data+sent;
__ASSERT_NO_MSG(tx->len >= sent);
tx->len -= sent;
}else{
LOG_ERR("Failed to send data");
}
if(tx->len <= 0){
LOG_DBG("ISR TX done");
uart_irq_tx_disable(dev);
k_sem_give(usb_iface->tx_sem);
}
}
if(uart_irq_rx_ready(dev) == 1){
static uint8_t buf[64];
int read;
do{
read = uart_fifo_read(dev, buf, sizeof(buf));
__ASSERT_NO_MSG(read >= 0);
uint32_t bytes_written;
int ret = k_pipe_put(usb_iface->rx_pipe, buf, read, &bytes_written, read, K_NO_WAIT);
if(ret < 0){
LOG_ERR("Dropping data");
break;
}
}while(read > 0);
}
}
}