From bbeae09259707ba6b79db55dda2fd89b9e99f14f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Sep 2024 17:45:03 +0700 Subject: [PATCH] update vendor device to use edpt stream which also support non-buffereed (no fifo) mode --- src/class/vendor/vendor_device.c | 174 +++++++++++-------------------- src/class/vendor/vendor_device.h | 125 +++++++++------------- 2 files changed, 107 insertions(+), 192 deletions(-) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index d23530235..5d33d2e60 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -38,8 +38,7 @@ //--------------------------------------------------------------------+ #define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -typedef struct -{ +typedef struct { uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; @@ -49,19 +48,19 @@ typedef struct CFG_TUD_MEM_ALIGN uint8_t epout_buf[CFG_TUD_VENDOR_EPSIZE]; CFG_TUD_MEM_ALIGN uint8_t epin_buf[CFG_TUD_VENDOR_EPSIZE]; -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 struct { tu_edpt_stream_t stream; + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 uint8_t ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; + #endif }tx; -#endif -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 struct { tu_edpt_stream_t stream; + #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 uint8_t ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; + #endif } rx; -#endif } vendord_interface_t; @@ -69,6 +68,10 @@ CFG_TUD_MEM_SECTION static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; #define ITF_MEM_RESET_SIZE offsetof(vendord_interface_t, ep_out) + sizeof(((vendord_interface_t *)0)->ep_out) +//-------------------------------------------------------------------- +// Application API +//-------------------------------------------------------------------- + bool tud_vendor_n_mounted (uint8_t itf) { return _vendord_itf[itf].ep_in && _vendord_itf[itf].ep_out; } @@ -76,91 +79,63 @@ bool tud_vendor_n_mounted (uint8_t itf) { //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 -// static void _prep_out_transaction (vendord_interface_t* p_itf) -// { -// uint8_t const rhport = 0; -// -// // claim endpoint -// TU_VERIFY(usbd_edpt_claim(rhport, p_itf->ep_out), ); -// -// // Prepare for incoming data but only allow what we can store in the ring buffer. -// uint16_t max_read = tu_fifo_remaining(&p_itf->rx_ff); -// if ( max_read >= CFG_TUD_VENDOR_EPSIZE ) -// { -// usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); -// } -// else -// { -// // Release endpoint since we don't make any transfer -// usbd_edpt_release(rhport, p_itf->ep_out); -// } -// } - uint32_t tud_vendor_n_available (uint8_t itf) { TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; + return tu_edpt_stream_read_available(&p_itf->rx.stream); } bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) { TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; + return tu_edpt_stream_peek(&p_itf->rx.stream, u8); } uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - return tu_edpt_stream_read(&p_itf->rx.stream, buffer, bufsize); + uint8_t const rhport = 0; + + return tu_edpt_stream_read(rhport, &p_itf->rx.stream, buffer, bufsize); } void tud_vendor_n_read_flush (uint8_t itf) { TU_VERIFY(itf < CFG_TUD_VENDOR, ); vendord_interface_t* p_itf = &_vendord_itf[itf]; + uint8_t const rhport = 0; tu_edpt_stream_clear(&p_itf->rx.stream); - tu_edpt_stream_read_xfer(&p_itf->rx.stream); + tu_edpt_stream_read_xfer(rhport, &p_itf->rx.stream); } -#endif //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) { -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - return tu_edpt_stream_write(&p_itf->tx.stream, buffer, (uint16_t) bufsize); -#else uint8_t const rhport = 0; - vendord_interface_t* p_itf = &_vendord_itf[itf]; - // claim endpoint - TU_VERIFY(usbd_edpt_claim(rhport, p_itf->ep_in)); - - // prepare data - TU_VERIFY(0 == tu_memcpy_s(p_itf->epin_buf, CFG_TUD_VENDOR_EPSIZE, buffer, (uint16_t) bufsize)); - - TU_ASSERT(usbd_edpt_xfer(rhport, p_itf->ep_in, p_itf->epin_buf, (uint16_t) bufsize)); - - return bufsize; -#endif + return tu_edpt_stream_write(rhport, &p_itf->tx.stream, buffer, (uint16_t) bufsize); } -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 uint32_t tud_vendor_n_write_flush (uint8_t itf) { TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - return tu_edpt_stream_write_xfer(&p_itf->tx.stream); + uint8_t const rhport = 0; + + return tu_edpt_stream_write_xfer(rhport, &p_itf->tx.stream); } uint32_t tud_vendor_n_write_available (uint8_t itf) { TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - return tu_edpt_stream_write_available(&p_itf->tx.stream); + uint8_t const rhport = 0; + + return tu_edpt_stream_write_available(rhport, &p_itf->tx.stream); } -#endif //--------------------------------------------------------------------+ // USBD Driver API @@ -171,46 +146,36 @@ void vendord_init(void) { for(uint8_t i=0; i 0 - tu_edpt_stream_init(&p_itf->rx.stream, false, false, false, - p_itf->rx.ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, - p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); -#endif + uint8_t* rx_ff_buf = + #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 + p_itf->rx.ff_buf; + #else + NULL; + #endif + + tu_edpt_stream_init(&p_itf->rx.stream, false, false, false, + rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, + p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); + + uint8_t* tx_ff_buf = + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + p_itf->tx.ff_buf; + #else + NULL; + #endif -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 tu_edpt_stream_init(&p_itf->tx.stream, false, true, false, - p_itf->tx.ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, + tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, p_itf->epin_buf, CFG_TUD_VENDOR_EPSIZE); -#endif } } bool vendord_deinit(void) { -#if OSAL_MUTEX_REQUIRED - #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 for(uint8_t i=0; irx_ff.mutex_rd; - - if (mutex_rd) { - osal_mutex_delete(mutex_rd); - tu_fifo_config_mutex(&p_itf->rx_ff, NULL, NULL); - } + tu_edpt_stream_deinit(&p_itf->rx.stream); + tu_edpt_stream_deinit(&p_itf->tx.stream); } - #endif - #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - for(uint8_t i=0; itx_ff.mutex_wr; - - if (mutex_wr) { - osal_mutex_delete(mutex_wr); - tu_fifo_config_mutex(&p_itf->tx_ff, NULL, NULL); - } - } - #endif -#endif return true; } @@ -219,14 +184,9 @@ void vendord_reset(uint8_t rhport) { for(uint8_t i=0; i 0 tu_edpt_stream_clear(&p_itf->rx.stream); -#endif -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 tu_edpt_stream_clear(&p_itf->tx.stream); -#endif } } @@ -262,23 +222,12 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { p_vendor->ep_in = desc_ep->bEndpointAddress; - - #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - tu_edpt_stream_open(&p_vendor->tx.stream, rhport, desc_ep); + tu_edpt_stream_open(&p_vendor->tx.stream, desc_ep); tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf)); - #endif } else { p_vendor->ep_out = desc_ep->bEndpointAddress; - - #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - tu_edpt_stream_open(&p_vendor->rx.stream, rhport, desc_ep); - TU_ASSERT(tu_edpt_stream_read_xfer(&p_vendor->rx.stream) > 0, 0); // prepare for incoming data - #else - if ( !usbd_edpt_xfer(rhport, p_vendor->ep_out, p_vendor->epout_buf, CFG_TUD_VENDOR_EPSIZE) ) { - TU_LOG_FAILED(); - TU_BREAKPOINT(); - } - #endif + tu_edpt_stream_open(&p_vendor->rx.stream, desc_ep); + TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_vendor->rx.stream) > 0, 0); // prepare for incoming data } p_desc = tu_desc_next(p_desc); @@ -288,44 +237,39 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui } bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) rhport; (void) result; uint8_t itf = 0; vendord_interface_t* p_itf = _vendord_itf; for ( ; ; itf++, p_itf++) { - if (itf >= TU_ARRAY_SIZE(_vendord_itf)) return false; - if ( ( ep_addr == p_itf->ep_out ) || ( ep_addr == p_itf->ep_in ) ) break; + if (itf >= CFG_TUD_VENDOR) return false; + if ((ep_addr == p_itf->rx.stream.ep_addr) || (ep_addr == p_itf->tx.stream.ep_addr)) break; } - if ( ep_addr == p_itf->ep_out ) { -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - // Receive new data, put it into stream's fifo + if ( ep_addr == p_itf->rx.stream.ep_addr ) { + // Received new data: put into stream's fifo tu_edpt_stream_read_xfer_complete(&p_itf->rx.stream, xferred_bytes); -#endif // Invoked callback if any if (tud_vendor_rx_cb) { tud_vendor_rx_cb(itf, p_itf->epout_buf, (uint16_t) xferred_bytes); } -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - tu_edpt_stream_read_xfer(&p_itf->rx.stream); -#else - TU_ASSERT(usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE)); -#endif - } else if ( ep_addr == p_itf->ep_in ) { + tu_edpt_stream_read_xfer(rhport, &p_itf->rx.stream); + } else if ( ep_addr == p_itf->tx.stream.ep_addr ) { + // Send complete if (tud_vendor_tx_cb) { tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); } -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - // Send complete, try to send more if possible - if ( 0 == tu_edpt_stream_write_xfer(&p_itf->tx.stream) ) { + + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + // try to send more if possible + if ( 0 == tu_edpt_stream_write_xfer(rhport, &p_itf->tx.stream) ) { // If there is no data left, a ZLP should be sent if xferred_bytes is multiple of EP Packet size and not zero - tu_edpt_stream_write_zlp_if_needed(&p_itf->tx.stream, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(rhport, &p_itf->tx.stream, xferred_bytes); } -#endif + #endif } return true; diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 4a0cc3151..149ae2d56 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -33,12 +33,12 @@ #define CFG_TUD_VENDOR_EPSIZE 64 #endif -/* RX FIFO can be disabled by setting this value to 0, related API will also be disabled */ +// RX FIFO can be disabled by setting this value to 0 #ifndef CFG_TUD_VENDOR_RX_BUFSIZE #define CFG_TUD_VENDOR_RX_BUFSIZE 64 #endif -/* TX FIFO can be disabled by setting this value to 0, related API will also be disabled */ +// TX FIFO can be disabled by setting this value to 0 #ifndef CFG_TUD_VENDOR_TX_BUFSIZE #define CFG_TUD_VENDOR_TX_BUFSIZE 64 #endif @@ -48,48 +48,72 @@ #endif //--------------------------------------------------------------------+ -// Application API (Multiple Interfaces) +// Application API (Multiple Interfaces) i.e CFG_TUD_VENDOR > 1 //--------------------------------------------------------------------+ bool tud_vendor_n_mounted (uint8_t itf); - -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 uint32_t tud_vendor_n_available (uint8_t itf); uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize); bool tud_vendor_n_peek (uint8_t itf, uint8_t* ui8); void tud_vendor_n_read_flush (uint8_t itf); -#endif uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 uint32_t tud_vendor_n_write_flush (uint8_t itf); uint32_t tud_vendor_n_write_available (uint8_t itf); -#endif -static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); + // backward compatible #define tud_vendor_n_flush(itf) tud_vendor_n_write_flush(itf) -#endif //--------------------------------------------------------------------+ -// Application API (Single Port) +// Application API (Single Port) i.e CFG_TUD_VENDOR = 1 //--------------------------------------------------------------------+ -static inline bool tud_vendor_mounted (void); -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 -static inline uint32_t tud_vendor_available (void); -static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize); -static inline bool tud_vendor_peek (uint8_t* ui8); -static inline void tud_vendor_read_flush (void); -#endif -static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize); -static inline uint32_t tud_vendor_write_str (char const* str); + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_n_write_str(uint8_t itf, char const* str) { + return tud_vendor_n_write(itf, str, strlen(str)); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_mounted(void) { + return tud_vendor_n_mounted(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_available(void) { + return tud_vendor_n_available(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_read(void* buffer, uint32_t bufsize) { + return tud_vendor_n_read(0, buffer, bufsize); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_peek(uint8_t* ui8) { + return tud_vendor_n_peek(0, ui8); +} + +TU_ATTR_ALWAYS_INLINE static inline void tud_vendor_read_flush(void) { + tud_vendor_n_read_flush(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write(void const* buffer, uint32_t bufsize) { + return tud_vendor_n_write(0, buffer, bufsize); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_str(char const* str) { + return tud_vendor_n_write_str(0, str); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_flush(void) { + return tud_vendor_n_write_flush(0); +} + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 -static inline uint32_t tud_vendor_write_available (void); -static inline uint32_t tud_vendor_write_flush (void); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_available(void) { + return tud_vendor_n_write_available(0); +} +#endif // backward compatible #define tud_vendor_flush() tud_vendor_write_flush() -#endif + //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ @@ -103,59 +127,6 @@ TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); // Inline Functions //--------------------------------------------------------------------+ -static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str) -{ - return tud_vendor_n_write(itf, str, strlen(str)); -} - -static inline bool tud_vendor_mounted (void) -{ - return tud_vendor_n_mounted(0); -} - -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 -static inline uint32_t tud_vendor_available (void) -{ - return tud_vendor_n_available(0); -} - -static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize) -{ - return tud_vendor_n_read(0, buffer, bufsize); -} - -static inline bool tud_vendor_peek (uint8_t* ui8) -{ - return tud_vendor_n_peek(0, ui8); -} - -static inline void tud_vendor_read_flush(void) -{ - tud_vendor_n_read_flush(0); -} -#endif - -static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize) -{ - return tud_vendor_n_write(0, buffer, bufsize); -} - -static inline uint32_t tud_vendor_write_str (char const* str) -{ - return tud_vendor_n_write_str(0, str); -} - -#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 -static inline uint32_t tud_vendor_write_flush (void) -{ - return tud_vendor_n_write_flush(0); -} - -static inline uint32_t tud_vendor_write_available (void) -{ - return tud_vendor_n_write_available(0); -} -#endif //--------------------------------------------------------------------+ // Internal Class Driver API