Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CDC without DTR being set #506

Merged
merged 16 commits into from
Nov 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/device/cdc_dual_ports/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ static void cdc_task(void)

for (itf = 0; itf < CFG_TUD_CDC; itf++)
{
// connected() check for DTR bit
// Most but not all terminal client set this when making connection
if ( tud_cdc_n_connected(itf) )
{
if ( tud_cdc_n_available(itf) )
Expand Down
8 changes: 6 additions & 2 deletions examples/device/cdc_msc/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ void tud_resume_cb(void)
//--------------------------------------------------------------------+
void cdc_task(void)
{
if ( tud_cdc_connected() )
// connected() check for DTR bit
// Most but not all terminal client set this when making connection
// if ( tud_cdc_connected() )
{
// connected and there are data available
if ( tud_cdc_available() )
Expand All @@ -131,12 +133,14 @@ void cdc_task(void)
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
{
(void) itf;
(void) rts;

// connected
if ( dtr && rts )
if ( dtr )
{
// print initial message when connected
tud_cdc_write_str("\r\nTinyUSB CDC MSC device example\r\n");
tud_cdc_write_flush();
}
}

Expand Down
10 changes: 7 additions & 3 deletions examples/device/cdc_msc_freertos/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,11 @@ void cdc_task(void* params)
// RTOS forever loop
while ( 1 )
{
if ( tud_cdc_connected() )
// connected() check for DTR bit
// Most but not all terminal client set this when making connection
// if ( tud_cdc_connected() )
{
// connected and there are data available
// There are data available
if ( tud_cdc_available() )
{
uint8_t buf[64];
Expand Down Expand Up @@ -198,12 +200,14 @@ void cdc_task(void* params)
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
{
(void) itf;
(void) rts;

// connected
if ( dtr && rts )
if ( dtr )
{
// print initial message when connected
tud_cdc_write_str("\r\nTinyUSB CDC MSC device with FreeRTOS example\r\n");
tud_cdc_write_flush();
}
}

Expand Down
29 changes: 23 additions & 6 deletions src/class/cdc/cdc_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 )
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right, we have to add a check whether usb is enumerated to prevent executing edpt_xfer(). I will do it in a follow up PR

{
TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 );
return count;
Expand All @@ -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
Expand All @@ -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);
duempel marked this conversation as resolved.
Show resolved Hide resolved

#if CFG_FIFO_MUTEX
tu_fifo_config_mutex(&p_cdc->rx_ff, osal_mutex_create(&p_cdc->rx_ff_mutex));
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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);

Expand Down
9 changes: 9 additions & 0 deletions src/class/cdc/cdc_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
//--------------------------------------------------------------------+
Expand All @@ -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)
Expand Down Expand Up @@ -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);
}

/** @} */
/** @} */

Expand Down
21 changes: 21 additions & 0 deletions src/common/tusb_fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,27 @@ bool tu_fifo_clear(tu_fifo_t *f)
return true;
}

/******************************************************************************/
/*!
@brief Change the fifo mode to overwritable or not overwritable

@param[in] f
Pointer to the FIFO buffer to manipulate
@param[in] overwritable
Overwritable mode the fifo is set to
*/
/******************************************************************************/
bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable)
{
tu_fifo_lock(f);

f->overwritable = overwritable;

tu_fifo_unlock(f);

return true;
}

/******************************************************************************/
/*!
@brief Advance write pointer - intended to be used in combination with DMA.
Expand Down
1 change: 1 addition & 0 deletions src/common/tusb_fifo.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ typedef struct
.non_used_index_space = 0xFFFF - 2*_depth-1, \
}

bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable);
bool tu_fifo_clear(tu_fifo_t *f);
bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable);

Expand Down