From 794ee9704fdcb73c2007c8a35014f2f33f72d1b5 Mon Sep 17 00:00:00 2001 From: Chris Liang Date: Fri, 1 Dec 2023 20:17:06 +0800 Subject: [PATCH 1/6] Update USBCDC.h to support ZLP --- drivers/usb/include/usb/USBCDC.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/include/usb/USBCDC.h b/drivers/usb/include/usb/USBCDC.h index 777b352ad00..8e75b567093 100644 --- a/drivers/usb/include/usb/USBCDC.h +++ b/drivers/usb/include/usb/USBCDC.h @@ -230,6 +230,7 @@ class USBCDC: public USBDevice { uint8_t _rx_buffer[CDC_MAX_PACKET_SIZE]; uint8_t *_rx_buf; uint32_t _rx_size; + bool _trans_zlp; }; /** @}*/ From 1cccc7e14db05e90831594e0f7235082aae1e64c Mon Sep 17 00:00:00 2001 From: Chris Liang Date: Fri, 1 Dec 2023 20:22:47 +0800 Subject: [PATCH 2/6] Update USBCDC.cpp to support ZLP --- drivers/usb/source/USBCDC.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/source/USBCDC.cpp b/drivers/usb/source/USBCDC.cpp index 9cf1ed04d9e..fb93b16c3a2 100644 --- a/drivers/usb/source/USBCDC.cpp +++ b/drivers/usb/source/USBCDC.cpp @@ -186,6 +186,7 @@ void USBCDC::_init() _rx_in_progress = false; _rx_buf = _rx_buffer; _rx_size = 0; + _trans_zlp = false; } void USBCDC::callback_reset() @@ -387,6 +388,9 @@ void USBCDC::send_nb(uint8_t *buffer, uint32_t size, uint32_t *actual, bool now) } _tx_size += write_size; *actual = write_size; + if((CDC_MAX_PACKET_SIZE == size) && (CDC_MAX_PACKET_SIZE == write_size)) { + _trans_zlp = true; + } if (now) { _send_isr_start(); } @@ -403,6 +407,11 @@ void USBCDC::_send_isr_start() if (USBDevice::write_start(_bulk_in, _tx_buffer, _tx_size)) { _tx_in_progress = true; } + } else if(!_tx_in_progress && _trans_zlp) { + if (USBDevice::write_start(_bulk_in, _tx_buffer, 0)) { + _tx_in_progress = true; + _trans_zlp = false; + } } } From e2aed1824c2c3deb9300a8cd6e60e8d8dbdabb44 Mon Sep 17 00:00:00 2001 From: Chris Liang Date: Fri, 1 Dec 2023 20:43:12 +0800 Subject: [PATCH 3/6] Update USBCDC.cpp to fulfill A style --- drivers/usb/source/USBCDC.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/source/USBCDC.cpp b/drivers/usb/source/USBCDC.cpp index fb93b16c3a2..b32730388b3 100644 --- a/drivers/usb/source/USBCDC.cpp +++ b/drivers/usb/source/USBCDC.cpp @@ -388,7 +388,7 @@ void USBCDC::send_nb(uint8_t *buffer, uint32_t size, uint32_t *actual, bool now) } _tx_size += write_size; *actual = write_size; - if((CDC_MAX_PACKET_SIZE == size) && (CDC_MAX_PACKET_SIZE == write_size)) { + if ((CDC_MAX_PACKET_SIZE == size) && (CDC_MAX_PACKET_SIZE == write_size)) { _trans_zlp = true; } if (now) { @@ -407,7 +407,7 @@ void USBCDC::_send_isr_start() if (USBDevice::write_start(_bulk_in, _tx_buffer, _tx_size)) { _tx_in_progress = true; } - } else if(!_tx_in_progress && _trans_zlp) { + } else if (!_tx_in_progress && _trans_zlp) { if (USBDevice::write_start(_bulk_in, _tx_buffer, 0)) { _tx_in_progress = true; _trans_zlp = false; From ca616c865acb59c6f6311952787f242831ced02f Mon Sep 17 00:00:00 2001 From: Chris Liang Date: Tue, 5 Dec 2023 19:31:17 +0800 Subject: [PATCH 4/6] Move "send ZLP write start" after last alignment packet sent --- drivers/usb/source/USBCDC.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/usb/source/USBCDC.cpp b/drivers/usb/source/USBCDC.cpp index b32730388b3..3b0f8021f34 100644 --- a/drivers/usb/source/USBCDC.cpp +++ b/drivers/usb/source/USBCDC.cpp @@ -391,6 +391,7 @@ void USBCDC::send_nb(uint8_t *buffer, uint32_t size, uint32_t *actual, bool now) if ((CDC_MAX_PACKET_SIZE == size) && (CDC_MAX_PACKET_SIZE == write_size)) { _trans_zlp = true; } + if (now) { _send_isr_start(); } @@ -407,11 +408,6 @@ void USBCDC::_send_isr_start() if (USBDevice::write_start(_bulk_in, _tx_buffer, _tx_size)) { _tx_in_progress = true; } - } else if (!_tx_in_progress && _trans_zlp) { - if (USBDevice::write_start(_bulk_in, _tx_buffer, 0)) { - _tx_in_progress = true; - _trans_zlp = false; - } } } @@ -423,6 +419,11 @@ void USBCDC::_send_isr() { assert_locked(); + /* Send ZLP write start after last alignment packet sent */ + if (_trans_zlp && USBDevice::write_start(_bulk_in, _tx_buffer, 0)) { + _trans_zlp = false; + } + write_finish(_bulk_in); _tx_buf = _tx_buffer; _tx_size = 0; From c30af6a7dfccccbe44d5e5e6c9bd4b9fcb03f031 Mon Sep 17 00:00:00 2001 From: Chris Liang Date: Wed, 6 Dec 2023 19:19:27 +0800 Subject: [PATCH 5/6] To judge send ZLP or not in USBCDC::AsyncWrite --- drivers/usb/source/USBCDC.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/usb/source/USBCDC.cpp b/drivers/usb/source/USBCDC.cpp index 3b0f8021f34..827e7536e5a 100644 --- a/drivers/usb/source/USBCDC.cpp +++ b/drivers/usb/source/USBCDC.cpp @@ -39,7 +39,7 @@ class USBCDC::AsyncWrite: public AsyncOp { AsyncWrite(USBCDC *serial, uint8_t *buf, uint32_t size): serial(serial), tx_buf(buf), tx_size(size), result(false) { - + need_zlp = (size % CDC_MAX_PACKET_SIZE == 0) ? true : false; } virtual ~AsyncWrite() @@ -59,6 +59,12 @@ class USBCDC::AsyncWrite: public AsyncOp { tx_size -= actual_size; tx_buf += actual_size; if (tx_size == 0) { + // For ZLP case, not ending yet and need one more time to invoke process to send zero packet. + if (need_zlp) { + need_zlp = false; + serial->_send_isr_start(); + return false; + } result = true; return true; } @@ -72,6 +78,7 @@ class USBCDC::AsyncWrite: public AsyncOp { uint8_t *tx_buf; uint32_t tx_size; bool result; + bool need_zlp; }; class USBCDC::AsyncRead: public AsyncOp { @@ -388,7 +395,9 @@ void USBCDC::send_nb(uint8_t *buffer, uint32_t size, uint32_t *actual, bool now) } _tx_size += write_size; *actual = write_size; - if ((CDC_MAX_PACKET_SIZE == size) && (CDC_MAX_PACKET_SIZE == write_size)) { + + /* Enable ZLP flag as while send_nb() zero size */ + if (size == 0) { _trans_zlp = true; } @@ -409,6 +418,14 @@ void USBCDC::_send_isr_start() _tx_in_progress = true; } } + + /* Send ZLP write start */ + if (!_tx_in_progress && _trans_zlp) { + if (USBDevice::write_start(_bulk_in, _tx_buffer, 0)) { + _tx_in_progress = true; + _trans_zlp = false; + } + } } /* @@ -419,11 +436,6 @@ void USBCDC::_send_isr() { assert_locked(); - /* Send ZLP write start after last alignment packet sent */ - if (_trans_zlp && USBDevice::write_start(_bulk_in, _tx_buffer, 0)) { - _trans_zlp = false; - } - write_finish(_bulk_in); _tx_buf = _tx_buffer; _tx_size = 0; From 126d767a59799ce12ca647d87d6019917f13e4c2 Mon Sep 17 00:00:00 2001 From: cyliang tw Date: Wed, 13 Dec 2023 13:53:27 +0800 Subject: [PATCH 6/6] Avoid USBCDC send_nb break the continuation use case --- drivers/usb/source/USBCDC.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/source/USBCDC.cpp b/drivers/usb/source/USBCDC.cpp index 827e7536e5a..c42bead6d51 100644 --- a/drivers/usb/source/USBCDC.cpp +++ b/drivers/usb/source/USBCDC.cpp @@ -391,7 +391,7 @@ void USBCDC::send_nb(uint8_t *buffer, uint32_t size, uint32_t *actual, bool now) uint32_t free = sizeof(_tx_buffer) - _tx_size; uint32_t write_size = free > size ? size : free; if (size > 0) { - memcpy(_tx_buf, buffer, write_size); + memcpy(_tx_buf + _tx_size, buffer, write_size); } _tx_size += write_size; *actual = write_size;