From d069ea1421eace1768157e76c44164262ed9a1e6 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Wed, 25 Aug 2021 10:41:07 +0200 Subject: [PATCH 1/2] vendor: Add tx callback Other drivers already have notification about data sent. It allows batter control in application on vendor protocol level. --- src/class/vendor/vendor_device.c | 1 + src/class/vendor/vendor_device.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 8a4ca1d2e..02a4220be 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -247,6 +247,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint } else if ( ep_addr == p_itf->ep_in ) { + if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, xferred_bytes); // Send complete, try to send more if possible maybe_transmit(p_itf); } diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index d71c2a3e9..75cb77f5b 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -71,6 +71,8 @@ static inline uint32_t tud_vendor_write_available (void); // Invoked when received new data TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t itf); +// Invoked when last rx transfer finished +TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); //--------------------------------------------------------------------+ // Inline Functions From 4ca22156845162b69410a47a2b43e03ac552b9f3 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Wed, 25 Aug 2021 10:57:35 +0200 Subject: [PATCH 2/2] vendor: Add tx flush functionality So far tud_vendor_n_write() always flushed data. It requires to have whole vendor packed constructed before in one buffer. With this change data do get flushed when endpoint size is filled on write, when there is no enough data to fill endpoint data is not sent and subsequent calls to write functions can add more bytes. Vendor code needs to call tud_vendor_n_flush() when packet is ready to be sent. --- src/class/vendor/vendor_device.c | 16 +++++++++++++--- src/class/vendor/vendor_device.h | 7 +++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 02a4220be..586822f39 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -113,7 +113,7 @@ void tud_vendor_n_read_flush (uint8_t itf) //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ -static bool maybe_transmit(vendord_interface_t* p_itf) +static uint16_t maybe_transmit(vendord_interface_t* p_itf) { // skip if previous transfer not complete TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, p_itf->ep_in) ); @@ -123,14 +123,24 @@ static bool maybe_transmit(vendord_interface_t* p_itf) { TU_ASSERT( usbd_edpt_xfer(TUD_OPT_RHPORT, p_itf->ep_in, p_itf->epin_buf, count) ); } - return true; + return count; } uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) { vendord_interface_t* p_itf = &_vendord_itf[itf]; uint16_t ret = tu_fifo_write_n(&p_itf->tx_ff, buffer, bufsize); - maybe_transmit(p_itf); + if (tu_fifo_count(&p_itf->tx_ff) >= CFG_TUD_VENDOR_EPSIZE) { + maybe_transmit(p_itf); + } + return ret; +} + +uint32_t tud_vendor_n_flush (uint8_t itf) +{ + vendord_interface_t* p_itf = &_vendord_itf[itf]; + uint32_t ret = maybe_transmit(p_itf); + return ret; } diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 75cb77f5b..4a873e5fc 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -52,6 +52,7 @@ uint32_t tud_vendor_n_write_available (uint8_t itf); static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); +uint32_t tud_vendor_n_flush (uint8_t itf); //--------------------------------------------------------------------+ // Application API (Single Port) @@ -64,6 +65,7 @@ static inline void tud_vendor_read_flush (void); static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize); static inline uint32_t tud_vendor_write_str (char const* str); static inline uint32_t tud_vendor_write_available (void); +static inline uint32_t tud_vendor_flush (void); //--------------------------------------------------------------------+ // Application Callback API (weak is optional) @@ -123,6 +125,11 @@ static inline uint32_t tud_vendor_write_available (void) return tud_vendor_n_write_available(0); } +static inline uint32_t tud_vendor_flush (void) +{ + return tud_vendor_n_flush(0); +} + //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+