diff options
| author | Ha Thach <[email protected]> | 2025-11-27 23:52:51 +0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-11-27 23:52:51 +0700 |
| commit | 1618c58dc4ef82f30c51c6318046d8dccb524425 (patch) | |
| tree | e9f94209538f155544d3432496729c47f1350ef0 /src/class | |
| parent | 5ef55bfa30d6f8cf175b3d327f621c76aae7b138 (diff) | |
| parent | 6e9e9ce9d19d6aa30c69c6e6c82d09dde619f391 (diff) | |
Merge pull request #3373 from hathach/vendor-dedicated-hwfifo
update Vendor device to omit ep buffer for port with dedicated hwfifo
Diffstat (limited to 'src/class')
| -rw-r--r-- | src/class/cdc/cdc_device.c | 11 | ||||
| -rw-r--r-- | src/class/vendor/vendor_device.c | 254 | ||||
| -rw-r--r-- | src/class/vendor/vendor_device.h | 132 |
3 files changed, 243 insertions, 154 deletions
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 7ef8aa738..d7792afe4 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -266,9 +266,8 @@ void cdcd_init(void) { uint8_t *epout_buf = NULL; uint8_t *epin_buf = NULL; #else - cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[i]; - uint8_t *epout_buf = p_epbuf->epout; - uint8_t *epin_buf = p_epbuf->epin; + uint8_t *epout_buf = _cdcd_epbuf[i].epout; + uint8_t *epin_buf = _cdcd_epbuf[i].epin; #endif tu_edpt_stream_init(&p_cdc->stream.rx, false, false, false, p_cdc->stream.rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, @@ -516,11 +515,9 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ } // Data sent to host, we continue to fetch from tx fifo to send. - // Note: This will cause incorrect baudrate set in line coding. - // Though maybe the baudrate is not really important !!! + // Note: This will cause incorrect baudrate set in line coding. Though maybe the baudrate is not really important ! if (ep_addr == stream_tx->ep_addr) { - // invoke transmit callback to possibly refill tx fifo - tud_cdc_tx_complete_cb(itf); + tud_cdc_tx_complete_cb(itf); // invoke callback to possibly refill tx fifo if (0 == tu_edpt_stream_write_xfer(rhport, stream_tx)) { // If there is no data left, a ZLP should be sent if needed diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index c7903375d..62e183465 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -42,43 +42,51 @@ typedef struct { /*------------- From this point, data is not cleared by bus reset -------------*/ struct { - tu_edpt_stream_t stream; - #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - uint8_t ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; - #endif - } tx; + tu_edpt_stream_t tx; + tu_edpt_stream_t rx; - struct { - tu_edpt_stream_t stream; - #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - uint8_t ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; - #endif - } rx; + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + uint8_t tx_ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; + #endif + #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 + uint8_t rx_ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; + #endif + } stream; } vendord_interface_t; -#define ITF_MEM_RESET_SIZE (offsetof(vendord_interface_t, itf_num) + sizeof(((vendord_interface_t *)0)->itf_num)) +#define ITF_MEM_RESET_SIZE (offsetof(vendord_interface_t, itf_num) + sizeof(((vendord_interface_t *)0)->itf_num)) static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || CFG_TUD_VENDOR_RX_BUFSIZE == 0 typedef struct { + // Skip local EP buffer if dedicated hw FIFO is supported + #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || CFG_TUD_VENDOR_RX_BUFSIZE == 0 TUD_EPBUF_DEF(epout, CFG_TUD_VENDOR_EPSIZE); + #endif + + // Skip local EP buffer if dedicated hw FIFO is supported + #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 TUD_EPBUF_DEF(epin, CFG_TUD_VENDOR_EPSIZE); + #endif } vendord_epbuf_t; CFG_TUD_MEM_SECTION static vendord_epbuf_t _vendord_epbuf[CFG_TUD_VENDOR]; + #endif //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ -TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t itf, uint8_t const* buffer, uint16_t bufsize) { - (void) itf; - (void) buffer; - (void) bufsize; + +TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint32_t bufsize) { + (void)idx; + (void)buffer; + (void)bufsize; } -TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes) { - (void) itf; +TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t idx, uint32_t sent_bytes) { + (void)idx; (void) sent_bytes; } @@ -86,60 +94,79 @@ TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes) { // Application API //-------------------------------------------------------------------- -bool tud_vendor_n_mounted(uint8_t itf) { - TU_VERIFY(itf < CFG_TUD_VENDOR); - vendord_interface_t* p_itf = &_vendord_itf[itf]; - return p_itf->rx.stream.ep_addr || p_itf->tx.stream.ep_addr; +bool tud_vendor_n_mounted(uint8_t idx) { + TU_VERIFY(idx < CFG_TUD_VENDOR); + vendord_interface_t *p_itf = &_vendord_itf[idx]; + return p_itf->stream.rx.ep_addr || p_itf->stream.tx.ep_addr; } //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ -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); +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 +uint32_t tud_vendor_n_available(uint8_t idx) { + TU_VERIFY(idx < CFG_TUD_VENDOR, 0); + vendord_interface_t *p_itf = &_vendord_itf[idx]; + return tu_edpt_stream_read_available(&p_itf->stream.rx); } -bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) { - TU_VERIFY(itf < CFG_TUD_VENDOR); - vendord_interface_t* p_itf = &_vendord_itf[itf]; - return tu_edpt_stream_peek(&p_itf->rx.stream, u8); +bool tud_vendor_n_peek(uint8_t idx, uint8_t *u8) { + TU_VERIFY(idx < CFG_TUD_VENDOR); + vendord_interface_t *p_itf = &_vendord_itf[idx]; + return tu_edpt_stream_peek(&p_itf->stream.rx, 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->rhport, &p_itf->rx.stream, buffer, bufsize); +uint32_t tud_vendor_n_read(uint8_t idx, void *buffer, uint32_t bufsize) { + TU_VERIFY(idx < CFG_TUD_VENDOR, 0); + vendord_interface_t *p_itf = &_vendord_itf[idx]; + return tu_edpt_stream_read(p_itf->rhport, &p_itf->stream.rx, 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]; - tu_edpt_stream_clear(&p_itf->rx.stream); - tu_edpt_stream_read_xfer(p_itf->rhport, &p_itf->rx.stream); +uint32_t tud_vendor_n_read_discard(uint8_t idx, uint32_t count) { + TU_VERIFY(idx < CFG_TUD_VENDOR, 0); + vendord_interface_t *p_itf = &_vendord_itf[idx]; + return tu_edpt_stream_discard(&p_itf->stream.rx, count); } +void tud_vendor_n_read_flush(uint8_t idx) { + TU_VERIFY(idx < CFG_TUD_VENDOR, ); + vendord_interface_t *p_itf = &_vendord_itf[idx]; + tu_edpt_stream_clear(&p_itf->stream.rx); + tu_edpt_stream_read_xfer(p_itf->rhport, &p_itf->stream.rx); +} +#endif + +#if CFG_TUD_VENDOR_RX_MANUAL_XFER +bool tud_vendor_n_read_xfer(uint8_t idx) { + TU_VERIFY(idx < CFG_TUD_VENDOR); + vendord_interface_t *p_itf = &_vendord_itf[idx]; + return tu_edpt_stream_read_xfer(p_itf->rhport, &p_itf->stream.rx); +} +#endif + + //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ -uint32_t tud_vendor_n_write (uint8_t itf, const void* buffer, uint32_t bufsize) { - TU_VERIFY(itf < CFG_TUD_VENDOR, 0); - vendord_interface_t* p_itf = &_vendord_itf[itf]; - return tu_edpt_stream_write(p_itf->rhport, &p_itf->tx.stream, buffer, (uint16_t)bufsize); +uint32_t tud_vendor_n_write(uint8_t idx, const void *buffer, uint32_t bufsize) { + TU_VERIFY(idx < CFG_TUD_VENDOR, 0); + vendord_interface_t *p_itf = &_vendord_itf[idx]; + return tu_edpt_stream_write(p_itf->rhport, &p_itf->stream.tx, buffer, (uint16_t)bufsize); } -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->rhport, &p_itf->tx.stream); +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 +uint32_t tud_vendor_n_write_flush(uint8_t idx) { + TU_VERIFY(idx < CFG_TUD_VENDOR, 0); + vendord_interface_t *p_itf = &_vendord_itf[idx]; + return tu_edpt_stream_write_xfer(p_itf->rhport, &p_itf->stream.tx); } -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->rhport, &p_itf->tx.stream); +uint32_t tud_vendor_n_write_available(uint8_t idx) { + TU_VERIFY(idx < CFG_TUD_VENDOR, 0); + vendord_interface_t *p_itf = &_vendord_itf[idx]; + return tu_edpt_stream_write_available(p_itf->rhport, &p_itf->stream.tx); } +#endif //--------------------------------------------------------------------+ // USBD Driver API @@ -149,35 +176,45 @@ void vendord_init(void) { for(uint8_t i=0; i<CFG_TUD_VENDOR; i++) { vendord_interface_t* p_itf = &_vendord_itf[i]; - vendord_epbuf_t* p_epbuf = &_vendord_epbuf[i]; + + #if CFG_TUD_EDPT_DEDICATED_HWFIFO + #if CFG_TUD_VENDOR_RX_BUFSIZE == 0 // non-fifo rx still need ep buffer + uint8_t *epout_buf = _vendord_epbuf[i].epout; + #else + uint8_t *epout_buf = NULL; + #endif + + uint8_t *epin_buf = NULL; + #else + uint8_t *epout_buf = _vendord_epbuf[i].epout; + uint8_t *epin_buf = _vendord_epbuf[i].epin; + #endif #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - uint8_t *rx_ff_buf = p_itf->rx.ff_buf; + uint8_t *rx_ff_buf = p_itf->stream.rx_ff_buf; #else uint8_t *rx_ff_buf = NULL; #endif - tu_edpt_stream_init(&p_itf->rx.stream, false, false, false, - rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, - p_epbuf->epout, CFG_TUD_VENDOR_EPSIZE); + tu_edpt_stream_init(&p_itf->stream.rx, false, false, false, rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, epout_buf, + CFG_TUD_VENDOR_EPSIZE); #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 - uint8_t *tx_ff_buf = p_itf->tx.ff_buf; + uint8_t *tx_ff_buf = p_itf->stream.tx_ff_buf; #else - uint8_t* tx_ff_buf = NULL; + uint8_t *tx_ff_buf = NULL; #endif - tu_edpt_stream_init(&p_itf->tx.stream, false, true, false, - tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, - p_epbuf->epin, CFG_TUD_VENDOR_EPSIZE); + tu_edpt_stream_init(&p_itf->stream.tx, false, true, false, tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, epin_buf, + CFG_TUD_VENDOR_EPSIZE); } } bool vendord_deinit(void) { for(uint8_t i=0; i<CFG_TUD_VENDOR; i++) { vendord_interface_t* p_itf = &_vendord_itf[i]; - tu_edpt_stream_deinit(&p_itf->rx.stream); - tu_edpt_stream_deinit(&p_itf->tx.stream); + tu_edpt_stream_deinit(&p_itf->stream.rx); + tu_edpt_stream_deinit(&p_itf->stream.tx); } return true; } @@ -188,30 +225,42 @@ void vendord_reset(uint8_t rhport) { for(uint8_t i=0; i<CFG_TUD_VENDOR; i++) { vendord_interface_t* p_itf = &_vendord_itf[i]; tu_memclr(p_itf, ITF_MEM_RESET_SIZE); - tu_edpt_stream_clear(&p_itf->rx.stream); - tu_edpt_stream_close(&p_itf->rx.stream); - tu_edpt_stream_clear(&p_itf->tx.stream); - tu_edpt_stream_close(&p_itf->tx.stream); + tu_edpt_stream_clear(&p_itf->stream.rx); + tu_edpt_stream_close(&p_itf->stream.rx); + + tu_edpt_stream_clear(&p_itf->stream.tx); + tu_edpt_stream_close(&p_itf->stream.tx); } } -uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint16_t max_len) { +// Find vendor interface by endpoint address +static uint8_t find_vendor_itf(uint8_t ep_addr) { + for (uint8_t idx = 0; idx < CFG_TUD_VENDOR; idx++) { + const vendord_interface_t *p_vendor = &_vendord_itf[idx]; + if (ep_addr == 0) { + // find unused: require both ep == 0 + if (p_vendor->stream.rx.ep_addr == 0 && p_vendor->stream.tx.ep_addr == 0) { + return idx; + } + } else if (ep_addr == p_vendor->stream.rx.ep_addr || ep_addr == p_vendor->stream.tx.ep_addr) { + return idx; + } else { + // nothing to do + } + } + return 0xff; +} + +uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint16_t max_len) { TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == desc_itf->bInterfaceClass, 0); const uint8_t* desc_end = (const uint8_t*)desc_itf + max_len; const uint8_t* p_desc = tu_desc_next(desc_itf); // Find available interface - vendord_interface_t* p_vendor = NULL; - uint8_t itf; - for(itf=0; itf<CFG_TUD_VENDOR; itf++) { - if (!tud_vendor_n_mounted(itf)) { - p_vendor = &_vendord_itf[itf]; - break; - } - } - TU_VERIFY(p_vendor, 0); - + const uint8_t idx = find_vendor_itf(0); + TU_ASSERT(idx < CFG_TUD_VENDOR, 0); + vendord_interface_t *p_vendor = &_vendord_itf[idx]; p_vendor->rhport = rhport; p_vendor->itf_num = desc_itf->bInterfaceNumber; @@ -225,16 +274,18 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uin // open endpoint stream, skip if already opened (multiple IN/OUT endpoints) if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_t *stream_tx = &p_vendor->tx.stream; + tu_edpt_stream_t *stream_tx = &p_vendor->stream.tx; if (stream_tx->ep_addr == 0) { tu_edpt_stream_open(stream_tx, desc_ep); tu_edpt_stream_write_xfer(rhport, stream_tx); // flush pending data } } else { - tu_edpt_stream_t *stream_rx = &p_vendor->rx.stream; + tu_edpt_stream_t *stream_rx = &p_vendor->stream.rx; if (stream_rx->ep_addr == 0) { tu_edpt_stream_open(stream_rx, desc_ep); + #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare for incoming data + #endif } } } @@ -247,38 +298,35 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uin bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; + const uint8_t idx = find_vendor_itf(ep_addr); + TU_VERIFY(idx < CFG_TUD_VENDOR); + vendord_interface_t *p_vendor = &_vendord_itf[idx]; - uint8_t itf; - vendord_interface_t* p_vendor; - - for (itf = 0; itf < CFG_TUD_VENDOR; itf++) { - p_vendor = &_vendord_itf[itf]; - if ((ep_addr == p_vendor->rx.stream.ep_addr) || (ep_addr == p_vendor->tx.stream.ep_addr)) { - break; - } - } - TU_VERIFY(itf < CFG_TUD_VENDOR); - vendord_epbuf_t* p_epbuf = &_vendord_epbuf[itf]; - - if ( ep_addr == p_vendor->rx.stream.ep_addr ) { + if (ep_addr == p_vendor->stream.rx.ep_addr) { // Received new data: put into stream's fifo - tu_edpt_stream_read_xfer_complete(&p_vendor->rx.stream, xferred_bytes); + tu_edpt_stream_read_xfer_complete(&p_vendor->stream.rx, xferred_bytes); - // Invoked callback if any - tud_vendor_rx_cb(itf, p_epbuf->epout, (uint16_t) xferred_bytes); + // invoke callback + #if CFG_TUD_VENDOR_RX_BUFSIZE == 0 + tud_vendor_rx_cb(idx, p_vendor->stream.rx.ep_buf, xferred_bytes); + #else + tud_vendor_rx_cb(idx, NULL, 0); + #endif - tu_edpt_stream_read_xfer(rhport, &p_vendor->rx.stream); - } else if ( ep_addr == p_vendor->tx.stream.ep_addr ) { + #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 + tu_edpt_stream_read_xfer(rhport, &p_vendor->stream.rx); // prepare next data + #endif + } else if (ep_addr == p_vendor->stream.tx.ep_addr) { // Send complete - tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); + tud_vendor_tx_cb(idx, (uint16_t)xferred_bytes); - #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 // try to send more if possible - if ( 0 == tu_edpt_stream_write_xfer(rhport, &p_vendor->tx.stream) ) { + if (0 == tu_edpt_stream_write_xfer(rhport, &p_vendor->stream.tx)) { // 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(rhport, &p_vendor->tx.stream, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(rhport, &p_vendor->stream.tx, xferred_bytes); } - #endif + #endif } return true; diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 5376f3917..764d99070 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -27,87 +27,133 @@ #ifndef TUSB_VENDOR_DEVICE_H_ #define TUSB_VENDOR_DEVICE_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include "common/tusb_common.h" +//--------------------------------------------------------------------+ +// Configuration +//--------------------------------------------------------------------+ #ifndef CFG_TUD_VENDOR_EPSIZE -#define CFG_TUD_VENDOR_EPSIZE 64 + #define CFG_TUD_VENDOR_EPSIZE 64 #endif // RX FIFO can be disabled by setting this value to 0 #ifndef CFG_TUD_VENDOR_RX_BUFSIZE -#define CFG_TUD_VENDOR_RX_BUFSIZE 64 + #define CFG_TUD_VENDOR_RX_BUFSIZE 64 #endif // TX FIFO can be disabled by setting this value to 0 #ifndef CFG_TUD_VENDOR_TX_BUFSIZE -#define CFG_TUD_VENDOR_TX_BUFSIZE 64 + #define CFG_TUD_VENDOR_TX_BUFSIZE 64 #endif -#ifdef __cplusplus - extern "C" { +// Application will manually schedule RX transfer. This can be useful when using with non-fifo (buffered) mode +// i.e. CFG_TUD_VENDOR_RX_BUFSIZE = 0 +#ifndef CFG_TUD_VENDOR_RX_MANUAL_XFER + #define CFG_TUD_VENDOR_RX_MANUAL_XFER 0 #endif //--------------------------------------------------------------------+ // Application API (Multiple Interfaces) i.e CFG_TUD_VENDOR > 1 //--------------------------------------------------------------------+ -bool tud_vendor_n_mounted (uint8_t itf); -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); -uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); -uint32_t tud_vendor_n_write_flush (uint8_t itf); -uint32_t tud_vendor_n_write_available (uint8_t itf); +// Return whether the vendor interface is mounted +bool tud_vendor_n_mounted(uint8_t idx); + +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 +// Return number of available bytes for reading +uint32_t tud_vendor_n_available(uint8_t idx); + +// Peek a byte from RX buffer +bool tud_vendor_n_peek(uint8_t idx, uint8_t *ui8); + +// Read from RX FIFO +uint32_t tud_vendor_n_read(uint8_t idx, void *buffer, uint32_t bufsize); -TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); +// Discard count bytes in RX FIFO +uint32_t tud_vendor_n_read_discard(uint8_t idx, uint32_t count); + +// Flush (clear) RX FIFO +void tud_vendor_n_read_flush(uint8_t idx); +#endif + +#if CFG_TUD_VENDOR_RX_MANUAL_XFER +// Start a new RX transfer to fill the RX FIFO, return false if previous transfer is still ongoing +bool tud_vendor_n_read_xfer(uint8_t idx); +#endif + +// Write to TX FIFO. This can be buffered and not sent immediately unless buffered bytes >= USB endpoint size +uint32_t tud_vendor_n_write(uint8_t idx, const void *buffer, uint32_t bufsize); + +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 +// Force sending buffered data, return number of bytes sent +uint32_t tud_vendor_n_write_flush(uint8_t idx); + +// Return number of bytes available for writing in TX FIFO +uint32_t tud_vendor_n_write_available(uint8_t idx); +#endif + +// Write a null-terminated string to TX FIFO +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_n_write_str(uint8_t idx, const char *str) { + return tud_vendor_n_write(idx, str, strlen(str)); +} // backward compatible -#define tud_vendor_n_flush(itf) tud_vendor_n_write_flush(itf) +#define tud_vendor_n_flush(idx) tud_vendor_n_write_flush(idx) //--------------------------------------------------------------------+ // Application API (Single Port) i.e CFG_TUD_VENDOR = 1 //--------------------------------------------------------------------+ - -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); + return tud_vendor_n_mounted(0); } +#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_available(void) { - return tud_vendor_n_available(0); + 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 bool tud_vendor_peek(uint8_t* ui8) { - return tud_vendor_n_peek(0, ui8); +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 uint32_t tud_vendor_read_discard(uint32_t count) { + return tud_vendor_n_read_discard(0, count); } TU_ATTR_ALWAYS_INLINE static inline void tud_vendor_read_flush(void) { - tud_vendor_n_read_flush(0); + tud_vendor_n_read_flush(0); } +#endif -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); +#if CFG_TUD_VENDOR_RX_MANUAL_XFER +TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_read_xfer(void) { + return tud_vendor_n_read_xfer(0); } +#endif -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(const void *buffer, uint32_t bufsize) { + return tud_vendor_n_write(0, buffer, bufsize); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_flush(void) { - return tud_vendor_n_write_flush(0); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_str(const char *str) { + return tud_vendor_n_write_str(0, str); } #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_flush(void) { + return tud_vendor_n_write_flush(0); +} + TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_available(void) { - return tud_vendor_n_write_available(0); + return tud_vendor_n_write_available(0); } #endif @@ -118,15 +164,13 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_available(void) { // Application Callback API (weak is optional) //--------------------------------------------------------------------+ -// Invoked when received new data -void tud_vendor_rx_cb(uint8_t itf, uint8_t const* buffer, uint16_t bufsize); -// Invoked when last rx transfer finished -void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); - -//--------------------------------------------------------------------+ -// Inline Functions -//--------------------------------------------------------------------+ +// Invoked when received new data. +// - CFG_TUD_VENDOR_RX_BUFSIZE > 0; buffer and bufsize must not be used (both NULL,0) since data is in RX FIFO +// - CFG_TUD_VENDOR_RX_BUFSIZE = 0: Buffer and bufsize are valid +void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint32_t bufsize); +// Invoked when tx transfer is finished +void tud_vendor_tx_cb(uint8_t idx, uint32_t sent_bytes); //--------------------------------------------------------------------+ // Internal Class Driver API @@ -134,11 +178,11 @@ void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); void vendord_init(void); bool vendord_deinit(void); void vendord_reset(uint8_t rhport); -uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *idx_desc, uint16_t max_len); bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); #ifdef __cplusplus - } +} #endif #endif /* TUSB_VENDOR_DEVICE_H_ */ |
