Skip to content

Commit

Permalink
usbd: device_next: cdc: add option to enable short packet terminate
Browse files Browse the repository at this point in the history
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 an option to usbd_cdc_acm to
enable the enforcement of zero length packet mentioned above, ensuring
that condition of short packet terminate is fulfilled.

Signed-off-by: Chew Zeh Yang <[email protected]>
  • Loading branch information
zeonchew committed Oct 3, 2024
1 parent 2815b6d commit c0d442e
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 0 deletions.
10 changes: 10 additions & 0 deletions subsys/usb/device_next/class/Kconfig.cdc_acm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ config USBD_CDC_ACM_STACK_SIZE
help
USB CDC ACM workqueue stack size.

config USBD_CDC_ACM_ENSURE_SHORT_PKT_FOR_LAST_TX_PKT
bool "USB CDC ACM transmission always end with short packet"
default n
help
If the length of CDC ACM TX payload to be sent to USB Host
is in multiple of max-packet-size of the BULK-IN endpoint,
a Zero-Length Packet will be sent followig the last packet
of the payload, to ensure short packet termination for the
BULK-IN endpoint.

module = USBD_CDC_ACM
module-str = usbd cdc_acm
default-count = 1
Expand Down
6 changes: 6 additions & 0 deletions subsys/usb/device_next/class/usbd_cdc_acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,12 @@ 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);

if (IS_ENABLED(CONFIG_USBD_CDC_ACM_ENSURE_SHORT_PKT_FOR_LAST_TX_PKT)) {
if (len != 0 && len % cdc_acm_get_bulk_mps(c_data) == 0) {
udc_ep_buf_set_zlp(buf);
}
}

ret = usbd_ep_enqueue(c_data, buf);
if (ret) {
LOG_ERR("Failed to enqueue");
Expand Down

0 comments on commit c0d442e

Please sign in to comment.