usbd: device_next: cdc: add option to enable short packet terminate
For usbser.sys driver, which is the default USB host driver for CDC devices in windows, it is expected that USB device always indicate completion of transmission by short packet. In case where the last packet length is multiple of max packet size of the BULK IN endpoint, the USB device shall indicate completion of transmission by sending a zero length packet. This commit adds the sending of the short packet termination mentioned above, ensuring condition of short packet terminate is fulfilled. Signed-off-by: Chew Zeh Yang <zeon.chew@ambiq.com>
This commit is contained in:
parent
76e1e1b804
commit
d770a4c584
@ -99,6 +99,15 @@ struct cdc_acm_uart_data {
|
||||
bool line_state_rts;
|
||||
/* UART actual DTR state */
|
||||
bool line_state_dtr;
|
||||
/* When flow_ctrl is set, poll out is blocked when the buffer is full,
|
||||
* roughly emulating flow control.
|
||||
*/
|
||||
bool flow_ctrl;
|
||||
/* Used to enqueue a ZLP transfer when the previous IN transfer length
|
||||
* was a multiple of the endpoint MPS and no more data is added to
|
||||
* the TX FIFO during the user callback execution.
|
||||
*/
|
||||
bool zlp_needed;
|
||||
/* UART API IRQ callback */
|
||||
uart_irq_callback_user_data_t cb;
|
||||
/* UART API user callback data */
|
||||
@ -107,10 +116,6 @@ struct cdc_acm_uart_data {
|
||||
struct k_work irq_cb_work;
|
||||
struct cdc_acm_uart_fifo rx_fifo;
|
||||
struct cdc_acm_uart_fifo tx_fifo;
|
||||
/* When flow_ctrl is set, poll out is blocked when the buffer is full,
|
||||
* roughly emulating flow control.
|
||||
*/
|
||||
bool flow_ctrl;
|
||||
/* USBD CDC ACM TX fifo work */
|
||||
struct k_work_delayable tx_fifo_work;
|
||||
/* USBD CDC ACM RX fifo work */
|
||||
@ -574,6 +579,8 @@ static void cdc_acm_tx_fifo_handler(struct k_work *work)
|
||||
len = ring_buf_get(data->tx_fifo.rb, buf->data, buf->size);
|
||||
net_buf_add(buf, len);
|
||||
|
||||
data->zlp_needed = len != 0 && len % cdc_acm_get_bulk_mps(c_data) == 0;
|
||||
|
||||
ret = usbd_ep_enqueue(c_data, buf);
|
||||
if (ret) {
|
||||
LOG_ERR("Failed to enqueue");
|
||||
@ -844,9 +851,12 @@ static void cdc_acm_irq_cb_handler(struct k_work *work)
|
||||
cdc_acm_work_submit(&data->rx_fifo_work);
|
||||
}
|
||||
|
||||
if (data->tx_fifo.altered) {
|
||||
LOG_DBG("tx fifo altered, submit work");
|
||||
if (!atomic_test_bit(&data->state, CDC_ACM_TX_FIFO_BUSY)) {
|
||||
if (!atomic_test_bit(&data->state, CDC_ACM_TX_FIFO_BUSY)) {
|
||||
if (data->tx_fifo.altered) {
|
||||
LOG_DBG("tx fifo altered, submit work");
|
||||
cdc_acm_work_schedule(&data->tx_fifo_work, K_NO_WAIT);
|
||||
} else if (data->zlp_needed) {
|
||||
LOG_DBG("zlp needed, submit work");
|
||||
cdc_acm_work_schedule(&data->tx_fifo_work, K_NO_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user