summaryrefslogtreecommitdiff
path: root/src/class
diff options
context:
space:
mode:
Diffstat (limited to 'src/class')
-rw-r--r--src/class/cdc/cdc_device.c29
-rw-r--r--src/class/cdc/cdc_device.h9
2 files changed, 32 insertions, 6 deletions
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c
index 2933dcd3d..58f485a5d 100644
--- a/src/class/cdc/cdc_device.c
+++ b/src/class/cdc/cdc_device.c
@@ -178,6 +178,9 @@ uint32_t tud_cdc_n_write_flush (uint8_t itf)
{
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
+ // Skip if usb is not ready yet
+ TU_VERIFY( tud_ready(), 0 );
+
// No data to send
if ( !tu_fifo_count(&p_cdc->tx_ff) ) return 0;
@@ -189,7 +192,7 @@ uint32_t tud_cdc_n_write_flush (uint8_t itf)
// Pull data from FIFO
uint16_t const count = tu_fifo_read_n(&p_cdc->tx_ff, p_cdc->epin_buf, sizeof(p_cdc->epin_buf));
- if ( count && tud_cdc_n_connected(itf) )
+ if ( count )
{
TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 );
return count;
@@ -207,6 +210,10 @@ uint32_t tud_cdc_n_write_available (uint8_t itf)
return tu_fifo_remaining(&_cdcd_itf[itf].tx_ff);
}
+bool tud_cdc_n_write_clear (uint8_t itf)
+{
+ return tu_fifo_clear(&_cdcd_itf[itf].tx_ff);
+}
//--------------------------------------------------------------------+
// USBD Driver API
@@ -227,9 +234,13 @@ void cdcd_init(void)
p_cdc->line_coding.parity = 0;
p_cdc->line_coding.data_bits = 8;
- // config fifo
+ // Config RX fifo
tu_fifo_config(&p_cdc->rx_ff, p_cdc->rx_ff_buf, TU_ARRAY_SIZE(p_cdc->rx_ff_buf), 1, false);
- tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, false);
+
+ // Config TX fifo as overwritable at initialization and will be changed to non-overwritable
+ // if terminal supports DTR bit. Without DTR we do not know if data is actually polled by terminal.
+ // In this way, the most current data is prioritized.
+ tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true);
#if CFG_FIFO_MUTEX
tu_fifo_config_mutex(&p_cdc->rx_ff, osal_mutex_create(&p_cdc->rx_ff_mutex));
@@ -244,9 +255,12 @@ void cdcd_reset(uint8_t rhport)
for(uint8_t i=0; i<CFG_TUD_CDC; i++)
{
- tu_memclr(&_cdcd_itf[i], ITF_MEM_RESET_SIZE);
- tu_fifo_clear(&_cdcd_itf[i].rx_ff);
- tu_fifo_clear(&_cdcd_itf[i].tx_ff);
+ cdcd_interface_t* p_cdc = &_cdcd_itf[i];
+
+ tu_memclr(p_cdc, ITF_MEM_RESET_SIZE);
+ tu_fifo_clear(&p_cdc->rx_ff);
+ tu_fifo_clear(&p_cdc->tx_ff);
+ tu_fifo_set_overwritable(&p_cdc->tx_ff, true);
}
}
@@ -372,6 +386,9 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
bool const rts = tu_bit_test(request->wValue, 1);
p_cdc->line_state = (uint8_t) request->wValue;
+
+ // Disable fifo overwriting if DTR bit is set
+ tu_fifo_set_overwritable(&p_cdc->tx_ff, !dtr);
TU_LOG2(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts);
diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h
index 3e68e2a88..62dcd3c0a 100644
--- a/src/class/cdc/cdc_device.h
+++ b/src/class/cdc/cdc_device.h
@@ -102,6 +102,9 @@ uint32_t tud_cdc_n_write_flush (uint8_t itf);
// Return the number of bytes (characters) available for writing to TX FIFO buffer in a single n_write operation.
uint32_t tud_cdc_n_write_available (uint8_t itf);
+// Clear the transmit FIFO
+bool tud_cdc_n_write_clear (uint8_t itf);
+
//--------------------------------------------------------------------+
// Application API (Single Port)
//--------------------------------------------------------------------+
@@ -121,6 +124,7 @@ static inline uint32_t tud_cdc_write (void const* buffer, uint32_t buf
static inline uint32_t tud_cdc_write_str (char const* str);
static inline uint32_t tud_cdc_write_flush (void);
static inline uint32_t tud_cdc_write_available (void);
+static inline bool tud_cdc_write_clear (void);
//--------------------------------------------------------------------+
// Application Callback API (weak is optional)
@@ -230,6 +234,11 @@ static inline uint32_t tud_cdc_write_available(void)
return tud_cdc_n_write_available(0);
}
+static inline bool tud_cdc_write_clear(void)
+{
+ return tud_cdc_n_write_clear(0);
+}
+
/** @} */
/** @} */