mirror of
https://github.com/hathach/tinyusb.git
synced 2025-02-21 03:40:52 +00:00
Fix slow CDC OUT by NAKing
This NAKs CDC OUT packets when the ring buffer doesn't have enough space for it. This makes CDC OUT reliable rather than allowing overwriting into the ring buffer.
This commit is contained in:
parent
29b49199be
commit
909891325a
@ -87,6 +87,24 @@ typedef struct
|
||||
//--------------------------------------------------------------------+
|
||||
CFG_TUSB_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC] = { { 0 } };
|
||||
|
||||
bool pending_read_from_host;
|
||||
static void _prep_next_transaction(void) {
|
||||
uint8_t const itf = 0;
|
||||
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
|
||||
|
||||
// skip if previous transfer not complete
|
||||
if (pending_read_from_host) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare for incoming data but only allow what we can store in the ring buffer.
|
||||
uint16_t max_read = tu_fifo_remaining(&p_cdc->rx_ff);
|
||||
if (max_read >= CFG_TUD_CDC_EPSIZE) {
|
||||
dcd_edpt_xfer(TUD_OPT_RHPORT, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE);
|
||||
pending_read_from_host = true;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// APPLICATION API
|
||||
//--------------------------------------------------------------------+
|
||||
@ -123,12 +141,19 @@ uint32_t tud_cdc_n_available(uint8_t itf)
|
||||
char tud_cdc_n_read_char(uint8_t itf)
|
||||
{
|
||||
char ch;
|
||||
return tu_fifo_read(&_cdcd_itf[itf].rx_ff, &ch) ? ch : (-1);
|
||||
if (!tu_fifo_read(&_cdcd_itf[itf].rx_ff, &ch)) {
|
||||
ch = -1;
|
||||
}
|
||||
|
||||
_prep_next_transaction();
|
||||
return ch;
|
||||
}
|
||||
|
||||
uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize)
|
||||
{
|
||||
return tu_fifo_read_n(&_cdcd_itf[itf].rx_ff, buffer, bufsize);
|
||||
uint32_t num_read = tu_fifo_read_n(&_cdcd_itf[itf].rx_ff, buffer, bufsize);
|
||||
_prep_next_transaction();
|
||||
return num_read;
|
||||
}
|
||||
|
||||
char tud_cdc_n_peek(uint8_t itf, int pos)
|
||||
@ -140,6 +165,7 @@ char tud_cdc_n_peek(uint8_t itf, int pos)
|
||||
void tud_cdc_n_read_flush (uint8_t itf)
|
||||
{
|
||||
tu_fifo_clear(&_cdcd_itf[itf].rx_ff);
|
||||
_prep_next_transaction();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
@ -207,7 +233,7 @@ void cdcd_init(void)
|
||||
p_cdc->line_coding.data_bits = 8;
|
||||
|
||||
// config fifo
|
||||
tu_fifo_config(&p_cdc->rx_ff, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, 1, true);
|
||||
tu_fifo_config(&p_cdc->rx_ff, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, 1, false);
|
||||
tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, 1, false);
|
||||
|
||||
#if CFG_FIFO_MUTEX
|
||||
@ -290,7 +316,8 @@ bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t
|
||||
}
|
||||
|
||||
// Prepare for incoming data
|
||||
TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE) );
|
||||
pending_read_from_host = false;
|
||||
_prep_next_transaction();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -383,8 +410,8 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
|
||||
// invoke receive callback (if there is still data)
|
||||
if (tud_cdc_rx_cb && tu_fifo_count(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf);
|
||||
|
||||
// prepare for incoming data
|
||||
TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE) );
|
||||
pending_read_from_host = false;
|
||||
_prep_next_transaction();
|
||||
}
|
||||
|
||||
// nothing to do with in and notif endpoint
|
||||
|
Loading…
x
Reference in New Issue
Block a user