From 2f3b21a1e58e5c03c61e83920d77f8c27540dfd5 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 16 Oct 2025 10:44:22 +0700 Subject: fix some warnings detected by pvs-studio --- src/class/cdc/cdc_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index f1c4a3bbf..577a92a52 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -533,7 +533,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Check for wanted char and invoke callback if needed if (((signed char) p_cdc->wanted_char) != -1) { for (uint32_t i = 0; i < xferred_bytes; i++) { - if ((p_cdc->wanted_char == p_epbuf->epout[i]) && !tu_fifo_empty(&p_cdc->rx_ff)) { + if ((p_cdc->wanted_char == (char) p_epbuf->epout[i]) && !tu_fifo_empty(&p_cdc->rx_ff)) { tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); } } -- cgit v1.3.1 From 27415e6114cb6e23ca085b21161eb79278f6b97b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 06:12:08 +0000 Subject: Add is_isr parameter to usbd_edpt_xfer and usbd_edpt_xfer_fifo - Added bool is_isr parameter to usbd_edpt_xfer() and usbd_edpt_xfer_fifo() wrapper functions - These are called by class drivers to queue USB transfers - Updated all callers to pass false by default (non-ISR context) - Updated audiod_rx_xfer_isr() and audiod_tx_xfer_isr() to pass true (ISR context) - All 21 unit tests pass Co-authored-by: HiFiPhile <4375114+HiFiPhile@users.noreply.github.com> --- src/class/audio/audio_device.c | 8 ++++---- src/class/bth/bth_device.c | 6 +++--- src/class/cdc/cdc_device.c | 10 +++++----- src/class/hid/hid_device.c | 6 +++--- src/class/midi/midi_device.c | 6 +++--- src/class/msc/msc_device.c | 12 ++++++------ src/class/mtp/mtp_device.c | 8 ++++---- src/class/net/ecm_rndis_device.c | 6 +++--- src/class/net/ncm_device.c | 10 +++++----- src/class/usbtmc/usbtmc_device.c | 16 ++++++++-------- src/class/video/video_device.c | 4 ++-- src/device/usbd.c | 8 ++++---- src/device/usbd_control.c | 4 ++-- src/device/usbd_pvt.h | 4 ++-- src/tusb.c | 2 +- 15 files changed, 55 insertions(+), 55 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 7df177773..af0be903f 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -520,10 +520,10 @@ static bool audiod_rx_xfer_isr(uint8_t rhport, audiod_function_t* audio, uint16_ TU_VERIFY(tu_fifo_write_n(&audio->ep_out_ff, audio->lin_buf_out, n_bytes_received)); // Schedule for next receive - TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz), false); + TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz, true), false); #else // Data is already placed in EP FIFO, schedule for next receive - TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz), false); + TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz, true), false); #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP @@ -580,10 +580,10 @@ static bool audiod_tx_xfer_isr(uint8_t rhport, audiod_function_t * audio, uint16 #endif #if USE_LINEAR_BUFFER_TX tu_fifo_read_n(&audio->ep_in_ff, audio->lin_buf_in, n_bytes_tx); - TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_in, audio->lin_buf_in, n_bytes_tx)); + TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_in, audio->lin_buf_in, n_bytes_tx, true)); #else // Send everything in ISO EP FIFO - TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_in, &audio->ep_in_ff, n_bytes_tx)); + TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_in, &audio->ep_in_ff, n_bytes_tx, true)); #endif // Call a weak callback here - a possibility for user to get informed former TX was completed and data gets now loaded into EP in buffer diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index 3f1529cb6..b679d6ab6 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -67,7 +67,7 @@ static bool bt_tx_data(uint8_t ep, void *data, uint16_t len) { // skip if previous transfer not complete TU_VERIFY(!usbd_edpt_busy(rhport, ep)); - TU_ASSERT(usbd_edpt_xfer(rhport, ep, data, len)); + TU_ASSERT(usbd_edpt_xfer(rhport, ep, data, len, false)); return true; } @@ -169,7 +169,7 @@ uint16_t btd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_ itf_desc = (tusb_desc_interface_t const *) tu_desc_next(tu_desc_next(desc_ep)); // Prepare for incoming data from host - TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_epbuf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE), 0); + TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_epbuf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE, false), 0); drv_len = hci_itf_size; @@ -272,7 +272,7 @@ bool btd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, tud_bt_acl_data_received_cb(_btd_epbuf.epout_buf, xferred_bytes); // prepare for next data - TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_epbuf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE)); + TU_ASSERT(usbd_edpt_xfer(rhport, _btd_itf.ep_acl_out, _btd_epbuf.epout_buf, CFG_TUD_BTH_DATA_EPSIZE, false)); } else if (ep_addr == _btd_itf.ep_ev) { tud_bt_event_sent_cb((uint16_t) xferred_bytes); } else if (ep_addr == _btd_itf.ep_acl_in) { diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index f1c4a3bbf..bef430a5d 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -111,7 +111,7 @@ static bool _prep_out_transaction(uint8_t itf) { available = tu_fifo_remaining(&p_cdc->rx_ff); if (available >= CFG_TUD_CDC_EP_BUFSIZE) { - return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_epbuf->epout, CFG_TUD_CDC_EP_BUFSIZE); + return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_epbuf->epout, CFG_TUD_CDC_EP_BUFSIZE, false); } else { // Release endpoint since we don't make any transfer usbd_edpt_release(p_cdc->rhport, p_cdc->ep_out); @@ -196,7 +196,7 @@ bool tud_cdc_n_notify_uart_state (uint8_t itf, const cdc_notify_uart_state_t *st notify_msg->request.wLength = sizeof(cdc_notify_uart_state_t); notify_msg->serial_state = *state; - return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *)notify_msg, 8 + sizeof(cdc_notify_uart_state_t)); + return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *, false)notify_msg, 8 + sizeof(cdc_notify_uart_state_t)); } bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed_change_t* conn_speed_change) { @@ -213,7 +213,7 @@ bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed notify_msg->request.wLength = sizeof(cdc_notify_conn_speed_change_t); notify_msg->conn_speed_change = *conn_speed_change; - return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *)notify_msg, 8 + sizeof(cdc_notify_conn_speed_change_t)); + return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *, false)notify_msg, 8 + sizeof(cdc_notify_conn_speed_change_t)); } #endif @@ -280,7 +280,7 @@ uint32_t tud_cdc_n_write_flush(uint8_t itf) { const uint16_t count = tu_fifo_read_n(&p_cdc->tx_ff, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE); if (count) { - TU_ASSERT(usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_in, p_epbuf->epin, count), 0); + TU_ASSERT(usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_in, p_epbuf->epin, count, false), 0); return count; } else { // Release endpoint since we don't make any transfer @@ -560,7 +560,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // xferred_bytes is multiple of EP Packet size and not zero if (!tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE - 1)))) { if (usbd_edpt_claim(rhport, p_cdc->ep_in)) { - TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0)); + TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0, false)); } } } diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index b4f24902b..6ee4cd9c1 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -128,7 +128,7 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, u TU_VERIFY(0 == tu_memcpy_s(p_epbuf->epin, CFG_TUD_HID_EP_BUFSIZE, report, len)); } - return usbd_edpt_xfer(rhport, p_hid->ep_in, p_epbuf->epin, len); + return usbd_edpt_xfer(rhport, p_hid->ep_in, p_epbuf->epin, len, false); } uint8_t tud_hid_n_interface_protocol(uint8_t instance) { @@ -263,7 +263,7 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16 // Prepare for output endpoint if (p_hid->ep_out) { - TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_epbuf->epout, CFG_TUD_HID_EP_BUFSIZE), drv_len); + TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_epbuf->epout, CFG_TUD_HID_EP_BUFSIZE, false), drv_len); } return drv_len; @@ -413,7 +413,7 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ } // prepare for new transfer - TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_epbuf->epout, CFG_TUD_HID_EP_BUFSIZE)); + TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_epbuf->epout, CFG_TUD_HID_EP_BUFSIZE, false)); } return true; diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 7dac7c4a5..c4b4925d6 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -99,7 +99,7 @@ static void _prep_out_transaction(uint8_t idx) { available = tu_fifo_remaining(&p_midi->rx_ff); if ( available >= CFG_TUD_MIDI_EP_BUFSIZE ) { - usbd_edpt_xfer(rhport, p_midi->ep_out, _midid_epbuf[idx].epout, CFG_TUD_MIDI_EP_BUFSIZE); + usbd_edpt_xfer(rhport, p_midi->ep_out, _midid_epbuf[idx].epout, CFG_TUD_MIDI_EP_BUFSIZE, false); }else { // Release endpoint since we don't make any transfer @@ -228,7 +228,7 @@ static uint32_t write_flush(uint8_t idx) { uint16_t count = tu_fifo_read_n(&midi->tx_ff, _midid_epbuf[idx].epin, CFG_TUD_MIDI_EP_BUFSIZE); if (count) { - TU_ASSERT( usbd_edpt_xfer(rhport, midi->ep_in, _midid_epbuf[idx].epin, count), 0 ); + TU_ASSERT( usbd_edpt_xfer(rhport, midi->ep_in, _midid_epbuf[idx].epin, count, false), 0 ); return count; }else { // Release endpoint since we don't make any transfer @@ -548,7 +548,7 @@ bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32 // xferred_bytes is multiple of EP size and not zero if (!tu_fifo_count(&p_midi->tx_ff) && xferred_bytes && (0 == (xferred_bytes % CFG_TUD_MIDI_EP_BUFSIZE))) { if (usbd_edpt_claim(rhport, p_midi->ep_in)) { - usbd_edpt_xfer(rhport, p_midi->ep_in, NULL, 0); + usbd_edpt_xfer(rhport, p_midi->ep_in, NULL, 0, false); } } } diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index b0eafd5da..b272c80c0 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -113,13 +113,13 @@ static inline bool send_csw(mscd_interface_t* p_msc) { p_msc->csw.data_residue = p_msc->cbw.total_bytes - p_msc->xferred_len; p_msc->stage = MSC_STAGE_STATUS_SENT; memcpy(_mscd_epbuf.buf, &p_msc->csw, sizeof(msc_csw_t)); - return usbd_edpt_xfer(rhport, p_msc->ep_in , _mscd_epbuf.buf, sizeof(msc_csw_t)); + return usbd_edpt_xfer(rhport, p_msc->ep_in , _mscd_epbuf.buf, sizeof(msc_csw_t), false); } static inline bool prepare_cbw(mscd_interface_t* p_msc) { uint8_t rhport = p_msc->rhport; p_msc->stage = MSC_STAGE_CMD; - return usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, sizeof(msc_cbw_t)); + return usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, sizeof(msc_cbw_t), false); } static void fail_scsi_op(mscd_interface_t* p_msc, uint8_t status) { @@ -531,7 +531,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } else { // Didn't check for case 9 (Ho > Dn), which requires examining scsi command first // but it is OK to just receive data then responded with failed status - TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, (uint16_t) p_msc->total_len)); + TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, (uint16_t) p_msc->total_len, false)); } } else { // First process if it is a built-in commands @@ -563,7 +563,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } else { // cannot return more than host expect p_msc->total_len = tu_min32((uint32_t)resplen, p_cbw->total_bytes); - TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_epbuf.buf, (uint16_t) p_msc->total_len)); + TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_epbuf.buf, (uint16_t) p_msc->total_len, false)); } } } @@ -860,7 +860,7 @@ static void proc_read10_cmd(mscd_interface_t* p_msc) { static void proc_read_io_data(mscd_interface_t* p_msc, int32_t nbytes) { const uint8_t rhport = p_msc->rhport; if (nbytes > 0) { - TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_epbuf.buf, (uint16_t) nbytes),); + TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_epbuf.buf, (uint16_t) nbytes, false),); } else { // nbytes is status switch (nbytes) { @@ -896,7 +896,7 @@ static void proc_write10_cmd(mscd_interface_t* p_msc) { // remaining bytes capped at class buffer uint16_t nbytes = (uint16_t)tu_min32(CFG_TUD_MSC_EP_BUFSIZE, p_cbw->total_bytes - p_msc->xferred_len); // Write10 callback will be called later when usb transfer complete - TU_ASSERT(usbd_edpt_xfer(p_msc->rhport, p_msc->ep_out, _mscd_epbuf.buf, nbytes),); + TU_ASSERT(usbd_edpt_xfer(p_msc->rhport, p_msc->ep_out, _mscd_epbuf.buf, nbytes, false),); } // process new data arrived from WRITE10 diff --git a/src/class/mtp/mtp_device.c b/src/class/mtp/mtp_device.c index 04bde9415..0499f2dda 100644 --- a/src/class/mtp/mtp_device.c +++ b/src/class/mtp/mtp_device.c @@ -191,7 +191,7 @@ TU_ATTR_UNUSED static const char* _mtp_phase_str[] = { //--------------------------------------------------------------------+ static bool prepare_new_command(mtpd_interface_t* p_mtp) { p_mtp->phase = MTP_PHASE_COMMAND; - return usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_out, _mtpd_epbuf.buf, CFG_TUD_MTP_EP_BUFSIZE); + return usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_out, _mtpd_epbuf.buf, CFG_TUD_MTP_EP_BUFSIZE, false); } static bool mtpd_data_xfer(mtp_container_info_t* p_container, uint8_t ep_addr) { @@ -219,7 +219,7 @@ static bool mtpd_data_xfer(mtp_container_info_t* p_container, uint8_t ep_addr) { if (xact_len) { // already transferred all bytes in header's length. Application make an unnecessary extra call TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, ep_addr)); - TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, ep_addr, _mtpd_epbuf.buf, xact_len)); + TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, ep_addr, _mtpd_epbuf.buf, xact_len, false)); } return true; } @@ -238,7 +238,7 @@ bool tud_mtp_response_send(mtp_container_info_t* p_container) { p_container->header->type = MTP_CONTAINER_TYPE_RESPONSE_BLOCK; p_container->header->transaction_id = p_mtp->command.header.transaction_id; TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, p_mtp->ep_in)); - return usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_in, _mtpd_epbuf.buf, (uint16_t)p_container->header->len); + return usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_in, _mtpd_epbuf.buf, (uint16_t) p_container->header->len, false); } bool tud_mtp_mounted(void) { @@ -251,7 +251,7 @@ bool tud_mtp_event_send(mtp_event_t* event) { TU_VERIFY(p_mtp->ep_event != 0); _mtpd_epbuf.buf_event = *event; TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, p_mtp->ep_event)); // Claim the endpoint - return usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_event, (uint8_t*) &_mtpd_epbuf.buf_event, sizeof(mtp_event_t)); + return usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_event, (uint8_t*, false) &_mtpd_epbuf.buf_event, sizeof(mtp_event_t)); } //--------------------------------------------------------------------+ diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c index 7dff66823..eaa82c187 100644 --- a/src/class/net/ecm_rndis_device.c +++ b/src/class/net/ecm_rndis_device.c @@ -82,12 +82,12 @@ static bool can_xmit; static bool ecm_link_is_up = true; // Store link state for ECM mode void tud_network_recv_renew(void) { - usbd_edpt_xfer(0, _netd_itf.ep_out, _netd_epbuf.rx, NETD_PACKET_SIZE); + usbd_edpt_xfer(0, _netd_itf.ep_out, _netd_epbuf.rx, NETD_PACKET_SIZE, false); } static void do_in_xfer(uint8_t *buf, uint16_t len) { can_xmit = false; - usbd_edpt_xfer(0, _netd_itf.ep_in, buf, len); + usbd_edpt_xfer(0, _netd_itf.ep_in, buf, len, false); } void netd_report(uint8_t *buf, uint16_t len) { @@ -100,7 +100,7 @@ void netd_report(uint8_t *buf, uint16_t len) { } memcpy(_netd_epbuf.notify, buf, len); - usbd_edpt_xfer(rhport, _netd_itf.ep_notif, _netd_epbuf.notify, len); + usbd_edpt_xfer(rhport, _netd_itf.ep_notif, _netd_epbuf.notify, len, false); } //--------------------------------------------------------------------+ diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 02833c5f1..5e6dc5610 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -205,7 +205,7 @@ static void notification_xmit(uint8_t rhport, bool force_next) { uint16_t notif_len = sizeof(notify_speed_change.header) + notify_speed_change.header.wLength; ncm_epbuf.epnotif = notify_speed_change; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_epbuf.epnotif, notif_len); + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*, false) &ncm_epbuf.epnotif, notif_len); ncm_interface.notification_xmit_state = NOTIFICATION_CONNECTED; ncm_interface.notification_xmit_is_running = true; @@ -227,7 +227,7 @@ static void notification_xmit(uint8_t rhport, bool force_next) { uint16_t notif_len = sizeof(notify_connected.header) + notify_connected.header.wLength; ncm_epbuf.epnotif = notify_connected; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_epbuf.epnotif, notif_len); + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *, false) &ncm_epbuf.epnotif, notif_len); ncm_interface.notification_xmit_state = NOTIFICATION_DONE; ncm_interface.notification_xmit_is_running = true; @@ -331,7 +331,7 @@ static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) { TU_LOG_DRV("xmit_insert_required_zlp! (%u)\n", (unsigned) xferred_bytes); // start transmission of the ZLP - usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0); + usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0, false); return true; } // xmit_insert_required_zlp @@ -377,7 +377,7 @@ static void xmit_start_if_possible(uint8_t rhport) { } // Kick off an endpoint transfer - usbd_edpt_xfer(0, ncm_interface.ep_in, ncm_interface.xmit_tinyusb_ntb->data, ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength); + usbd_edpt_xfer(0, ncm_interface.ep_in, ncm_interface.xmit_tinyusb_ntb->data, ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, false); } // xmit_start_if_possible /** @@ -526,7 +526,7 @@ static void recv_try_to_start_new_reception(uint8_t rhport) { // initiate transfer TU_LOG_DRV(" start reception\n"); - bool r = usbd_edpt_xfer(rhport, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + bool r = usbd_edpt_xfer(rhport, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE, false); if (!r) { recv_put_ntb_into_free_list(ncm_interface.recv_tinyusb_ntb); ncm_interface.recv_tinyusb_ntb = NULL; diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 3f6bedd4c..e97740079 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -261,7 +261,7 @@ bool tud_usbtmc_transmit_dev_msg_data( bool stateChanged = atomicChangeState(STATE_TX_REQUESTED, (packetLen >= txBufLen) ? STATE_TX_INITIATED : STATE_TX_SHORTED); TU_VERIFY(stateChanged); - TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, (uint16_t) packetLen)); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, (uint16_t) packetLen, false)); return true; } @@ -273,7 +273,7 @@ bool tud_usbtmc_transmit_notification_data(const void *data, size_t len) { TU_VERIFY(usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)); TU_VERIFY(tu_memcpy_s(usbtmc_epbuf.epnotif, CFG_TUD_USBTMC_INT_EP_SIZE, data, len) == 0); - TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, usbtmc_epbuf.epnotif, (uint16_t) len)); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, usbtmc_epbuf.epnotif, (uint16_t) len, false)); return true; } @@ -396,7 +396,7 @@ bool tud_usbtmc_start_bus_read(void) { default: return false; } - TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_out, usbtmc_epbuf.epout, (uint16_t) usbtmc_state.ep_bulk_out_wMaxPacketSize)); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_out, usbtmc_epbuf.epout, (uint16_t) usbtmc_state.ep_bulk_out_wMaxPacketSize, false)); return true; } @@ -567,7 +567,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint if (usbtmc_state.transfer_size_remaining >= USBTMCD_BUFFER_SIZE) { // Copy buffer to ensure alignment correctness memcpy(usbtmc_epbuf.epin, usbtmc_state.devInBuffer, USBTMCD_BUFFER_SIZE); - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, USBTMCD_BUFFER_SIZE)); + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, USBTMCD_BUFFER_SIZE, false)); usbtmc_state.devInBuffer += USBTMCD_BUFFER_SIZE; usbtmc_state.transfer_size_remaining -= USBTMCD_BUFFER_SIZE; usbtmc_state.transfer_size_sent += USBTMCD_BUFFER_SIZE; @@ -578,7 +578,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint usbtmc_state.transfer_size_sent += packetLen; usbtmc_state.transfer_size_remaining = 0; usbtmc_state.devInBuffer = NULL; - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, (uint16_t) packetLen)); + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, (uint16_t) packetLen, false)); if (((packetLen % usbtmc_state.ep_bulk_in_wMaxPacketSize) != 0) || (packetLen == 0)) { usbtmc_state.state = STATE_TX_SHORTED; } @@ -587,7 +587,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case STATE_ABORTING_BULK_IN: // need to send short packet (ZLP?) - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, (uint16_t) 0u)); + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, (uint16_t) 0u, false)); usbtmc_state.state = STATE_ABORTING_BULK_IN_SHORTED; return true; @@ -713,7 +713,7 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request criticalLeave(); if (usbtmc_state.transfer_size_sent == 0) { // Send short packet, nothing is in the buffer yet - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, (uint16_t) 0u)); + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_epbuf.epin, (uint16_t) 0u, false)); usbtmc_state.state = STATE_ABORTING_BULK_IN_SHORTED; } TU_VERIFY(tud_usbtmc_initiate_abort_bulk_in_cb(&(rsp.USBTMC_status))); @@ -841,7 +841,7 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request }, .StatusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status))}; // Must be queued before control request response sent (USB488v1.0 4.3.1.2) - usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void *) &intMsg, sizeof(intMsg)); + usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void *, false) &intMsg, sizeof(intMsg)); } } else { rsp.statusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)); diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 5c00cc358..2c610c469 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -1262,7 +1262,7 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu stm->buffer = (uint8_t*)buffer; stm->bufsize = bufsize; uint_fast16_t pkt_len = _prepare_in_payload(stm, stm_epbuf->buf); - TU_ASSERT( usbd_edpt_xfer(0, ep_addr, stm_epbuf->buf, (uint16_t) pkt_len), 0); + TU_ASSERT( usbd_edpt_xfer(0, ep_addr, stm_epbuf->buf, (uint16_t) pkt_len, false), 0); return true; } @@ -1433,7 +1433,7 @@ bool videod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 /* Claim the endpoint */ TU_VERIFY( usbd_edpt_claim(rhport, ep_addr), 0); uint_fast16_t pkt_len = _prepare_in_payload(stm, stm_epbuf->buf); - TU_ASSERT( usbd_edpt_xfer(rhport, ep_addr, stm_epbuf->buf, (uint16_t) pkt_len), 0); + TU_ASSERT( usbd_edpt_xfer(rhport, ep_addr, stm_epbuf->buf, (uint16_t) pkt_len, false), 0); } else { stm->buffer = NULL; stm->bufsize = 0; diff --git a/src/device/usbd.c b/src/device/usbd.c index d5ebcc66b..a664c2186 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1410,7 +1410,7 @@ bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) { return tu_edpt_release(ep_state, _usbd_mutex); } -bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { +bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes, bool is_isr) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); @@ -1433,7 +1433,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t t // could return and USBD task can preempt and clear the busy _usbd_dev.ep_status[epnum][dir].busy = 1; - if (dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes, false)) { + if (dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes, is_isr)) { return true; } else { // DCD error, mark endpoint as ready to allow next transfer @@ -1449,7 +1449,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t t // bytes should be written and second to keep the return value free to give back a boolean // success message. If total_bytes is too big, the FIFO will copy only what is available // into the USB buffer! -bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t total_bytes) { +bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t total_bytes, bool is_isr) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); @@ -1464,7 +1464,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_ // and usbd task can preempt and clear the busy _usbd_dev.ep_status[epnum][dir].busy = 1; - if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes, false)) { + if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes, is_isr)) { TU_LOG_USBD("OK\r\n"); return true; } else { diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index c9700fd9d..b75362425 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -71,7 +71,7 @@ CFG_TUD_MEM_SECTION static struct { static inline bool status_stage_xact(uint8_t rhport, const tusb_control_request_t* request) { // Opposite to endpoint in Data Phase const uint8_t ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN; - return usbd_edpt_xfer(rhport, ep_addr, NULL, 0); + return usbd_edpt_xfer(rhport, ep_addr, NULL, 0, false); } // Status phase @@ -98,7 +98,7 @@ static bool data_stage_xact(uint8_t rhport) { } } - return usbd_edpt_xfer(rhport, ep_addr, xact_len ? _ctrl_epbuf.buf : NULL, xact_len); + return usbd_edpt_xfer(rhport, ep_addr, xact_len ? _ctrl_epbuf.buf : NULL, xact_len, false); } // Transmit data to/from the control endpoint. diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index a688cf497..a1c884f12 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -84,10 +84,10 @@ bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr); // Submit a usb transfer -bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); +bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr); // Submit a usb ISO transfer by use of a FIFO (ring buffer) - all bytes in FIFO get transmitted -bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes); +bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr); // Claim an endpoint before submitting a transfer. // If caller does not make any transfer, it must release endpoint for others. diff --git a/src/tusb.c b/src/tusb.c index 083e6d861..7f451ee70 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -378,7 +378,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(uint8_t hwid, tu_edpt_strea #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count); + return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false); #endif } return false; -- cgit v1.3.1 From 30132e8e6d39447c0633f96594ff4bdac06d6bc8 Mon Sep 17 00:00:00 2001 From: Mengsk Date: Wed, 22 Oct 2025 16:57:11 +0200 Subject: Fix copilot issues Signed-off-by: Mengsk --- hw/mcu/raspberry_pi/Pico-PIO-USB | 1 - hw/mcu/st/cmsis_device_f4 | 1 - hw/mcu/st/stm32f4xx_hal_driver | 1 - lib/CMSIS_5 | 1 - lib/FreeRTOS-Kernel | 1 - lib/lwip | 1 - src/class/audio/audio_device.c | 22 +++++++++++----------- src/class/cdc/cdc_device.c | 4 ++-- src/class/mtp/mtp_device.c | 2 +- src/class/net/ncm_device.c | 4 ++-- src/class/usbtmc/usbtmc_device.c | 2 +- src/portable/chipidea/ci_fs/dcd_ci_fs.c | 2 +- src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c | 2 +- src/portable/nxp/khci/dcd_khci.c | 2 +- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 1 - test/fuzz/dcd_fuzz.cc | 5 +++-- tools/uf2 | 1 - 17 files changed, 23 insertions(+), 30 deletions(-) delete mode 160000 hw/mcu/raspberry_pi/Pico-PIO-USB delete mode 160000 hw/mcu/st/cmsis_device_f4 delete mode 160000 hw/mcu/st/stm32f4xx_hal_driver delete mode 160000 lib/CMSIS_5 delete mode 160000 lib/FreeRTOS-Kernel delete mode 160000 lib/lwip delete mode 160000 tools/uf2 (limited to 'src/class/cdc/cdc_device.c') diff --git a/hw/mcu/raspberry_pi/Pico-PIO-USB b/hw/mcu/raspberry_pi/Pico-PIO-USB deleted file mode 160000 index 675543bcc..000000000 --- a/hw/mcu/raspberry_pi/Pico-PIO-USB +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 675543bcc9baa8170f868ab7ba316d418dbcf41f diff --git a/hw/mcu/st/cmsis_device_f4 b/hw/mcu/st/cmsis_device_f4 deleted file mode 160000 index 3c77349ce..000000000 --- a/hw/mcu/st/cmsis_device_f4 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3c77349ce04c8af401454cc51f85ea9a50e34fc1 diff --git a/hw/mcu/st/stm32f4xx_hal_driver b/hw/mcu/st/stm32f4xx_hal_driver deleted file mode 160000 index b6f0ed382..000000000 --- a/hw/mcu/st/stm32f4xx_hal_driver +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b6f0ed3829f3829eb358a2e7417d80bba1a42db7 diff --git a/lib/CMSIS_5 b/lib/CMSIS_5 deleted file mode 160000 index 2b7495b85..000000000 --- a/lib/CMSIS_5 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c diff --git a/lib/FreeRTOS-Kernel b/lib/FreeRTOS-Kernel deleted file mode 160000 index cc0e0707c..000000000 --- a/lib/FreeRTOS-Kernel +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cc0e0707c0c748713485b870bb980852b210877f diff --git a/lib/lwip b/lib/lwip deleted file mode 160000 index 159e31b68..000000000 --- a/lib/lwip +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 159e31b689577dbf69cf0683bbaffbd71fa5ee10 diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index af0be903f..6c972ca7a 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -520,10 +520,10 @@ static bool audiod_rx_xfer_isr(uint8_t rhport, audiod_function_t* audio, uint16_ TU_VERIFY(tu_fifo_write_n(&audio->ep_out_ff, audio->lin_buf_out, n_bytes_received)); // Schedule for next receive - TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz, true), false); + TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz, true)); #else // Data is already placed in EP FIFO, schedule for next receive - TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz, true), false); + TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz, true)); #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP @@ -607,7 +607,7 @@ bool tud_audio_int_n_write(uint8_t func_id, const audio_interrupt_data_t *data) // Check length if (tu_memcpy_s(int_ep_buf[func_id].buf, sizeof(int_ep_buf[func_id].buf), data, sizeof(audio_interrupt_data_t)) == 0) { // Schedule transmit - TU_ASSERT(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int, int_ep_buf[func_id].buf, sizeof(int_ep_buf[func_id].buf)), 0); + TU_ASSERT(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int, int_ep_buf[func_id].buf, sizeof(int_ep_buf[func_id].buf), false)); } else { // Release endpoint since we don't make any transfer usbd_edpt_release(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int); @@ -619,7 +619,7 @@ bool tud_audio_int_n_write(uint8_t func_id, const audio_interrupt_data_t *data) #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // This function is called once a transmit of a feedback packet was successfully completed. Here, we get the next feedback value to be sent -static inline bool audiod_fb_send(audiod_function_t *audio) { +static inline bool audiod_fb_send(audiod_function_t *audio, bool is_isr) { bool apply_correction = (TUSB_SPEED_FULL == tud_speed_get()) && audio->feedback.format_correction; // Format the feedback value if (apply_correction) { @@ -647,7 +647,7 @@ static inline bool audiod_fb_send(audiod_function_t *audio) { // 10.14 3 3 Linux, OSX // // We send 3 bytes since sending packet larger than wMaxPacketSize is pretty ugly - return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) audio->fb_buf, apply_correction ? 3 : 4); + return usbd_edpt_xfer(audio->rhport, audio->ep_fb, (uint8_t *) audio->fb_buf, apply_correction ? 3 : 4, is_isr); } #endif @@ -1133,10 +1133,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *p #endif // Schedule first transmit if alternate interface is not zero, as sample data is available a ZLP is loaded #if USE_LINEAR_BUFFER_TX - TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_in, audio->lin_buf_in, 0)); + TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_in, audio->lin_buf_in, 0, false)); #else // Send everything in ISO EP FIFO - TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_in, &audio->ep_in_ff, 0)); + TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_in, &audio->ep_in_ff, 0, false)); #endif } #endif// CFG_TUD_AUDIO_ENABLE_EP_IN @@ -1152,9 +1152,9 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *p // Prepare for incoming data #if USE_LINEAR_BUFFER_RX - TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz), false); + TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz, false)); #else - TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz), false); + TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz, false)); #endif } @@ -1164,7 +1164,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *p audio->ep_fb = ep_addr; audio->feedback.frame_shift = desc_ep->bInterval - 1; // Schedule first feedback transmit - audiod_fb_send(audio); + audiod_fb_send(audio, false); } #endif #endif// CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1472,7 +1472,7 @@ bool audiod_xfer_isr(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint if (audio->ep_fb == ep_addr) { // Schedule a transmit with the new value if EP is not busy // Schedule next transmission - value is changed bytud_audio_n_fb_set() in the meantime or the old value gets sent - audiod_fb_send(audio); + audiod_fb_send(audio, true); return true; } #endif diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index bef430a5d..94c82cc77 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -196,7 +196,7 @@ bool tud_cdc_n_notify_uart_state (uint8_t itf, const cdc_notify_uart_state_t *st notify_msg->request.wLength = sizeof(cdc_notify_uart_state_t); notify_msg->serial_state = *state; - return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *, false)notify_msg, 8 + sizeof(cdc_notify_uart_state_t)); + return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *)notify_msg, 8 + sizeof(cdc_notify_uart_state_t), false); } bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed_change_t* conn_speed_change) { @@ -213,7 +213,7 @@ bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed notify_msg->request.wLength = sizeof(cdc_notify_conn_speed_change_t); notify_msg->conn_speed_change = *conn_speed_change; - return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *, false)notify_msg, 8 + sizeof(cdc_notify_conn_speed_change_t)); + return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *)notify_msg, 8 + sizeof(cdc_notify_conn_speed_change_t), false); } #endif diff --git a/src/class/mtp/mtp_device.c b/src/class/mtp/mtp_device.c index 0499f2dda..764019e42 100644 --- a/src/class/mtp/mtp_device.c +++ b/src/class/mtp/mtp_device.c @@ -251,7 +251,7 @@ bool tud_mtp_event_send(mtp_event_t* event) { TU_VERIFY(p_mtp->ep_event != 0); _mtpd_epbuf.buf_event = *event; TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, p_mtp->ep_event)); // Claim the endpoint - return usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_event, (uint8_t*, false) &_mtpd_epbuf.buf_event, sizeof(mtp_event_t)); + return usbd_edpt_xfer(p_mtp->rhport, p_mtp->ep_event, (uint8_t*) &_mtpd_epbuf.buf_event, sizeof(mtp_event_t), false); } //--------------------------------------------------------------------+ diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 5e6dc5610..335f6ad09 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -205,7 +205,7 @@ static void notification_xmit(uint8_t rhport, bool force_next) { uint16_t notif_len = sizeof(notify_speed_change.header) + notify_speed_change.header.wLength; ncm_epbuf.epnotif = notify_speed_change; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*, false) &ncm_epbuf.epnotif, notif_len); + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t*) &ncm_epbuf.epnotif, notif_len, false); ncm_interface.notification_xmit_state = NOTIFICATION_CONNECTED; ncm_interface.notification_xmit_is_running = true; @@ -227,7 +227,7 @@ static void notification_xmit(uint8_t rhport, bool force_next) { uint16_t notif_len = sizeof(notify_connected.header) + notify_connected.header.wLength; ncm_epbuf.epnotif = notify_connected; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *, false) &ncm_epbuf.epnotif, notif_len); + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_epbuf.epnotif, notif_len, false); ncm_interface.notification_xmit_state = NOTIFICATION_DONE; ncm_interface.notification_xmit_is_running = true; diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index e97740079..4b0bb01ec 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -841,7 +841,7 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request }, .StatusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status))}; // Must be queued before control request response sent (USB488v1.0 4.3.1.2) - usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void *, false) &intMsg, sizeof(intMsg)); + usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void *) &intMsg, sizeof(intMsg), false); } } else { rsp.statusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)); diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c index 6bf3450ed..283baf645 100644 --- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c +++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c @@ -132,7 +132,7 @@ static void prepare_next_setup_packet(uint8_t rhport) _dcd.bdt[0][1][in_odd].data = 1; _dcd.bdt[0][1][in_odd ^ 1].data = 0; dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), - _dcd.setup_packet, sizeof(_dcd.setup_packet)); + _dcd.setup_packet, sizeof(_dcd.setup_packet), false); } static void process_stall(uint8_t rhport) diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c index 5cec4defb..6c0302031 100644 --- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c +++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -128,7 +128,7 @@ static void prepare_next_setup_packet(uint8_t rhport) _dcd.bdt[0][1][in_odd].data = 1; _dcd.bdt[0][1][in_odd ^ 1].data = 0; dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), - _dcd.setup_packet, sizeof(_dcd.setup_packet)); + _dcd.setup_packet, sizeof(_dcd.setup_packet), false); } static void process_stall(uint8_t rhport) diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index 395bf0d3d..3b0de47f4 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -130,7 +130,7 @@ static void prepare_next_setup_packet(uint8_t rhport) _dcd.bdt[0][1][in_odd].data = 1; _dcd.bdt[0][1][in_odd ^ 1].data = 0; dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), - _dcd.setup_packet, sizeof(_dcd.setup_packet)); + _dcd.setup_packet, sizeof(_dcd.setup_packet), false); } static void process_stall(uint8_t rhport) diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 6e889b473..2257d0368 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -488,7 +488,6 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t //--------------------------------------------------------------------+ static void bus_reset(uint8_t rhport) { - (void) is_isr; tu_memclr(&_dcd, sizeof(dcd_data_t)); edpt_reset_all(rhport); diff --git a/test/fuzz/dcd_fuzz.cc b/test/fuzz/dcd_fuzz.cc index 046a90555..7a5d51623 100644 --- a/test/fuzz/dcd_fuzz.cc +++ b/test/fuzz/dcd_fuzz.cc @@ -104,7 +104,7 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { UNUSED(rhport); state.address = dev_addr; // Respond with status. - dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false); return; } @@ -160,10 +160,11 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to // notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, - uint16_t total_bytes) { + uint16_t total_bytes, bool is_isr) { UNUSED(rhport); UNUSED(buffer); UNUSED(total_bytes); + UNUSED(is_isr); uint8_t const dir = tu_edpt_dir(ep_addr); diff --git a/tools/uf2 b/tools/uf2 deleted file mode 160000 index c594542b2..000000000 --- a/tools/uf2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c594542b2faa01cc33a2b97c9fbebc38549df80a -- cgit v1.3.1 From 9fac6dd49d9cd681ed9140c124d3001b6d1491be Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 7 Nov 2025 14:04:58 +0700 Subject: fix more alerts found by pvs-studio --- .PVS-Studio/.pvsconfig | 11 +- .clang-format | 5 +- .github/copilot-instructions.md | 24 ++ .../net_lwip_webserver/src/usb_descriptors.c | 251 +++++++++++---------- hw/bsp/imxrt/family.cmake | 3 +- hw/bsp/rp2040/family.c | 4 +- src/class/cdc/cdc_device.c | 23 +- src/class/cdc/cdc_device.h | 13 +- src/class/msc/msc_device.c | 79 ++++--- src/class/msc/msc_host.c | 8 +- src/common/tusb_debug.h | 14 +- src/osal/osal_pico.h | 5 +- 12 files changed, 244 insertions(+), 196 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/.PVS-Studio/.pvsconfig b/.PVS-Studio/.pvsconfig index 2cc60722a..a60d6dd2b 100644 --- a/.PVS-Studio/.pvsconfig +++ b/.PVS-Studio/.pvsconfig @@ -1,13 +1,14 @@ //V_EXCLUDE_PATH */iar/cxarm* -//V_EXCLUDE_PATH */pico-sdk/ -//V_EXCLUDE_PATH */esp-idf/ -//V_EXCLUDE_PATH */hw/bsp/espressif/components/ -//V_EXCLUDE_PATH */hw/mcu/ +//V_EXCLUDE_PATH */pico-sdk/* +//V_EXCLUDE_PATH */esp-idf/* +//V_EXCLUDE_PATH */hw/mcu/* +//V_EXCLUDE_PATH */hw/bsp/espressif/components/* +//V_EXCLUDE_PATH */lib/* //-V::2506 MISRA. A function should have a single point of exit at the end. //-V::2514 MISRA. Unions should not be used. //-V:memcpy:2547 [MISRA-C-17.7] The return value of non-void function 'memcpy' should be used. -//-V:printf:2547 [MISRA-C-17.7] The return value of non-void function 'printf' should be used. +//-V:memmove:2547 [MISRA-C-17.7] The return value of non-void function 'memmove' should be used. //-V::2584::{gintsts} dwc2 //-V::2600 [MISRA-C-21.6] The function with the 'printf' name should not be used. //+V2614 DISABLE_LENGHT_LIMIT_CHECK:YES diff --git a/.clang-format b/.clang-format index 79a160a8d..c7d769172 100644 --- a/.clang-format +++ b/.clang-format @@ -33,7 +33,8 @@ AllowAllConstructorInitializersOnNextLine: false AllowAllParametersOfDeclarationOnNextLine: false AllowShortBlocksOnASingleLine: Empty AllowShortCaseExpressionOnASingleLine: true -AllowShortCaseLabelsOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: false AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: Never AlwaysBreakTemplateDeclarations: Yes @@ -76,6 +77,8 @@ MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 2 NamespaceIndentation: All +QualifierAlignment: Custom +QualifierOrder: ['static', 'const', 'volatile', 'restrict', 'type'] ReflowComments: false SpaceAfterTemplateKeyword: false SpaceBeforeRangeBasedForLoopColon: false diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 9982583cd..9f9ab7e72 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -88,6 +88,30 @@ python3 tools/build.py -b BOARD_NAME - Check spelling: `pip install codespell && codespell` (uses `.codespellrc` config) - Pre-commit hooks validate unit tests and code quality automatically +### Static Analysis with PVS-Studio +- **Analyze whole project**: + ```bash + pvs-studio-analyzer analyze -f examples/cmake-build-raspberry_pi_pico/compile_commands.json -R .PVS-Studio/.pvsconfig -o pvs-report.log -j12 --dump-files --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser + ``` +- **Analyze specific source files**: + ```bash + pvs-studio-analyzer analyze -f examples/cmake-build-raspberry_pi_pico/compile_commands.json -R .PVS-Studio/.pvsconfig -S path/to/file.c -o pvs-report.log -j12 --dump-files --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser + ``` +- **Multiple specific files**: + ```bash + pvs-studio-analyzer analyze -f examples/cmake-build-raspberry_pi_pico/compile_commands.json -R .PVS-Studio/.pvsconfig -S src/file1.c -S src/file2.c -o pvs-report.log -j12 --dump-files --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser + ``` +- Requires `compile_commands.json` in the build directory (generated by CMake with `-DCMAKE_EXPORT_COMPILE_COMMANDS=ON`) +- Use `-f` option to specify path to `compile_commands.json` +- Use `-R .PVS-Studio/.pvsconfig` to specify rule configuration file +- Use `-j12` for parallel analysis with 12 threads +- `--dump-files` saves preprocessed files for debugging +- `--misra-c-version 2023` enables MISRA C:2023 checks +- `--misra-cpp-version 2008` enables MISRA C++:2008 checks +- `--use-old-parser` uses legacy parser for compatibility +- Analysis takes ~10-30 seconds depending on project size. Set timeout to 5+ minutes. +- View results: `plog-converter -a GA:1,2 -t errorfile pvs-report.log` or open in PVS-Studio GUI + ## Validation ### ALWAYS Run These After Making Changes diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index 1bc568983..b49962d65 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -24,6 +24,7 @@ */ #include "bsp/board_api.h" +#include "class/net/net_device.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. @@ -32,35 +33,34 @@ * Auto ProductID layout's Bitmap: * [MSB] NET | VENDOR | MIDI | HID | MSC | CDC [LSB] */ -#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ - PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) | PID_MAP(ECM_RNDIS, 5) | PID_MAP(NCM, 5) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID \ + (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) | \ + PID_MAP(ECM_RNDIS, 5) | PID_MAP(NCM, 5)) // String Descriptor Index -enum -{ +enum { STRID_LANGID = 0, STRID_MANUFACTURER, STRID_PRODUCT, STRID_SERIAL, STRID_INTERFACE, - STRID_MAC + STRID_MAC, + STRID_COUNT }; -enum -{ +enum { ITF_NUM_CDC = 0, ITF_NUM_CDC_DATA, ITF_NUM_TOTAL }; -enum -{ +enum { #if CFG_TUD_ECM_RNDIS CONFIG_ID_RNDIS = 0, CONFIG_ID_ECM = 1, #else - CONFIG_ID_NCM = 0, + CONFIG_ID_NCM = 0, #endif CONFIG_ID_COUNT }; @@ -68,103 +68,103 @@ enum //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -static tusb_desc_device_t const desc_device = -{ - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, +static const tusb_desc_device_t desc_device = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, #if CFG_TUD_NCM - .bcdUSB = 0x0201, + .bcdUSB = 0x0201, #else - .bcdUSB = 0x0200, + .bcdUSB = 0x0200, #endif - // Use Interface Association Descriptor (IAD) device class - .bDeviceClass = TUSB_CLASS_MISC, - .bDeviceSubClass = MISC_SUBCLASS_COMMON, - .bDeviceProtocol = MISC_PROTOCOL_IAD, + // Use Interface Association Descriptor (IAD) device class + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - .idVendor = 0xCafe, - .idProduct = USB_PID, - .bcdDevice = 0x0101, + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0101, - .iManufacturer = STRID_MANUFACTURER, - .iProduct = STRID_PRODUCT, - .iSerialNumber = STRID_SERIAL, + .iManufacturer = STRID_MANUFACTURER, + .iProduct = STRID_PRODUCT, + .iSerialNumber = STRID_SERIAL, - .bNumConfigurations = CONFIG_ID_COUNT // multiple configurations + .bNumConfigurations = CONFIG_ID_COUNT // multiple configurations }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor -uint8_t const * tud_descriptor_device_cb(void) -{ - return (uint8_t const *) &desc_device; +const uint8_t *tud_descriptor_device_cb(void) { + return (const uint8_t *)&desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ -#define MAIN_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_RNDIS_DESC_LEN) -#define ALT_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_ECM_DESC_LEN) -#define NCM_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_NCM_DESC_LEN) +#define MAIN_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_RNDIS_DESC_LEN) +#define ALT_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_ECM_DESC_LEN) +#define NCM_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_NCM_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX - // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number - // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... - #define EPNUM_NET_NOTIF 0x81 - #define EPNUM_NET_OUT 0x02 - #define EPNUM_NET_IN 0x82 +// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number +// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... +#define EPNUM_NET_NOTIF 0x81 +#define EPNUM_NET_OUT 0x02 +#define EPNUM_NET_IN 0x82 #elif CFG_TUSB_MCU == OPT_MCU_CXD56 - // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number - // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) - #define EPNUM_NET_NOTIF 0x83 - #define EPNUM_NET_OUT 0x02 - #define EPNUM_NET_IN 0x81 +// CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number +// 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) +#define EPNUM_NET_NOTIF 0x83 +#define EPNUM_NET_OUT 0x02 +#define EPNUM_NET_IN 0x81 #elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) - // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h - // e.g EP1 OUT & EP1 IN cannot exist together - #define EPNUM_NET_NOTIF 0x81 - #define EPNUM_NET_OUT 0x02 - #define EPNUM_NET_IN 0x83 +// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h +// e.g EP1 OUT & EP1 IN cannot exist together +#define EPNUM_NET_NOTIF 0x81 +#define EPNUM_NET_OUT 0x02 +#define EPNUM_NET_IN 0x83 #else - #define EPNUM_NET_NOTIF 0x81 - #define EPNUM_NET_OUT 0x02 - #define EPNUM_NET_IN 0x82 +#define EPNUM_NET_NOTIF 0x81 +#define EPNUM_NET_OUT 0x02 +#define EPNUM_NET_IN 0x82 #endif #if CFG_TUD_ECM_RNDIS -static uint8_t const rndis_configuration[] = -{ +static uint8_t const rndis_configuration[] = { // Config number (index+1), interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(CONFIG_ID_RNDIS+1, ITF_NUM_TOTAL, 0, MAIN_CONFIG_TOTAL_LEN, 0, 100), + TUD_CONFIG_DESCRIPTOR(CONFIG_ID_RNDIS + 1, ITF_NUM_TOTAL, 0, MAIN_CONFIG_TOTAL_LEN, 0, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. - TUD_RNDIS_DESCRIPTOR(ITF_NUM_CDC, STRID_INTERFACE, EPNUM_NET_NOTIF, 8, EPNUM_NET_OUT, EPNUM_NET_IN, CFG_TUD_NET_ENDPOINT_SIZE), + TUD_RNDIS_DESCRIPTOR( + ITF_NUM_CDC, STRID_INTERFACE, EPNUM_NET_NOTIF, 8, EPNUM_NET_OUT, EPNUM_NET_IN, CFG_TUD_NET_ENDPOINT_SIZE), }; -static uint8_t const ecm_configuration[] = -{ +static const uint8_t ecm_configuration[] = { // Config number (index+1), interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(CONFIG_ID_ECM+1, ITF_NUM_TOTAL, 0, ALT_CONFIG_TOTAL_LEN, 0, 100), + TUD_CONFIG_DESCRIPTOR(CONFIG_ID_ECM + 1, ITF_NUM_TOTAL, 0, ALT_CONFIG_TOTAL_LEN, 0, 100), // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. - TUD_CDC_ECM_DESCRIPTOR(ITF_NUM_CDC, STRID_INTERFACE, STRID_MAC, EPNUM_NET_NOTIF, 64, EPNUM_NET_OUT, EPNUM_NET_IN, CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU), + TUD_CDC_ECM_DESCRIPTOR( + ITF_NUM_CDC, STRID_INTERFACE, STRID_MAC, EPNUM_NET_NOTIF, 64, EPNUM_NET_OUT, EPNUM_NET_IN, + CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU), }; #else -static uint8_t const ncm_configuration[] = -{ +static uint8_t const ncm_configuration[] = { // Config number (index+1), interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(CONFIG_ID_NCM+1, ITF_NUM_TOTAL, 0, NCM_CONFIG_TOTAL_LEN, 0, 100), + TUD_CONFIG_DESCRIPTOR(CONFIG_ID_NCM + 1, ITF_NUM_TOTAL, 0, NCM_CONFIG_TOTAL_LEN, 0, 100), // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. - TUD_CDC_NCM_DESCRIPTOR(ITF_NUM_CDC, STRID_INTERFACE, STRID_MAC, EPNUM_NET_NOTIF, 64, EPNUM_NET_OUT, EPNUM_NET_IN, CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU), + TUD_CDC_NCM_DESCRIPTOR( + ITF_NUM_CDC, STRID_INTERFACE, STRID_MAC, EPNUM_NET_NOTIF, 64, EPNUM_NET_OUT, EPNUM_NET_IN, + CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU), }; #endif @@ -173,21 +173,19 @@ static uint8_t const ncm_configuration[] = // - Windows only works with RNDIS // - MacOS only works with CDC-ECM // - Linux will work on both -static uint8_t const * const configuration_arr[2] = -{ +static const uint8_t *const configuration_arr[CONFIG_ID_COUNT] = { #if CFG_TUD_ECM_RNDIS [CONFIG_ID_RNDIS] = rndis_configuration, - [CONFIG_ID_ECM ] = ecm_configuration + [CONFIG_ID_ECM] = ecm_configuration #else - [CONFIG_ID_NCM ] = ncm_configuration + [CONFIG_ID_NCM] = ncm_configuration #endif }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_descriptor_configuration_cb(uint8_t index) -{ +const uint8_t *tud_descriptor_configuration_cb(uint8_t index) { return (index < CONFIG_ID_COUNT) ? configuration_arr[index] : NULL; } @@ -213,81 +211,84 @@ https://developers.google.com/web/fundamentals/native-hardware/build-for-webusb/ (Section Microsoft OS compatibility descriptors) */ -#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN) +#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN) -#define MS_OS_20_DESC_LEN 0xB2 +#define MS_OS_20_DESC_LEN 0xB2 // BOS Descriptor is required for webUSB -uint8_t const desc_bos[] = -{ +const uint8_t desc_bos[] = { // total length, number of device caps TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1), // Microsoft OS 2.0 descriptor - TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, 1) -}; + TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, 1)}; -uint8_t const * tud_descriptor_bos_cb(void) -{ +const uint8_t *tud_descriptor_bos_cb(void) { return desc_bos; } -uint8_t const desc_ms_os_20[] = -{ +const uint8_t desc_ms_os_20[] = { // Set header: length, type, windows version, total length - U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN), + U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), + U16_TO_U8S_LE(MS_OS_20_DESC_LEN), // Configuration subset header: length, type, configuration index, reserved, configuration total length - U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION), 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A), + U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION), 0, 0, + U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A), // Function Subset header: length, type, first interface, reserved, subset length - U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), ITF_NUM_CDC, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08), + U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), ITF_NUM_CDC, 0, + U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A - 0x08), // MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID - U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'N', 'C', 'M', 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible + U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'N', 'C', 'M', 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible // MS OS 2.0 Registry property descriptor: length, type - U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08-0x08-0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY), - U16_TO_U8S_LE(0x0007), U16_TO_U8S_LE(0x002A), // wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16 - 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, - 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00, + U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A - 0x08 - 0x08 - 0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY), + U16_TO_U8S_LE(0x0007), + U16_TO_U8S_LE(0x002A), // wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16 + 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', + 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00, U16_TO_U8S_LE(0x0050), // wPropertyDataLength - //bPropertyData: {12345678-0D08-43FD-8B3E-127CA8AFFF9D} - '{', 0x00, '1', 0x00, '2', 0x00, '3', 0x00, '4', 0x00, '5', 0x00, '6', 0x00, '7', 0x00, '8', 0x00, '-', 0x00, - '0', 0x00, 'D', 0x00, '0', 0x00, '8', 0x00, '-', 0x00, '4', 0x00, '3', 0x00, 'F', 0x00, 'D', 0x00, '-', 0x00, - '8', 0x00, 'B', 0x00, '3', 0x00, 'E', 0x00, '-', 0x00, '1', 0x00, '2', 0x00, '7', 0x00, 'C', 0x00, 'A', 0x00, - '8', 0x00, 'A', 0x00, 'F', 0x00, 'F', 0x00, 'F', 0x00, '9', 0x00, 'D', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00 -}; + //bPropertyData: {12345678-0D08-43FD-8B3E-127CA8AFFF9D} + '{', 0x00, '1', 0x00, '2', 0x00, '3', 0x00, '4', 0x00, '5', 0x00, '6', 0x00, '7', 0x00, '8', 0x00, '-', 0x00, '0', + 0x00, 'D', 0x00, '0', 0x00, '8', 0x00, '-', 0x00, '4', 0x00, '3', 0x00, 'F', 0x00, 'D', 0x00, '-', 0x00, '8', 0x00, + 'B', 0x00, '3', 0x00, 'E', 0x00, '-', 0x00, '1', 0x00, '2', 0x00, '7', 0x00, 'C', 0x00, 'A', 0x00, '8', 0x00, 'A', + 0x00, 'F', 0x00, 'F', 0x00, 'F', 0x00, '9', 0x00, 'D', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00}; TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size"); // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { +bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request) { // nothing to with DATA & ACK stage - if (stage != CONTROL_STAGE_SETUP) return true; + if (stage != CONTROL_STAGE_SETUP) { + return true; + } switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_VENDOR: - switch (request->bRequest) { + switch (request->bRequest) { //-V2520 //-V2659 case 1: if (request->wIndex == 7) { // Get Microsoft OS 2.0 compatible descriptor uint16_t total_len; memcpy(&total_len, desc_ms_os_20 + 8, 2); - return tud_control_xfer(rhport, request, (void*)(uintptr_t)desc_ms_os_20, total_len); + return tud_control_xfer(rhport, request, (void *)(uintptr_t)desc_ms_os_20, total_len); } else { return false; } - default: break; + default: + break; // nothing to do } break; - default: break; + default: + break; // nothing to do } // stall unknown request @@ -300,26 +301,24 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ //--------------------------------------------------------------------+ // array of pointer to string descriptors -static char const* string_desc_arr [] = -{ - [STRID_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409) - [STRID_MANUFACTURER] = "TinyUSB", // Manufacturer - [STRID_PRODUCT] = "TinyUSB Device", // Product - [STRID_SERIAL] = NULL, // Serials will use unique ID if possible - [STRID_INTERFACE] = "TinyUSB Network Interface" // Interface Description - - // STRID_MAC index is handled separately +static const char *string_desc_arr[STRID_COUNT] = { + [STRID_LANGID] = (const char[]){0x09, 0x04}, // supported language is English (0x0409) + [STRID_MANUFACTURER] = "TinyUSB", // Manufacturer + [STRID_PRODUCT] = "TinyUSB Device", // Product + [STRID_SERIAL] = NULL, // Serials will use unique ID if possible + [STRID_INTERFACE] = "TinyUSB Network Interface", // Interface Description + [STRID_MAC] = NULL // STRID_MAC index is handled separately }; static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { - (void) langid; +const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void)langid; unsigned int chr_count = 0; - switch ( index ) { + switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; @@ -331,34 +330,40 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { case STRID_MAC: // Convert MAC address into UTF-16 - for (unsigned i=0; i> 4) & 0xf]; - _desc_str[1+chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 0) & 0xf]; + for (unsigned i = 0; i < sizeof(tud_network_mac_address); i++) { + _desc_str[1 + chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 4) & 0xf]; + _desc_str[1 + chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 0) & 0xf]; } break; - default: + default: { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + if (index >= sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) { + return NULL; + } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); - size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; + + const size_t max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type + if (chr_count > max_count) { + chr_count = max_count; + } // Convert ASCII string into UTF-16 - for ( size_t i = 0; i < chr_count; i++ ) { + for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; + } } // first byte is length (including header), second byte is string type - _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2)); + _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } diff --git a/hw/bsp/imxrt/family.cmake b/hw/bsp/imxrt/family.cmake index 100deba1f..11cc00983 100644 --- a/hw/bsp/imxrt/family.cmake +++ b/hw/bsp/imxrt/family.cmake @@ -56,10 +56,9 @@ function(family_add_board BOARD_TARGET) endif() endforeach() - target_compile_definitions(${BOARD_TARGET} PUBLIC __STARTUP_CLEAR_BSS - CFG_TUSB_MEM_SECTION=__attribute__\(\(section\(\"NonCacheable\"\)\)\) + [=[CFG_TUSB_MEM_SECTION=__attribute__((section("NonCacheable")))]=] ) if (NOT M4 STREQUAL "1") diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index 35e5fc923..a51b3f758 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -105,7 +105,9 @@ static bool __no_inline_not_in_flash_func(get_bootsel_button)(void) { IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); // Note we can't call into any sleep functions in flash right now - for (volatile int i = 0; i < 1000; ++i) {} + for (volatile int i = 0; i < 1000; ++i) { + __nop(); + } // The HI GPIO registers in SIO can observe and control the 6 QSPI pins. // Note the button pulls the pin *low* when pressed. diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 577a92a52..b3253b141 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -270,7 +270,7 @@ uint32_t tud_cdc_n_write_flush(uint8_t itf) { TU_VERIFY(tud_ready(), 0); // Skip if usb is not ready yet // No data to send - if (!tu_fifo_count(&p_cdc->tx_ff)) { + if (0 == tu_fifo_count(&p_cdc->tx_ff)) { return 0; } @@ -279,7 +279,7 @@ uint32_t tud_cdc_n_write_flush(uint8_t itf) { // Pull data from FIFO const uint16_t count = tu_fifo_read_n(&p_cdc->tx_ff, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE); - if (count) { + if (count > 0) { TU_ASSERT(usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_in, p_epbuf->epin, count), 0); return count; } else { @@ -337,15 +337,15 @@ bool cdcd_deinit(void) { #if OSAL_MUTEX_REQUIRED for(uint8_t i=0; irx_ff.mutex_rd; - osal_mutex_t mutex_wr = p_cdc->tx_ff.mutex_wr; + const osal_mutex_t mutex_rd = p_cdc->rx_ff.mutex_rd; + const osal_mutex_t mutex_wr = p_cdc->tx_ff.mutex_wr; - if (mutex_rd) { + if (mutex_rd != NULL) { osal_mutex_delete(mutex_rd); tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, NULL); } - if (mutex_wr) { + if (mutex_wr != NULL) { osal_mutex_delete(mutex_wr); tu_fifo_config_mutex(&p_cdc->tx_ff, NULL, NULL); } @@ -449,13 +449,15 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ } TU_VERIFY(itf < CFG_TUD_CDC); - switch (request->bRequest) { + switch (request->bRequest) { //-V2520 //-V2659 case CDC_REQUEST_SET_LINE_CODING: if (stage == CONTROL_STAGE_SETUP) { TU_LOG_DRV(" Set Line Coding\r\n"); tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); } else if (stage == CONTROL_STAGE_ACK) { tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); + } else { + // nothing to do } break; @@ -491,6 +493,8 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ // Invoke callback tud_cdc_line_state_cb(itf, dtr, rts); + } else { + // nothing to do } break; @@ -500,7 +504,10 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ } else if (stage == CONTROL_STAGE_ACK) { TU_LOG_DRV(" Send Break\r\n"); tud_cdc_send_break_cb(itf, request->wValue); + } else { + // nothing to do } + break; default: @@ -558,7 +565,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (0 == tud_cdc_n_write_flush(itf)) { // If there is no data left, a ZLP should be sent if // xferred_bytes is multiple of EP Packet size and not zero - if (!tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE - 1)))) { + if (0 == tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes > 0 && (0 == (xferred_bytes & (BULK_PACKET_SIZE - 1)))) { if (usbd_edpt_claim(rhport, p_cdc->ep_in)) { TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0)); } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index c321f3d16..f30f93bc6 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -53,15 +53,16 @@ // Driver Configuration //--------------------------------------------------------------------+ typedef struct TU_ATTR_PACKED { - uint8_t rx_persistent : 1; // keep rx fifo data even with bus reset or disconnect - uint8_t tx_persistent : 1; // keep tx fifo data even with reset or disconnect - uint8_t tx_overwritabe_if_not_connected : 1; // if not connected, tx fifo can be overwritten + bool rx_persistent : 1; // keep rx fifo data even with bus reset or disconnect + bool tx_persistent : 1; // keep tx fifo data even with reset or disconnect + bool tx_overwritabe_if_not_connected : 1; // if not connected, tx fifo can be overwritten } tud_cdc_configure_t; +TU_VERIFY_STATIC(sizeof(tud_cdc_configure_t) == 1, "size is not correct"); #define TUD_CDC_CONFIGURE_DEFAULT() { \ - .rx_persistent = 0, \ - .tx_persistent = 0, \ - .tx_overwritabe_if_not_connected = 1, \ + .rx_persistent = false, \ + .tx_persistent = false, \ + .tx_overwritabe_if_not_connected = false, \ } // Configure CDC driver behavior diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index b0eafd5da..4ba34c7dc 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -83,7 +83,7 @@ typedef struct { uint8_t add_sense_code; uint8_t add_sense_qualifier; - uint8_t pending_io; // pending async IO + bool pending_io; // pending async IO }mscd_interface_t; static mscd_interface_t _mscd_itf; @@ -92,6 +92,8 @@ CFG_TUD_MEM_SECTION static struct { TUD_EPBUF_DEF(buf, CFG_TUD_MSC_EP_BUFSIZE); } _mscd_epbuf; +TU_VERIFY_STATIC(CFG_TUD_MSC_EP_BUFSIZE >= 64, "CFG_TUD_MSC_EP_BUFSIZE must be at least 64"); + //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ @@ -107,16 +109,16 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_data_in(uint8_t dir) { return tu_bit_test(dir, 7); } -static inline bool send_csw(mscd_interface_t* p_msc) { +TU_ATTR_ALWAYS_INLINE static inline bool send_csw(mscd_interface_t* p_msc) { // Data residue is always = host expect - actual transferred uint8_t rhport = p_msc->rhport; p_msc->csw.data_residue = p_msc->cbw.total_bytes - p_msc->xferred_len; p_msc->stage = MSC_STAGE_STATUS_SENT; - memcpy(_mscd_epbuf.buf, &p_msc->csw, sizeof(msc_csw_t)); + memcpy(_mscd_epbuf.buf, (uint8_t*) &p_msc->csw, sizeof(msc_csw_t)); //-V1086 return usbd_edpt_xfer(rhport, p_msc->ep_in , _mscd_epbuf.buf, sizeof(msc_csw_t)); } -static inline bool prepare_cbw(mscd_interface_t* p_msc) { +TU_ATTR_ALWAYS_INLINE static inline bool prepare_cbw(mscd_interface_t* p_msc) { uint8_t rhport = p_msc->rhport; p_msc->stage = MSC_STAGE_CMD; return usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, sizeof(msc_cbw_t)); @@ -133,7 +135,7 @@ static void fail_scsi_op(mscd_interface_t* p_msc, uint8_t status) { // failed but sense key is not set: default to Illegal Request if (p_msc->sense_key == 0) { - tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + (void) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); } // If there is data stage and not yet complete, stall it @@ -146,18 +148,18 @@ static void fail_scsi_op(mscd_interface_t* p_msc, uint8_t status) { } } -static inline uint32_t rdwr10_get_lba(uint8_t const command[]) { +TU_ATTR_ALWAYS_INLINE static inline uint32_t rdwr10_get_lba(uint8_t const command[]) { // use offsetof to avoid pointer to the odd/unaligned address const uint32_t lba = tu_unaligned_read32(command + offsetof(scsi_write10_t, lba)); return tu_ntohl(lba); // lba is in Big Endian } -static inline uint16_t rdwr10_get_blockcount(msc_cbw_t const* cbw) { +TU_ATTR_ALWAYS_INLINE static inline uint16_t rdwr10_get_blockcount(msc_cbw_t const* cbw) { uint16_t const block_count = tu_unaligned_read16(cbw->command + offsetof(scsi_write10_t, block_count)); return tu_ntohs(block_count); } -static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw) { +TU_ATTR_ALWAYS_INLINE static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw) { // first extract block count in the command uint16_t const block_count = rdwr10_get_blockcount(cbw); if (block_count == 0) { @@ -171,7 +173,7 @@ static uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw) { uint16_t const block_count = rdwr10_get_blockcount(cbw); if (cbw->total_bytes == 0) { - if (block_count) { + if (block_count > 0) { TU_LOG_DRV(" SCSI case 2 (Hn < Di) or case 3 (Hn < Do) \r\n"); status = MSC_CSW_STATUS_PHASE_ERROR; } else { @@ -190,6 +192,8 @@ static uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw) { } else if (cbw->total_bytes / block_count == 0) { TU_LOG_DRV(" Computed block size = 0. SCSI case 7 Hi < Di (READ10) or case 13 Ho < Do (WRIT10)\r\n"); status = MSC_CSW_STATUS_PHASE_ERROR; + } else { + // nothing to do } } @@ -309,7 +313,7 @@ bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, u TU_ATTR_ALWAYS_INLINE static inline void set_sense_medium_not_present(uint8_t lun) { // default sense is NOT READY, MEDIUM NOT PRESENT - tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3A, 0x00); + (void) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3A, 0x00); } static void proc_async_io_done(void *bytes_io) { @@ -318,7 +322,7 @@ static void proc_async_io_done(void *bytes_io) { const int32_t nbytes = (int32_t) (intptr_t) bytes_io; const uint8_t cmd = p_msc->cbw.command[0]; - p_msc->pending_io = 0; + p_msc->pending_io = false; switch (cmd) { case SCSI_CMD_READ_10: proc_read_io_data(p_msc, nbytes); @@ -328,7 +332,7 @@ static void proc_async_io_done(void *bytes_io) { proc_write_io_data(p_msc, (uint32_t) nbytes, nbytes); break; - default: break; + default: break; // nothing to do } // send status if stage is transitioned to STATUS @@ -429,6 +433,8 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t TU_ASSERT(prepare_cbw(p_msc)); } } + } else { + // nothing to do } } @@ -438,7 +444,7 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t // From this point only handle class request only TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); - switch ( request->bRequest ) { + switch (request->bRequest) { //-V2520 //-V2659 case MSC_REQ_RESET: TU_LOG_DRV(" MSC BOT Reset\r\n"); TU_VERIFY(request->wValue == 0 && request->wLength == 0); @@ -451,7 +457,7 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t TU_VERIFY(request->wValue == 0 && request->wLength == 1); uint8_t maxlun = tud_msc_get_maxlun_cb(); - TU_VERIFY(maxlun); + TU_VERIFY(maxlun != 0); maxlun--; // MAX LUN is minus 1 by specs tud_control_xfer(rhport, request, &maxlun, 1); break; @@ -510,7 +516,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t if (status != MSC_CSW_STATUS_PASSED) { fail_scsi_op(p_msc, status); - } else if (p_cbw->total_bytes) { + } else if (p_cbw->total_bytes > 0) { if (SCSI_CMD_READ_10 == p_cbw->command[0]) { proc_read10_cmd(p_msc); } else { @@ -547,7 +553,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t TU_LOG_DRV(" SCSI unsupported or failed command\r\n"); fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED); } else if (resplen == 0) { - if (p_cbw->total_bytes) { + if (p_cbw->total_bytes > 0) { // 6.7 The 13 Cases: case 4 (Hi > Dn) // TU_LOG_DRV(" SCSI case 4 (Hi > Dn): %lu\r\n", p_cbw->total_bytes); fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED); @@ -647,7 +653,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } break; - default: break; + default: break; // nothing to do } if (p_msc->stage == MSC_STAGE_STATUS) { @@ -683,9 +689,8 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ } break; - case SCSI_CMD_START_STOP_UNIT: + case SCSI_CMD_START_STOP_UNIT: { resplen = 0; - scsi_start_stop_unit_t const* start_stop = (scsi_start_stop_unit_t const*)scsi_cmd; if (!tud_msc_start_stop_cb(lun, start_stop->power_condition, start_stop->start, start_stop->load_eject)) { // Failed status response @@ -697,10 +702,10 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ } } break; + } - case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: { resplen = 0; - scsi_prevent_allow_medium_removal_t const* prevent_allow = (scsi_prevent_allow_medium_removal_t const*)scsi_cmd; if (!tud_msc_prevent_allow_medium_removal_cb(lun, prevent_allow->prohibit_removal, prevent_allow->control)) { // Failed status response @@ -712,7 +717,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ } } break; - + } case SCSI_CMD_READ_CAPACITY_10: { uint32_t block_count; @@ -740,8 +745,8 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = sizeof(read_capa10); TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &read_capa10, (size_t) resplen)); } + break; } - break; case SCSI_CMD_READ_FORMAT_CAPACITY: { scsi_read_format_capacity_data_t read_fmt_capa = { @@ -772,8 +777,8 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = sizeof(read_fmt_capa); TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &read_fmt_capa, (size_t) resplen)); } + break; } - break; case SCSI_CMD_INQUIRY: { scsi_inquiry_resp_t *inquiry_rsp = (scsi_inquiry_resp_t *) buffer; @@ -789,8 +794,8 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ tud_msc_inquiry_cb(lun, inquiry_rsp->vendor_id, inquiry_rsp->product_id, inquiry_rsp->product_rev); resplen = sizeof(scsi_inquiry_resp_t); } + break; } - break; case SCSI_CMD_MODE_SENSE_6: { scsi_mode_sense6_resp_t mode_resp = { @@ -807,8 +812,8 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = sizeof(mode_resp); TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &mode_resp, (size_t) resplen)); + break; } - break; case SCSI_CMD_REQUEST_SENSE: { scsi_sense_fixed_resp_t sense_rsp = { @@ -828,9 +833,9 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = tud_msc_request_sense_cb(lun, buffer, (uint16_t)bufsize); // Clear sense data after copy - tud_msc_set_sense(lun, 0, 0, 0); + (void) tud_msc_set_sense(lun, 0, 0, 0); + break; } - break; default: resplen = -1; break; @@ -842,6 +847,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ static void proc_read10_cmd(mscd_interface_t* p_msc) { msc_cbw_t const* p_cbw = &p_msc->cbw; uint16_t const block_sz = rdwr10_get_blocksize(p_cbw); // already verified non-zero + TU_VERIFY(block_sz != 0, ); // Adjust lba & offset with transferred bytes uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); uint32_t const offset = p_msc->xferred_len % block_sz; @@ -849,10 +855,10 @@ static void proc_read10_cmd(mscd_interface_t* p_msc) { // remaining bytes capped at class buffer int32_t nbytes = (int32_t)tu_min32(CFG_TUD_MSC_EP_BUFSIZE, p_cbw->total_bytes - p_msc->xferred_len); - p_msc->pending_io = 1; + p_msc->pending_io = true; nbytes = tud_msc_read10_cb(p_cbw->lun, lba, offset, _mscd_epbuf.buf, (uint32_t)nbytes); if (nbytes != TUD_MSC_RET_ASYNC) { - p_msc->pending_io = 0; + p_msc->pending_io = false; proc_read_io_data(p_msc, nbytes); } } @@ -876,19 +882,19 @@ static void proc_read_io_data(mscd_interface_t* p_msc, int32_t nbytes) { dcd_event_xfer_complete(rhport, p_msc->ep_in, 0, XFER_RESULT_SUCCESS, false); break; - default: break; + default: break; // nothing to do } } } static void proc_write10_cmd(mscd_interface_t* p_msc) { msc_cbw_t const* p_cbw = &p_msc->cbw; - bool writable = tud_msc_is_writable_cb(p_cbw->lun); + const bool writable = tud_msc_is_writable_cb(p_cbw->lun); if (!writable) { // Not writable, complete this SCSI op with error // Sense = Write protected - tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_DATA_PROTECT, 0x27, 0x00); + (void) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_DATA_PROTECT, 0x27, 0x00); fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED); return; } @@ -903,15 +909,16 @@ static void proc_write10_cmd(mscd_interface_t* p_msc) { static void proc_write10_host_data(mscd_interface_t* p_msc, uint32_t xferred_bytes) { msc_cbw_t const* p_cbw = &p_msc->cbw; uint16_t const block_sz = rdwr10_get_blocksize(p_cbw); // already verified non-zero + TU_VERIFY(block_sz != 0, ); // Adjust lba & offset with transferred bytes uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); uint32_t const offset = p_msc->xferred_len % block_sz; - p_msc->pending_io = 1; + p_msc->pending_io = true; int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, offset, _mscd_epbuf.buf, xferred_bytes); if (nbytes != TUD_MSC_RET_ASYNC) { - p_msc->pending_io = 0; + p_msc->pending_io = false; proc_write_io_data(p_msc, xferred_bytes, nbytes); } } @@ -927,7 +934,7 @@ static void proc_write_io_data(mscd_interface_t* p_msc, uint32_t xferred_bytes, fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED); break; - default: break; + default: break; // nothing to do } } else { if ((uint32_t)nbytes < xferred_bytes) { diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index eb69ae400..5aa27c196 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -191,7 +191,7 @@ bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* respons .cmd_code = SCSI_CMD_INQUIRY, .alloc_length = sizeof(scsi_inquiry_resp_t) }; - memcpy(cbw.command, &cmd_inquiry, cbw.cmd_len); + memcpy(cbw.command, &cmd_inquiry, cbw.cmd_len); //-V1086 return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg); } @@ -225,7 +225,7 @@ bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void* response, .cmd_code = SCSI_CMD_REQUEST_SENSE, .alloc_length = 18 }; - memcpy(cbw.command, &cmd_request_sense, cbw.cmd_len); + memcpy(cbw.command, &cmd_request_sense, cbw.cmd_len); //-V1086 return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg); } @@ -247,7 +247,7 @@ bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void* buffer, uint32_t lba, u .lba = tu_htonl(lba), .block_count = tu_htons(block_count) }; - memcpy(cbw.command, &cmd_read10, cbw.cmd_len); + memcpy(cbw.command, &cmd_read10, cbw.cmd_len); //-V1086 return tuh_msc_scsi_command(dev_addr, &cbw, buffer, complete_cb, arg); } @@ -269,7 +269,7 @@ bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const* buffer, uint32_t .lba = tu_htonl(lba), .block_count = tu_htons(block_count) }; - memcpy(cbw.command, &cmd_write10, cbw.cmd_len); + memcpy(cbw.command, &cmd_write10, cbw.cmd_len); //-V1086 return tuh_msc_scsi_command(dev_addr, &cbw, (void*) (uintptr_t) buffer, complete_cb, arg); } diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index a7bf3e959..905dc239c 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -61,9 +61,9 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); TU_ATTR_ALWAYS_INLINE static inline void tu_print_buf(uint8_t const* buf, uint32_t bufsize) { for(uint32_t i=0; i= 2 diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h index ace5907d7..f5385071a 100644 --- a/src/osal/osal_pico.h +++ b/src/osal/osal_pico.h @@ -81,8 +81,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; - sem_release(sem_hdl); - return true; + return sem_release(sem_hdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { @@ -139,7 +138,7 @@ typedef osal_queue_def_t* osal_queue_t; TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { critical_section_init(&qdef->critsec); - tu_fifo_clear(&qdef->ff); + (void) tu_fifo_clear(&qdef->ff); return (osal_queue_t) qdef; } -- cgit v1.3.1 From f11adb02ebc0c594a7114b08585b8af18c3ee6d6 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 12 Nov 2025 21:22:25 +0700 Subject: migrate cdc device to use edpt stream API tu_edpt_stream_open() does not clear fifo, allow for persistent stream when disconnect/reconnect --- .clang-format | 7 +- .../net_lwip_webserver/src/usb_descriptors.c | 2 +- src/class/cdc/cdc_device.c | 393 +++++++++------------ src/class/midi/midi_device.c | 2 + src/class/vendor/vendor_device.c | 16 +- src/common/tusb_private.h | 7 +- src/tusb.c | 8 +- 7 files changed, 194 insertions(+), 241 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/.clang-format b/.clang-format index c278fec37..40d40f7e9 100644 --- a/.clang-format +++ b/.clang-format @@ -1,7 +1,7 @@ --- Language: Cpp BasedOnStyle: LLVM -AlignAfterOpenBracket: AlwaysBreak +AlignAfterOpenBracket: Align AlignConsecutiveAssignments: Enabled: true AcrossEmptyLines: false @@ -38,6 +38,7 @@ AllowShortEnumsOnASingleLine: false AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: Never AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true BreakBeforeBraces: Custom BraceWrapping: AfterCaseLabel: false @@ -57,8 +58,10 @@ BraceWrapping: SplitEmptyRecord: true SplitEmptyNamespace: true BracedInitializerIndentWidth: 2 +BreakBeforeBinaryOperators: None BreakConstructorInitializers: AfterColon BreakConstructorInitializersBeforeComma: false +ContinuationIndentWidth: 2 ColumnLimit: 120 ConstructorInitializerAllOnOneLineOrOnePerLine: false Cpp11BracedListStyle: true @@ -78,6 +81,8 @@ MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 2 NamespaceIndentation: All +PenaltyBreakBeforeFirstCallParameter: 1000000 +PenaltyBreakOpenParenthesis: 1000000 QualifierAlignment: Custom QualifierOrder: ['static', 'const', 'volatile', 'restrict', 'type'] ReflowComments: false diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index b49962d65..c976cb62b 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -270,7 +270,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_contro switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_VENDOR: - switch (request->bRequest) { //-V2520 //-V2659 + switch (request->bRequest) { case 1: if (request->wIndex == 7) { // Get Microsoft OS 2.0 compatible descriptor diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index b3253b141..92139b14e 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -48,28 +48,23 @@ typedef struct { uint8_t rhport; uint8_t itf_num; - uint8_t ep_in; - uint8_t ep_out; - uint8_t ep_notify; uint8_t line_state; // Bit 0: DTR, Bit 1: RTS /*------------- From this point, data is not cleared by bus reset -------------*/ - char wanted_char; TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; + char wanted_char; - // FIFO - tu_fifo_t rx_ff; - tu_fifo_t tx_ff; - - uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE]; - uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE]; + struct { + tu_edpt_stream_t tx; + tu_edpt_stream_t rx; - OSAL_MUTEX_DEF(rx_ff_mutex); - OSAL_MUTEX_DEF(tx_ff_mutex); + uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE]; + uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE]; + } stream; } cdcd_interface_t; -#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char) +#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) typedef struct { TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE); @@ -80,111 +75,102 @@ typedef struct { #endif } cdcd_epbuf_t; -//--------------------------------------------------------------------+ -// INTERNAL OBJECT & FUNCTION DECLARATION -//--------------------------------------------------------------------+ -static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; -CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; - -static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT(); - -static bool _prep_out_transaction(uint8_t itf) { - const uint8_t rhport = 0; - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; - - // Skip if usb is not ready yet - TU_VERIFY(tud_ready() && p_cdc->ep_out); - - uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); - - // Prepare for incoming data but only allow what we can store in the ring buffer. - // TODO Actually we can still carry out the transfer, keeping count of received bytes - // and slowly move it to the FIFO when read(). - // This pre-check reduces endpoint claiming - TU_VERIFY(available >= CFG_TUD_CDC_EP_BUFSIZE); - - // claim endpoint - TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_out)); - - // fifo can be changed before endpoint is claimed - available = tu_fifo_remaining(&p_cdc->rx_ff); - - if (available >= CFG_TUD_CDC_EP_BUFSIZE) { - return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_epbuf->epout, CFG_TUD_CDC_EP_BUFSIZE); - } else { - // Release endpoint since we don't make any transfer - usbd_edpt_release(p_cdc->rhport, p_cdc->ep_out); - return false; - } -} - //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf) { - (void) itf; + (void)itf; } TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { - (void) itf; - (void) wanted_char; + (void)itf; + (void)wanted_char; } TU_ATTR_WEAK void tud_cdc_tx_complete_cb(uint8_t itf) { - (void) itf; + (void)itf; } TU_ATTR_WEAK void tud_cdc_notify_complete_cb(uint8_t itf) { - (void) itf; + (void)itf; } TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { - (void) itf; - (void) dtr; - (void) rts; + (void)itf; + (void)dtr; + (void)rts; } -TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding) { - (void) itf; - (void) p_line_coding; +TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, const cdc_line_coding_t *p_line_coding) { + (void)itf; + (void)p_line_coding; } TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) { - (void) itf; - (void) duration_ms; + (void)itf; + (void)duration_ms; +} + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; +CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; +static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT(); + +TU_ATTR_ALWAYS_INLINE static inline uint8_t find_cdc_itf(uint8_t ep_addr) { + for (uint8_t idx = 0; idx < CFG_TUD_CDC; idx++) { + const cdcd_interface_t *p_cdc = &_cdcd_itf[idx]; + if (ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr || + (ep_addr == p_cdc->ep_notify && ep_addr != 0)) { + return idx; + } + } + return TUSB_INDEX_INVALID_8; } //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg) { - TU_VERIFY(driver_cfg); + TU_VERIFY(driver_cfg != NULL); _cdcd_cfg = *driver_cfg; return true; } bool tud_cdc_n_ready(uint8_t itf) { - return tud_ready() && _cdcd_itf[itf].ep_in != 0 && _cdcd_itf[itf].ep_out != 0; + TU_VERIFY(itf < CFG_TUD_CDC); + TU_VERIFY(tud_ready()); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + + const bool in_opened = tu_edpt_stream_is_opened(&p_cdc->stream.tx); + const bool out_opened = tu_edpt_stream_is_opened(&p_cdc->stream.rx); + return in_opened && out_opened; } bool tud_cdc_n_connected(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_CDC); + TU_VERIFY(tud_ready()); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; // DTR (bit 0) active is considered as connected - return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0); + return tu_bit_test(p_cdc->line_state, 0); } uint8_t tud_cdc_n_get_line_state(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_CDC, 0); return _cdcd_itf[itf].line_state; } -void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding) { +void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t *coding) { + TU_VERIFY(itf < CFG_TUD_CDC, ); (*coding) = _cdcd_itf[itf].line_coding; } #if CFG_TUD_CDC_NOTIFY bool tud_cdc_n_notify_uart_state (uint8_t itf, const cdc_notify_uart_state_t *state) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; + TU_VERIFY(itf < CFG_TUD_CDC); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[itf]; TU_VERIFY(tud_ready() && p_cdc->ep_notify != 0); TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_notify)); @@ -200,8 +186,9 @@ bool tud_cdc_n_notify_uart_state (uint8_t itf, const cdc_notify_uart_state_t *st } bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed_change_t* conn_speed_change) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; + TU_VERIFY(itf < CFG_TUD_CDC); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[itf]; TU_VERIFY(tud_ready() && p_cdc->ep_notify != 0); TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_notify)); @@ -218,6 +205,7 @@ bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed #endif void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { + TU_VERIFY(itf < CFG_TUD_CDC, ); _cdcd_itf[itf].wanted_char = wanted; } @@ -225,77 +213,55 @@ void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { // READ API //--------------------------------------------------------------------+ uint32_t tud_cdc_n_available(uint8_t itf) { - return tu_fifo_count(&_cdcd_itf[itf].rx_ff); + TU_VERIFY(itf < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_read_available(&p_cdc->stream.rx); } uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(itf); - return num_read; + TU_VERIFY(itf < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_read(p_cdc->rhport, &p_cdc->stream.rx, buffer, bufsize); } -bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { - return tu_fifo_peek(&_cdcd_itf[itf].rx_ff, chr); +bool tud_cdc_n_peek(uint8_t itf, uint8_t *chr) { + TU_VERIFY(itf < CFG_TUD_CDC); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_peek(&p_cdc->stream.rx, chr); } void tud_cdc_n_read_flush(uint8_t itf) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - tu_fifo_clear(&p_cdc->rx_ff); - _prep_out_transaction(itf); + TU_VERIFY(itf < CFG_TUD_CDC, ); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + tu_edpt_stream_clear(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(p_cdc->rhport, &p_cdc->stream.rx); } //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint16_t wr_count = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - - // flush if queue more than packet size - if (tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE - #if CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE - || tu_fifo_full(&p_cdc->tx_ff) // check full if fifo size is less than packet size - #endif - ) { - tud_cdc_n_write_flush(itf); - } - - return wr_count; + TU_VERIFY(itf < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_write(p_cdc->rhport, &p_cdc->stream.tx, buffer, bufsize); } uint32_t tud_cdc_n_write_flush(uint8_t itf) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; - TU_VERIFY(tud_ready(), 0); // Skip if usb is not ready yet - - // No data to send - if (0 == tu_fifo_count(&p_cdc->tx_ff)) { - return 0; - } - - TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_in), 0); // Claim the endpoint - - // Pull data from FIFO - const uint16_t count = tu_fifo_read_n(&p_cdc->tx_ff, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE); - - if (count > 0) { - TU_ASSERT(usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_in, p_epbuf->epin, count), 0); - return count; - } else { - // Release endpoint since we don't make any transfer - // Note: data is dropped if terminal is not connected - usbd_edpt_release(p_cdc->rhport, p_cdc->ep_in); - return 0; - } + TU_VERIFY(itf < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_write_xfer(p_cdc->rhport, &p_cdc->stream.tx); } uint32_t tud_cdc_n_write_available(uint8_t itf) { - return tu_fifo_remaining(&_cdcd_itf[itf].tx_ff); + TU_VERIFY(itf < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_write_available(p_cdc->rhport, &p_cdc->stream.tx); } bool tud_cdc_n_write_clear(uint8_t itf) { - return tu_fifo_clear(&_cdcd_itf[itf].tx_ff); + TU_VERIFY(itf < CFG_TUD_CDC); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_clear(&p_cdc->stream.tx); } //--------------------------------------------------------------------+ @@ -304,7 +270,8 @@ bool tud_cdc_n_write_clear(uint8_t itf) { void cdcd_init(void) { tu_memclr(_cdcd_itf, sizeof(_cdcd_itf)); for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { - cdcd_interface_t* p_cdc = &_cdcd_itf[i]; + cdcd_interface_t *p_cdc = &_cdcd_itf[i]; + cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[i]; p_cdc->wanted_char = (char) -1; @@ -314,44 +281,23 @@ void cdcd_init(void) { p_cdc->line_coding.parity = 0; p_cdc->line_coding.data_bits = 8; - // Config RX fifo - tu_fifo_config(&p_cdc->rx_ff, p_cdc->rx_ff_buf, TU_ARRAY_SIZE(p_cdc->rx_ff_buf), 1, false); + tu_edpt_stream_init(&p_cdc->stream.rx, false, false, false, p_cdc->stream.rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, + p_epbuf->epout, CFG_TUD_CDC_EP_BUFSIZE); // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not // know if data is actually polled by terminal. This way the most current data is prioritized. // Default: is overwritable - tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, _cdcd_cfg.tx_overwritabe_if_not_connected); - - #if OSAL_MUTEX_REQUIRED - osal_mutex_t mutex_rd = osal_mutex_create(&p_cdc->rx_ff_mutex); - osal_mutex_t mutex_wr = osal_mutex_create(&p_cdc->tx_ff_mutex); - TU_ASSERT(mutex_rd != NULL && mutex_wr != NULL, ); - - tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, mutex_rd); - tu_fifo_config_mutex(&p_cdc->tx_ff, mutex_wr, NULL); - #endif + tu_edpt_stream_init(&p_cdc->stream.tx, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, + p_cdc->stream.tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE); } } bool cdcd_deinit(void) { - #if OSAL_MUTEX_REQUIRED for(uint8_t i=0; irx_ff.mutex_rd; - const osal_mutex_t mutex_wr = p_cdc->tx_ff.mutex_wr; - - if (mutex_rd != NULL) { - osal_mutex_delete(mutex_rd); - tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, NULL); - } - - if (mutex_wr != NULL) { - osal_mutex_delete(mutex_wr); - tu_fifo_config_mutex(&p_cdc->tx_ff, NULL, NULL); - } + tu_edpt_stream_deinit(&p_cdc->stream.rx); + tu_edpt_stream_deinit(&p_cdc->stream.tx); } - #endif - return true; } @@ -360,74 +306,85 @@ void cdcd_reset(uint8_t rhport) { for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { cdcd_interface_t* p_cdc = &_cdcd_itf[i]; - tu_memclr(p_cdc, ITF_MEM_RESET_SIZE); - if (!_cdcd_cfg.rx_persistent) { - tu_fifo_clear(&p_cdc->rx_ff); - } - if (!_cdcd_cfg.tx_persistent) { - tu_fifo_clear(&p_cdc->tx_ff); - } - tu_fifo_set_overwritable(&p_cdc->tx_ff, _cdcd_cfg.tx_overwritabe_if_not_connected); + + tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, _cdcd_cfg.tx_overwritabe_if_not_connected); // // back to default + tu_edpt_stream_close(&p_cdc->stream.rx); + tu_edpt_stream_close(&p_cdc->stream.tx); } } uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16_t max_len) { // Only support ACM subclass - TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && - CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0); + TU_VERIFY(TUSB_CLASS_CDC == itf_desc->bInterfaceClass && + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, + 0); - // Find available interface - cdcd_interface_t* p_cdc; - uint8_t cdc_id; - for (cdc_id = 0; cdc_id < CFG_TUD_CDC; cdc_id++) { - p_cdc = &_cdcd_itf[cdc_id]; - if (p_cdc->ep_in == 0) { - break; - } - } + const uint8_t cdc_id = find_cdc_itf(0); // Find available interface TU_ASSERT(cdc_id < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[cdc_id]; //------------- Control Interface -------------// p_cdc->rhport = rhport; p_cdc->itf_num = itf_desc->bInterfaceNumber; - uint16_t drv_len = sizeof(tusb_desc_interface_t); - const uint8_t* p_desc = tu_desc_next(itf_desc); + const uint8_t *p_desc = (const uint8_t *)itf_desc; + const uint8_t *desc_end = p_desc + max_len; - // Communication Functional Descriptors - while (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len) { - drv_len += tu_desc_len(p_desc); + // Skip all class-specific descriptor + p_desc = tu_desc_next(itf_desc); + while (tu_desc_in_bounds(p_desc, desc_end) && TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) { p_desc = tu_desc_next(p_desc); } + // notification endpoint (optional) if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { - // notification endpoint const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); p_cdc->ep_notify = desc_ep->bEndpointAddress; - drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } - //------------- Data Interface (if any) -------------// - if ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && - (TUSB_CLASS_CDC_DATA == ((const tusb_desc_interface_t*) p_desc)->bInterfaceClass)) { - // next to endpoint descriptor - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + //------------- Data Interface (optional) -------------// + if (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) { + const tusb_desc_interface_t *data_itf_desc = (const tusb_desc_interface_t *)p_desc; + if (TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass) { + for (uint8_t e = 0; e < data_itf_desc->bNumEndpoints; e++) { + if (!tu_desc_in_bounds(p_desc, desc_end)) { + break; + } + p_desc = tu_desc_next(p_desc); - // Open endpoint pair - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in), 0); + const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer, 0); - drv_len += 2 * sizeof(tusb_desc_endpoint_t); - } + TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { + tu_edpt_stream_t *stream_tx = &p_cdc->stream.tx; + tu_edpt_stream_open(stream_tx, desc_ep); + + if (_cdcd_cfg.tx_persistent) { + tu_edpt_stream_write_xfer(rhport, stream_tx); // flush pending data + } else { + tu_edpt_stream_clear(stream_tx); + } + } else { + tu_edpt_stream_t *stream_rx = &p_cdc->stream.rx; - // Prepare for incoming data - _prep_out_transaction(cdc_id); + tu_edpt_stream_open(stream_rx, desc_ep); + if (!_cdcd_cfg.rx_persistent) { + tu_edpt_stream_clear(stream_rx); + } + TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare for incoming data + } + } - return drv_len; + p_desc = tu_desc_next(p_desc); + } + } + + return p_desc - (const uint8_t *)itf_desc; } // Invoked when a control transfer occurred on an interface of this class @@ -449,7 +406,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ } TU_VERIFY(itf < CFG_TUD_CDC); - switch (request->bRequest) { //-V2520 //-V2659 + switch (request->bRequest) { case CDC_REQUEST_SET_LINE_CODING: if (stage == CONTROL_STAGE_SETUP) { TU_LOG_DRV(" Set Line Coding\r\n"); @@ -484,15 +441,13 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ // If enabled: fifo overwriting is disabled if DTR bit is set and vice versa if (_cdcd_cfg.tx_overwritabe_if_not_connected) { - tu_fifo_set_overwritable(&p_cdc->tx_ff, !dtr); + tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, !dtr); } else { - tu_fifo_set_overwritable(&p_cdc->tx_ff, false); + tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, false); } TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); - - // Invoke callback - tud_cdc_line_state_cb(itf, dtr, rts); + tud_cdc_line_state_cb(itf, dtr, rts); // invoke callback } else { // nothing to do } @@ -507,7 +462,6 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ } else { // nothing to do } - break; default: @@ -518,58 +472,45 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ } bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) result; + (void)result; - uint8_t itf; - cdcd_interface_t* p_cdc; - - // Identify which interface to use - for (itf = 0; itf < CFG_TUD_CDC; itf++) { - p_cdc = &_cdcd_itf[itf]; - if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in) || (ep_addr == p_cdc->ep_notify)) { - break; - } - } + uint8_t itf = find_cdc_itf(ep_addr); TU_ASSERT(itf < CFG_TUD_CDC); - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + tu_edpt_stream_t *stream_rx = &p_cdc->stream.rx; + tu_edpt_stream_t *stream_tx = &p_cdc->stream.tx; - // Received new data - if (ep_addr == p_cdc->ep_out) { - tu_fifo_write_n(&p_cdc->rx_ff, p_epbuf->epout, (uint16_t) xferred_bytes); + // Received new data, move to fifo + if (ep_addr == stream_rx->ep_addr) { + tu_edpt_stream_read_xfer_complete(stream_rx, xferred_bytes); - // Check for wanted char and invoke callback if needed - if (((signed char) p_cdc->wanted_char) != -1) { + // Check for wanted char and invoke wanted callback (multiple times if multiple wanted received) + if (((signed char)p_cdc->wanted_char) != -1) { for (uint32_t i = 0; i < xferred_bytes; i++) { - if ((p_cdc->wanted_char == (char) p_epbuf->epout[i]) && !tu_fifo_empty(&p_cdc->rx_ff)) { + if ((p_cdc->wanted_char == (char)stream_rx->ep_buf[i]) && !tu_edpt_stream_empty(stream_rx)) { tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); } } } - // invoke receive callback (if there is still data) - if (!tu_fifo_empty(&p_cdc->rx_ff)) { + // invoke receive callback if there is still data + if (!tu_edpt_stream_empty(stream_rx)) { tud_cdc_rx_cb(itf); } - // prepare for OUT transaction - _prep_out_transaction(itf); + tu_edpt_stream_read_xfer(rhport, stream_rx); // prepare for more data } // 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 !!! - if (ep_addr == p_cdc->ep_in) { + if (ep_addr == stream_tx->ep_addr) { // invoke transmit callback to possibly refill tx fifo tud_cdc_tx_complete_cb(itf); - if (0 == tud_cdc_n_write_flush(itf)) { - // If there is no data left, a ZLP should be sent if - // xferred_bytes is multiple of EP Packet size and not zero - if (0 == tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes > 0 && (0 == (xferred_bytes & (BULK_PACKET_SIZE - 1)))) { - if (usbd_edpt_claim(rhport, p_cdc->ep_in)) { - TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0)); - } - } + if (0 == tu_edpt_stream_write_xfer(rhport, stream_tx)) { + // If there is no data left, a ZLP should be sent if needed + tu_edpt_stream_write_zlp_if_needed(rhport, stream_tx, xferred_bytes); } } diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index f065e486a..79e7dfa71 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -405,8 +405,10 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint1 if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { tu_edpt_stream_open(&p_midi->ep_stream.tx, desc_ep); + tu_edpt_stream_clear(&p_midi->ep_stream.tx); } else { tu_edpt_stream_open(&p_midi->ep_stream.rx, desc_ep); + tu_edpt_stream_clear(&p_midi->ep_stream.rx); TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_midi->ep_stream.rx) > 0, 0); // prepare to receive data } diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index c916ebe47..7da4d2239 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -234,16 +234,18 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uin const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); - // open endpoint stream, skip if already opened + // open endpoint stream, skip if already opened (multiple IN/OUT endpoints) if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - if (p_vendor->tx.stream.ep_addr == 0) { - tu_edpt_stream_open(&p_vendor->tx.stream, desc_ep); - tud_vendor_n_write_flush(itf); + tu_edpt_stream_t *stream_tx = &p_vendor->tx.stream; + 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 { - if (p_vendor->rx.stream.ep_addr == 0) { - 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 + tu_edpt_stream_t *stream_rx = &p_vendor->rx.stream; + if (stream_rx->ep_addr == 0) { + tu_edpt_stream_open(stream_rx, desc_ep); + TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare for incoming data } } } diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 367209e57..f82f87b6f 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -100,7 +100,6 @@ bool tu_edpt_stream_deinit(tu_edpt_stream_t* s); // Open an stream for an endpoint TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { - tu_fifo_clear(&s->ff); s->ep_addr = desc_ep->bEndpointAddress; s->is_mps512 = tu_edpt_packet_size(desc_ep) == 512; } @@ -113,11 +112,15 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_close(tu_edpt_stream_t* s->ep_addr = 0; } -// Clear fifo TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_clear(tu_edpt_stream_t* s) { return tu_fifo_clear(&s->ff); } +TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_empty(tu_edpt_stream_t *s) { + return tu_fifo_empty(&s->ff); +} + + //--------------------------------------------------------------------+ // Stream Write //--------------------------------------------------------------------+ diff --git a/src/tusb.c b/src/tusb.c index b308e2915..df33f2680 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -354,8 +354,8 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove return true; } -bool tu_edpt_stream_deinit(tu_edpt_stream_t* s) { - (void) s; +bool tu_edpt_stream_deinit(tu_edpt_stream_t *s) { + (void)s; #if OSAL_MUTEX_REQUIRED if (s->ff.mutex_wr) { osal_mutex_delete(s->ff.mutex_wr); @@ -363,7 +363,7 @@ bool tu_edpt_stream_deinit(tu_edpt_stream_t* s) { if (s->ff.mutex_rd) { osal_mutex_delete(s->ff.mutex_rd); } -#endif + #endif return true; } @@ -412,7 +412,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_release(uint8_t hwid, tu_edpt_st bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { // ZLP condition: no pending data, last transferred bytes is multiple of packet size const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; - TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes > 0 && (0 == (last_xferred_bytes & (mps - 1)))); + TU_VERIFY(tu_fifo_empty(&s->ff) && last_xferred_bytes > 0 && (0 == (last_xferred_bytes & (mps - 1)))); TU_VERIFY(stream_claim(hwid, s)); TU_ASSERT(stream_xfer(hwid, s, 0)); return true; -- cgit v1.3.1 From 397a3af8afc4bc5460572da4a40629684dfa788c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 13 Nov 2025 12:02:02 +0700 Subject: clear endpoint stream when open for cdc_host and midi_host --- src/class/cdc/cdc_device.c | 15 ++++++------- src/class/cdc/cdc_host.c | 50 ++++++++++++++++++-------------------------- src/class/midi/midi_device.c | 14 +++++++------ src/class/midi/midi_host.c | 48 ++++++++++++++++++++++-------------------- src/common/tusb_common.h | 2 +- src/common/tusb_private.h | 1 - src/tusb.c | 2 +- 7 files changed, 61 insertions(+), 71 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 92139b14e..80fa81d99 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -141,7 +141,7 @@ bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg) { bool tud_cdc_n_ready(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC); TU_VERIFY(tud_ready()); - cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + const cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; const bool in_opened = tu_edpt_stream_is_opened(&p_cdc->stream.tx); const bool out_opened = tu_edpt_stream_is_opened(&p_cdc->stream.rx); @@ -151,9 +151,8 @@ bool tud_cdc_n_ready(uint8_t itf) { bool tud_cdc_n_connected(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC); TU_VERIFY(tud_ready()); - cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; // DTR (bit 0) active is considered as connected - return tu_bit_test(p_cdc->line_state, 0); + return tu_bit_test(_cdcd_itf[itf].line_state, 0); } uint8_t tud_cdc_n_get_line_state(uint8_t itf) { @@ -214,8 +213,7 @@ void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { //--------------------------------------------------------------------+ uint32_t tud_cdc_n_available(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); - cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_read_available(&p_cdc->stream.rx); + return tu_edpt_stream_read_available(&_cdcd_itf[itf].stream.rx); } uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { @@ -226,8 +224,7 @@ uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { bool tud_cdc_n_peek(uint8_t itf, uint8_t *chr) { TU_VERIFY(itf < CFG_TUD_CDC); - cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_peek(&p_cdc->stream.rx, chr); + return tu_edpt_stream_peek(&_cdcd_itf[itf].stream.rx, chr); } void tud_cdc_n_read_flush(uint8_t itf) { @@ -362,8 +359,8 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_cdc->stream.tx; - tu_edpt_stream_open(stream_tx, desc_ep); + tu_edpt_stream_open(stream_tx, desc_ep); if (_cdcd_cfg.tx_persistent) { tu_edpt_stream_write_xfer(rhport, stream_tx); // flush pending data } else { @@ -384,7 +381,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 } } - return p_desc - (const uint8_t *)itf_desc; + return (uint16_t)(p_desc - (const uint8_t *)itf_desc); } // Invoked when a control transfer occurred on an interface of this class diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 7fdf0a7b9..35717ddf6 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -298,6 +298,7 @@ TU_VERIFY_STATIC(TU_ARRAY_SIZE(serial_drivers) == SERIAL_DRIVER_COUNT, "Serial d //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ +static bool open_ep_stream_pair(cdch_interface_t *p_cdc, const tusb_desc_endpoint_t *desc_ep); TU_ATTR_ALWAYS_INLINE static inline cdch_interface_t * get_itf(uint8_t idx) { TU_ASSERT(idx < CFG_TUH_CDC, NULL); @@ -364,7 +365,7 @@ static cdch_interface_t* get_itf_by_xfer(const tuh_xfer_t * xfer) { #endif default: - break; + break; // unknown driver } } } @@ -389,8 +390,6 @@ static cdch_interface_t * make_new_itf(uint8_t daddr, tusb_desc_interface_t cons return NULL; } -static bool open_ep_stream_pair(cdch_interface_t * p_cdc , tusb_desc_endpoint_t const *desc_ep); - //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ @@ -519,7 +518,7 @@ bool tuh_cdc_read_clear (uint8_t idx) { TU_VERIFY(p_cdc); bool ret = tu_edpt_stream_clear(&p_cdc->stream.rx); - tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); + (void)tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); return ret; } @@ -648,13 +647,10 @@ bool cdch_init(void) { for (size_t i = 0; i < CFG_TUH_CDC; i++) { cdch_interface_t *p_cdc = &cdch_data[i]; cdch_epbuf_t *epbuf = &cdch_epbuf[i]; - tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, - p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, - epbuf->tx, CFG_TUH_CDC_TX_EPSIZE); - - tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, - p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, - epbuf->rx, CFG_TUH_CDC_RX_EPSIZE); + TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, + epbuf->tx, CFG_TUH_CDC_TX_EPSIZE)); + TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, p_cdc->stream.rx_ff_buf, + CFG_TUH_CDC_RX_BUFSIZE, epbuf->rx, CFG_TUH_CDC_RX_EPSIZE)); } return true; @@ -663,8 +659,8 @@ bool cdch_init(void) { bool cdch_deinit(void) { for (size_t i = 0; i < CFG_TUH_CDC; i++) { cdch_interface_t *p_cdc = &cdch_data[i]; - tu_edpt_stream_deinit(&p_cdc->stream.tx); - tu_edpt_stream_deinit(&p_cdc->stream.rx); + (void)tu_edpt_stream_deinit(&p_cdc->stream.tx); + (void)tu_edpt_stream_deinit(&p_cdc->stream.rx); } return true; } @@ -674,11 +670,9 @@ void cdch_close(uint8_t daddr) { cdch_interface_t *p_cdc = &cdch_data[idx]; if (p_cdc->daddr == daddr) { TU_LOG_CDC(p_cdc, "close"); + tuh_cdc_umount_cb(idx); // invoke callback - // Invoke application callback - tuh_cdc_umount_cb(idx); - - p_cdc->daddr = 0; + p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; p_cdc->mounted = false; tu_edpt_stream_close(&p_cdc->stream.tx); @@ -696,13 +690,12 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t TU_ASSERT(p_cdc); if (ep_addr == p_cdc->stream.tx.ep_addr) { - // invoke tx complete callback to possibly refill tx fifo - tuh_cdc_tx_complete_cb(idx); + tuh_cdc_tx_complete_cb(idx); // invoke transmit complete callback if (0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->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(daddr, &p_cdc->stream.tx, xferred_bytes); + (void)tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes); } } else if (ep_addr == p_cdc->stream.rx.ep_addr) { #if CFG_TUH_CDC_FTDI @@ -718,7 +711,6 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t #endif { tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes); - tuh_cdc_rx_cb(idx); // invoke receive callback } @@ -727,7 +719,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t } else if (ep_addr == p_cdc->ep_notif) { // TODO handle notification endpoint } else { - TU_ASSERT(false); + return false; } return true; @@ -736,20 +728,17 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t //--------------------------------------------------------------------+ // Enumeration //--------------------------------------------------------------------+ - static bool open_ep_stream_pair(cdch_interface_t *p_cdc, tusb_desc_endpoint_t const *desc_ep) { for (size_t i = 0; i < 2; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); + tu_edpt_stream_t *stream = + (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) ? &p_cdc->stream.rx : &p_cdc->stream.tx; + tu_edpt_stream_open(stream, desc_ep); + tu_edpt_stream_clear(stream); - if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_cdc->stream.rx, desc_ep); - } else { - tu_edpt_stream_open(&p_cdc->stream.tx, desc_ep); - } - - desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(desc_ep); + desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_ep); } return true; @@ -832,6 +821,7 @@ static void cdch_process_set_config(tuh_xfer_t *xfer) { } } +// return false if there is no active transfer static bool set_line_state_on_enum(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { enum { ENUM_SET_LINE_CODING = 0, diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 79e7dfa71..b20903d68 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -404,15 +404,17 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint1 const uint8_t ep_addr = ((const tusb_desc_endpoint_t *)p_desc)->bEndpointAddress; if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_midi->ep_stream.tx, desc_ep); - tu_edpt_stream_clear(&p_midi->ep_stream.tx); + tu_edpt_stream_t *stream_tx = &p_midi->ep_stream.tx; + tu_edpt_stream_open(stream_tx, desc_ep); + tu_edpt_stream_clear(stream_tx); } else { - tu_edpt_stream_open(&p_midi->ep_stream.rx, desc_ep); - tu_edpt_stream_clear(&p_midi->ep_stream.rx); - TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_midi->ep_stream.rx) > 0, 0); // prepare to receive data + tu_edpt_stream_t *stream_rx = &p_midi->ep_stream.rx; + tu_edpt_stream_open(stream_rx, desc_ep); + tu_edpt_stream_clear(stream_rx); + TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare to receive data } - p_desc = tu_desc_next(p_desc); // skip CS Endpoint descriptor + p_desc = tu_desc_next(p_desc); // skip CS Endpoint descriptor found_ep++; } diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index 8b78fe945..07062875c 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -59,9 +59,6 @@ typedef struct { uint8_t iInterface; uint8_t itf_count; // number of interface including Audio Control + MIDI streaming - uint8_t ep_in; // IN endpoint address - uint8_t ep_out; // OUT endpoint address - uint8_t rx_cable_count; // IN endpoint CS descriptor bNumEmbMIDIJack value uint8_t tx_cable_count; // OUT endpoint CS descriptor bNumEmbMIDIJack value @@ -147,8 +144,6 @@ void midih_close(uint8_t daddr) { TU_LOG_DRV(" MIDI close addr = %u index = %u\r\n", daddr, idx); tuh_midi_umount_cb(idx); - p_midi->ep_in = 0; - p_midi->ep_out = 0; p_midi->bInterfaceNumber = 0; p_midi->rx_cable_count = 0; p_midi->tx_cable_count = 0; @@ -169,23 +164,25 @@ bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint const uint8_t idx = get_idx_by_ep_addr(dev_addr, ep_addr); TU_VERIFY(idx < CFG_TUH_MIDI); midih_interface_t *p_midi = &_midi_host[idx]; + tu_edpt_stream_t *ep_str_rx = &p_midi->ep_stream.rx; + tu_edpt_stream_t *ep_str_tx = &p_midi->ep_stream.tx; - if (ep_addr == p_midi->ep_stream.rx.ep_addr) { + if (ep_addr == ep_str_rx->ep_addr) { // receive new data, put it into FIFO and invoke callback if available // Note: some devices send back all zero packets even if there is no data ready - if (xferred_bytes && !tu_mem_is_zero(p_midi->ep_stream.rx.ep_buf, xferred_bytes)) { - tu_edpt_stream_read_xfer_complete(&p_midi->ep_stream.rx, xferred_bytes); + if (xferred_bytes && !tu_mem_is_zero(ep_str_rx->ep_buf, xferred_bytes)) { + tu_edpt_stream_read_xfer_complete(ep_str_rx, xferred_bytes); tuh_midi_rx_cb(idx, xferred_bytes); } - tu_edpt_stream_read_xfer(dev_addr, &p_midi->ep_stream.rx); // prepare for next transfer - } else if (ep_addr == p_midi->ep_stream.tx.ep_addr) { + tu_edpt_stream_read_xfer(dev_addr, ep_str_rx); // prepare for next transfer + } else if (ep_addr == ep_str_tx->ep_addr) { tuh_midi_tx_cb(idx, xferred_bytes); - if (0 == tu_edpt_stream_write_xfer(dev_addr, &p_midi->ep_stream.tx)) { + if (0 == tu_edpt_stream_write_xfer(dev_addr, ep_str_tx)) { // If there is no data left, a ZLP should be sent if // xferred_bytes is multiple of EP size and not zero - tu_edpt_stream_write_zlp_if_needed(dev_addr, &p_midi->ep_stream.tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(dev_addr, ep_str_tx, xferred_bytes); } } @@ -295,21 +292,20 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc; TU_LOG_DRV(" Endpoint and CS_Endpoint descriptor %02x\r\n", p_ep->bEndpointAddress); + tu_edpt_stream_t *ep_stream; if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { - p_midi->ep_out = p_ep->bEndpointAddress; p_midi->tx_cable_count = p_csep->bNumEmbMIDIJack; desc_cb.desc_epout = p_ep; - - TU_ASSERT(tuh_edpt_open(dev_addr, p_ep)); - tu_edpt_stream_open(&p_midi->ep_stream.tx, p_ep); + ep_stream = &p_midi->ep_stream.tx; } else { - p_midi->ep_in = p_ep->bEndpointAddress; p_midi->rx_cable_count = p_csep->bNumEmbMIDIJack; - desc_cb.desc_epin = p_ep; - - TU_ASSERT(tuh_edpt_open(dev_addr, p_ep)); - tu_edpt_stream_open(&p_midi->ep_stream.rx, p_ep); + desc_cb.desc_epin = p_ep; + ep_stream = &p_midi->ep_stream.rx; } + TU_ASSERT(tuh_edpt_open(dev_addr, p_ep)); + tu_edpt_stream_open(ep_stream, p_ep); + tu_edpt_stream_clear(ep_stream); + break; } @@ -379,8 +375,14 @@ bool tuh_midi_itf_get_info(uint8_t idx, tuh_itf_info_t* info) { desc->bDescriptorType = TUSB_DESC_INTERFACE; desc->bInterfaceNumber = p_midi->bInterfaceNumber; - desc->bAlternateSetting = 0; - desc->bNumEndpoints = (uint8_t)((p_midi->ep_in != 0 ? 1:0) + (p_midi->ep_out != 0 ? 1:0)); + desc->bAlternateSetting = 0; + desc->bNumEndpoints = 0; + if (tu_edpt_stream_is_opened(&p_midi->ep_stream.tx)) { + desc->bNumEndpoints++; + } + if (tu_edpt_stream_is_opened(&p_midi->ep_stream.rx)) { + desc->bNumEndpoints++; + } desc->bInterfaceClass = TUSB_CLASS_AUDIO; desc->bInterfaceSubClass = AUDIO_SUBCLASS_MIDI_STREAMING; desc->bInterfaceProtocol = 0; diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 7aa42a2d7..f377d5272 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -354,7 +354,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_subtype(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_SUBTYPE]; } -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_in_bounds(uint8_t const* p_desc, uint8_t const* desc_end) { +TU_ATTR_ALWAYS_INLINE static inline bool tu_desc_in_bounds(const uint8_t *p_desc, const uint8_t *desc_end) { if (p_desc >= desc_end) { return false; } diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index f82f87b6f..be1264a71 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -120,7 +120,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_empty(tu_edpt_stream_t * return tu_fifo_empty(&s->ff); } - //--------------------------------------------------------------------+ // Stream Write //--------------------------------------------------------------------+ diff --git a/src/tusb.c b/src/tusb.c index df33f2680..6fb5309ab 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -517,7 +517,7 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s) { } uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) { - uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t) bufsize); + const uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t)bufsize); tu_edpt_stream_read_xfer(hwid, s); return num_read; } -- cgit v1.3.1 From 2b07fa6e6a5376b6a9d1c4dd39b61a96cd9e0138 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 13 Nov 2025 12:47:36 +0700 Subject: Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/class/cdc/cdc_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 80fa81d99..babb89952 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -290,7 +290,7 @@ void cdcd_init(void) { } bool cdcd_deinit(void) { - for(uint8_t i=0; istream.rx); tu_edpt_stream_deinit(&p_cdc->stream.tx); @@ -305,7 +305,7 @@ void cdcd_reset(uint8_t rhport) { cdcd_interface_t* p_cdc = &_cdcd_itf[i]; tu_memclr(p_cdc, ITF_MEM_RESET_SIZE); - tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, _cdcd_cfg.tx_overwritabe_if_not_connected); // // back to default + tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, _cdcd_cfg.tx_overwritabe_if_not_connected); // back to default tu_edpt_stream_close(&p_cdc->stream.rx); tu_edpt_stream_close(&p_cdc->stream.tx); } -- cgit v1.3.1 From c9b623aa63d24d58a7a5e55dd296afd1261b2ab8 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 21 Nov 2025 17:02:56 +0700 Subject: edpt stream support xfer_fifo for device CFG_TUD_EDPT_DEDICATED_HWFIFO cdc device omit ep buffer when hwfifo is supported --- docs/info/changelog.rst | 2 +- src/class/cdc/cdc_device.c | 18 ++++++++++++++---- src/common/tusb_fifo.h | 4 ++++ src/common/tusb_private.h | 6 +++--- src/device/usbd.c | 11 ++++++++++- src/tusb.c | 22 ++++++++++++++++------ src/tusb_option.h | 16 ++++++++++------ 7 files changed, 58 insertions(+), 21 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index df23ce7d8..35c8515cc 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -5,7 +5,7 @@ Changelog 0.20.0 ====== -*November 19, 2024* +*November 19, 2025* General ------- diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 9e62c6509..a11de2f91 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -67,8 +67,11 @@ typedef struct { #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) typedef struct { + // Don't use local EP buffer if dedicated FIFO is supported + #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE); TUD_EPBUF_DEF(epin, CFG_TUD_CDC_EP_BUFSIZE); + #endif #if CFG_TUD_CDC_NOTIFY TUD_EPBUF_TYPE_DEF(cdc_notify_msg_t, epnotify); @@ -268,8 +271,6 @@ void cdcd_init(void) { tu_memclr(_cdcd_itf, sizeof(_cdcd_itf)); for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { cdcd_interface_t *p_cdc = &_cdcd_itf[i]; - cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[i]; - p_cdc->wanted_char = (char) -1; // default line coding is : stop bit = 1, parity = none, data bits = 8 @@ -278,14 +279,23 @@ void cdcd_init(void) { p_cdc->line_coding.parity = 0; p_cdc->line_coding.data_bits = 8; + #if CFG_TUD_EDPT_DEDICATED_HWFIFO + 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; + #endif + tu_edpt_stream_init(&p_cdc->stream.rx, false, false, false, p_cdc->stream.rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, - p_epbuf->epout, CFG_TUD_CDC_EP_BUFSIZE); + epout_buf, CFG_TUD_CDC_EP_BUFSIZE); // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not // know if data is actually polled by terminal. This way the most current data is prioritized. // Default: is overwritable tu_edpt_stream_init(&p_cdc->stream.tx, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, - p_cdc->stream.tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE); + p_cdc->stream.tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE); } } diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index c16216606..0b8e83760 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -48,6 +48,10 @@ extern "C" { // for OS None, we don't get preempted #define CFG_FIFO_MUTEX OSAL_MUTEX_REQUIRED +#if CFG_TUD_EDPT_DEDICATED_HWFIFO || CFG_TUH_EDPT_DEDICATED_HWFIFO + #define CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32 +#endif + /* Write/Read index is always in the range of: * 0 .. 2*depth-1 * The extra window allow us to determine the fifo state of empty or full with only 2 indices diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index be1264a71..48fd1d6d2 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -60,7 +60,7 @@ typedef struct { uint8_t ep_addr; uint16_t ep_bufsize; - uint8_t* ep_buf; // TODO xfer_fifo can skip this buffer + uint8_t *ep_buf; // set to NULL to use xfer_fifo when CFG_TUD_EDPT_DEDICATED_HWFIFO = 1 tu_fifo_t ff; // mutex: read if rx, otherwise write @@ -98,7 +98,7 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove // Deinit an endpoint stream bool tu_edpt_stream_deinit(tu_edpt_stream_t* s); -// Open an stream for an endpoint +// Open an endpoint stream TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { s->ep_addr = desc_ep->bEndpointAddress; s->is_mps512 = tu_edpt_packet_size(desc_ep) == 512; @@ -150,7 +150,7 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s); // Complete read transfer by writing EP -> FIFO. Must be called in the transfer complete callback TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) { - if (0u != tu_fifo_depth(&s->ff)) { + if (0u != tu_fifo_depth(&s->ff) && s->ep_buf != NULL) { tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes); } } diff --git a/src/device/usbd.c b/src/device/usbd.c index a65d14daf..5e7d0ffa7 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1474,6 +1474,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t t // success message. If total_bytes is too big, the FIFO will copy only what is available // into the USB buffer! bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t total_bytes, bool is_isr) { + #if CFG_TUD_EDPT_DEDICATED_HWFIFO rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); @@ -1481,7 +1482,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_ TU_LOG_USBD(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes); - // Attempt to transfer on a busy endpoint, sound like an race condition ! + // Attempt to transfer on a busy endpoint, sound like a race condition ! TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0); // Set busy first since the actual transfer can be complete before dcd_edpt_xfer() could return @@ -1499,6 +1500,14 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_ TU_BREAKPOINT(); return false; } + #else + (void)rhport; + (void)ep_addr; + (void)ff; + (void)total_bytes; + (void)is_isr; + return false; + #endif } bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr) { diff --git a/src/tusb.c b/src/tusb.c index 3852da76b..1b8fdc460 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -387,8 +387,12 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(uint8_t hwid, tu_edpt_strea #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false); - #endif + if (s->ep_buf == NULL) { + return usbd_edpt_xfer_fifo(hwid, s->ep_addr, &s->ff, count, false); + } else { + return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false); + } + #endif } return false; } @@ -419,12 +423,17 @@ bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint3 } uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) { - // skip if no data - TU_VERIFY(tu_fifo_count(&s->ff) > 0, 0); + const uint16_t ff_count = tu_fifo_count(&s->ff); + TU_VERIFY(ff_count > 0, 0); // skip if no data TU_VERIFY(stream_claim(hwid, s), 0); // Pull data from FIFO -> EP buf - const uint16_t count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); + uint16_t count; + if (s->ep_buf == NULL) { + count = ff_count; + } else { + count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); + } if (count > 0) { TU_ASSERT(stream_xfer(hwid, s, count), 0); @@ -441,7 +450,8 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buf TU_VERIFY(bufsize > 0); // TODO support ZLP if (0 == tu_fifo_depth(&s->ff)) { - // no fifo for buffered + // no fifo for buffered, ep_buf must be valid + TU_VERIFY(s->ep_buf != NULL, 0); TU_VERIFY(stream_claim(hwid, s), 0); const uint32_t xact_len = tu_min32(bufsize, s->ep_bufsize); memcpy(s->ep_buf, buffer, xact_len); diff --git a/src/tusb_option.h b/src/tusb_option.h index e2eaecd2d..d7b61d58d 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -306,18 +306,14 @@ #if defined(TUP_USBIP_DWC2) #if CFG_TUD_DWC2_SLAVE_ENABLE - #define CFG_TUD_EDPT_DEDICATED_FIFO + #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 #endif #if CFG_TUD_DWC2_SLAVE_ENABLE - #define CFG_TUH_EDPT_DEDICATED_FIFO + #define CFG_TUH_EDPT_DEDICATED_HWFIFO 1 #endif #endif -#if defined(CFG_TUD_EDPT_DEDICATED_FIFO) || defined(CFG_TUH_EDPT_DEDICATED_FIFO) - #define CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32 -#endif - //------------- ChipIdea -------------// // Enable CI_HS VBUS Charge. Set this to 1 if the USB_VBUS pin is not connected to 5V VBUS (note: 3.3V is // insufficient). @@ -590,6 +586,10 @@ #define CFG_TUD_NCM 0 #endif +#ifndef CFG_TUD_EDPT_DEDICATED_HWFIFO + #define CFG_TUD_EDPT_DEDICATED_HWFIFO 0 +#endif + //-------------------------------------------------------------------- // Host Options (Default) //-------------------------------------------------------------------- @@ -729,6 +729,10 @@ #define CFG_TUH_API_EDPT_XFER 0 #endif +#ifndef CFG_TUH_EDPT_DEDICATED_HWFIFO + #define CFG_TUH_EDPT_DEDICATED_HWFIFO 0 +#endif + //--------------------------------------------------------------------+ // TypeC Options (Default) //--------------------------------------------------------------------+ -- cgit v1.3.1 From 7df6e7bd054e6b81af8e0b2549ee60571be8c1d4 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 22 Nov 2025 00:56:24 +0700 Subject: implement wanted char for cdc device without ep_buf --- src/class/cdc/cdc_device.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index a11de2f91..aeaceb16c 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -66,8 +66,9 @@ typedef struct { #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) +#if CFG_TUD_EDPT_DEDICATED_HWFIFO || CFG_TUD_CDC_NOTIFY typedef struct { - // Don't use local EP buffer if dedicated FIFO is supported + // Don't use local EP buffer if dedicated hw FIFO is supported #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE); TUD_EPBUF_DEF(epin, CFG_TUD_CDC_EP_BUFSIZE); @@ -78,6 +79,9 @@ typedef struct { #endif } cdcd_epbuf_t; +CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; +#endif + //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ @@ -118,7 +122,6 @@ TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) { // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; -CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT(); TU_ATTR_ALWAYS_INLINE static inline uint8_t find_cdc_itf(uint8_t ep_addr) { @@ -491,11 +494,35 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (ep_addr == stream_rx->ep_addr) { tu_edpt_stream_read_xfer_complete(stream_rx, xferred_bytes); - // Check for wanted char and invoke wanted callback (multiple times if multiple wanted received) + // Check for wanted char and invoke wanted callback if (((signed char)p_cdc->wanted_char) != -1) { - for (uint32_t i = 0; i < xferred_bytes; i++) { - if ((p_cdc->wanted_char == (char)stream_rx->ep_buf[i]) && !tu_edpt_stream_empty(stream_rx)) { - tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); + tu_fifo_buffer_info_t buf_info; + tu_fifo_get_read_info(&stream_rx->ff, &buf_info); + + // find backward + uint8_t *ptr; + if (buf_info.len_wrap > 0) { + ptr = buf_info.ptr_wrap + buf_info.len_wrap - 1; // last byte of wrap buffer + } else if (buf_info.len_lin > 0) { + ptr = buf_info.ptr_lin + buf_info.len_lin - 1; // last byte of linear buffer + } else { + ptr = NULL; // no data + } + + if (ptr != NULL) { + for (uint32_t i = 0; i < xferred_bytes; i++) { + if (p_cdc->wanted_char == (char)*ptr) { + tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); + break; // only invoke once per transfer, even multiple wanted chars are present + } + + if (ptr == buf_info.ptr_wrap) { + ptr = buf_info.ptr_lin + buf_info.len_lin - 1; // last byte of linear buffer + } else if (ptr == buf_info.ptr_lin) { + break; // reached the beginning + } else { + ptr--; + } } } } -- cgit v1.3.1 From d9094ffcee61ee0c155945969c15a34e1e7365ed Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 22 Nov 2025 01:02:52 +0700 Subject: implement wanted char for cdc device without ep_buf --- src/class/cdc/cdc_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index aeaceb16c..3f860a657 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -66,7 +66,7 @@ typedef struct { #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) -#if CFG_TUD_EDPT_DEDICATED_HWFIFO || CFG_TUD_CDC_NOTIFY +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || CFG_TUD_CDC_NOTIFY typedef struct { // Don't use local EP buffer if dedicated hw FIFO is supported #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 -- cgit v1.3.1 From b98127fba2b198130eb8868defcf117c6b5ea231 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 22 Nov 2025 17:31:31 +0700 Subject: hil stress test cdc --- src/class/cdc/cdc_device.c | 2 +- src/common/tusb_fifo.c | 2 +- test/hil/hil_test.py | 2 +- test/unit-test/test/test_fifo.c | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 3f860a657..2ab592bca 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -513,7 +513,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ for (uint32_t i = 0; i < xferred_bytes; i++) { if (p_cdc->wanted_char == (char)*ptr) { tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); - break; // only invoke once per transfer, even multiple wanted chars are present + break; // only invoke once per transfer, even if multiple wanted chars are present } if (ptr == buf_info.ptr_wrap) { diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index f09fcbafa..0c44cbd76 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -400,7 +400,7 @@ uint16_t tu_fifo_write_n_access(tu_fifo_t *f, const void *data, uint16_t n, tu_f const uint8_t *buf8 = (const uint8_t *)data; TU_LOG(TU_FIFO_DBG, "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: ", rd_idx, wr_idx, - _ff_count(f->depth, wr_idx, rd_idx), _ff_remaining(f->depth, wr_idx, rd_idx), n); + tu_ff_overflow_count(f->depth, wr_idx, rd_idx), tu_ff_remaining_local(f->depth, wr_idx, rd_idx), n); if (!f->overwritable) { // limit up to full diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index aabf8a449..238d452e8 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -437,7 +437,7 @@ def test_device_cdc_msc(board): ser.write(test_str) ser.flush() rd_str = ser.read(len(test_str)) - assert rd_str == test_str, f'CDC wrong data ({size} bytes): expected: {test_str[:16]}... was {rd_str[:16]}' + assert rd_str == test_str, f'CDC wrong data ({size} bytes):\n expected: {test_str}\n was: {rd_str}' ser.close() diff --git a/test/unit-test/test/test_fifo.c b/test/unit-test/test/test_fifo.c index 83db10454..d1049b81d 100644 --- a/test/unit-test/test/test_fifo.c +++ b/test/unit-test/test/test_fifo.c @@ -182,10 +182,10 @@ static uint16_t help_write(uint16_t total, uint16_t n) { } void test_write_overwritable2(void) { -tu_fifo_set_overwritable(ff, true); + tu_fifo_set_overwritable(ff, true); -// based on actual crash tests detected by fuzzing -uint16_t total = 0; + // based on actual crash tests detected by fuzzing + uint16_t total = 0; total = help_write(total, 12); total = help_write(total, 55); -- cgit v1.3.1 From c925277e24e6743b311199d87461befe8b590187 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 26 Nov 2025 15:26:42 +0700 Subject: change tu_fifo_buffer_info_t layout --- src/class/cdc/cdc_device.c | 14 ++--- src/common/tusb_fifo.c | 58 +++++++++--------- src/common/tusb_fifo.h | 9 ++- src/common/tusb_mcu.h | 1 + src/portable/chipidea/ci_hs/dcd_ci_hs.c | 10 +-- src/portable/mentor/musb/dcd_musb.c | 8 +-- src/portable/microchip/samx7x/dcd_samx7x.c | 16 ++--- src/portable/renesas/rusb2/dcd_rusb2.c | 16 ++--- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 20 +++--- src/portable/sunxi/dcd_sunxi_musb.c | 8 +-- test/unit-test/test/test_fifo.c | 88 +++++++++++++-------------- 11 files changed, 124 insertions(+), 124 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 2ab592bca..fbca5b574 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -501,10 +501,10 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // find backward uint8_t *ptr; - if (buf_info.len_wrap > 0) { - ptr = buf_info.ptr_wrap + buf_info.len_wrap - 1; // last byte of wrap buffer - } else if (buf_info.len_lin > 0) { - ptr = buf_info.ptr_lin + buf_info.len_lin - 1; // last byte of linear buffer + if (buf_info.wrapped.len > 0) { + ptr = buf_info.wrapped.ptr + buf_info.wrapped.len - 1; // last byte of wrap buffer + } else if (buf_info.linear.len > 0) { + ptr = buf_info.linear.ptr + buf_info.linear.len - 1; // last byte of linear buffer } else { ptr = NULL; // no data } @@ -516,9 +516,9 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ break; // only invoke once per transfer, even if multiple wanted chars are present } - if (ptr == buf_info.ptr_wrap) { - ptr = buf_info.ptr_lin + buf_info.len_lin - 1; // last byte of linear buffer - } else if (ptr == buf_info.ptr_lin) { + if (ptr == buf_info.wrapped.ptr) { + ptr = buf_info.linear.ptr + buf_info.linear.len - 1; // last byte of linear buffer + } else if (ptr == buf_info.linear.ptr) { break; // reached the beginning } else { ptr--; diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 0c44cbd76..6bc384be3 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -82,8 +82,8 @@ bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_si //--------------------------------------------------------------------+ // Pull & Push +// copy data to/from fifo without updating read/write pointers //--------------------------------------------------------------------+ - #ifdef CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32 // Intended to be used to read from hardware USB FIFO in e.g. STM32 where all data is read from a constant address // Code adapted from dcd_synopsys.c @@ -216,7 +216,7 @@ static void _ff_push_n(tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t w } // get one item from fifo WITHOUT updating read pointer -TU_ATTR_ALWAYS_INLINE static inline void _ff_pull(tu_fifo_t *f, void *buf, uint16_t ptr) { +TU_ATTR_ALWAYS_INLINE static inline void _ff_pull(const tu_fifo_t *f, void *buf, uint16_t ptr) { memcpy(buf, f->buffer + (ptr * f->item_size), f->item_size); } @@ -326,7 +326,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t idx2ptr(uint16_t depth, uint16_t id // Works on local copies of w // When an overwritable fifo is overflowed, rd_idx will be re-index so that it forms a full fifo -TU_ATTR_ALWAYS_INLINE static inline uint16_t ff_correct_read_index(tu_fifo_t *f, uint16_t wr_idx) { +TU_ATTR_ALWAYS_INLINE static inline uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) { uint16_t rd_idx; if (wr_idx >= f->depth) { rd_idx = wr_idx - f->depth; @@ -349,7 +349,7 @@ static bool ff_peek_local(tu_fifo_t *f, void *p_buffer, uint16_t wr_idx, uint16_ // Correct read index if overflow if (ovf_count > f->depth) { ff_lock(f->mutex_rd); - rd_idx = ff_correct_read_index(f, wr_idx); + rd_idx = correct_read_index(f, wr_idx); ff_unlock(f->mutex_rd); } @@ -373,7 +373,7 @@ uint16_t tu_fifo_peek_n_access(tu_fifo_t *f, void *p_buffer, uint16_t n, uint16_ // Check overflow and correct if required if (cnt > f->depth) { - rd_idx = ff_correct_read_index(f, wr_idx); + rd_idx = correct_read_index(f, wr_idx); cnt = f->depth; } @@ -477,7 +477,7 @@ uint16_t tu_fifo_read_n_access(tu_fifo_t *f, void *buffer, uint16_t n, tu_fifo_a // Only use in case tu_fifo_overflow() returned true! void tu_fifo_correct_read_pointer(tu_fifo_t *f) { ff_lock(f->mutex_rd); - ff_correct_read_index(f, f->wr_idx); + correct_read_index(f, f->wr_idx); ff_unlock(f->mutex_rd); } @@ -696,7 +696,7 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { // Check overflow and correct if required - may happen in case a DMA wrote too fast if (cnt > f->depth) { ff_lock(f->mutex_rd); - rd_idx = ff_correct_read_index(f, wr_idx); + rd_idx = correct_read_index(f, wr_idx); ff_unlock(f->mutex_rd); cnt = f->depth; @@ -704,10 +704,10 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { // Check if fifo is empty if (cnt == 0) { - info->len_lin = 0; - info->len_wrap = 0; - info->ptr_lin = NULL; - info->ptr_wrap = NULL; + info->linear.len = 0; + info->wrapped.len = 0; + info->linear.ptr = NULL; + info->wrapped.ptr = NULL; return; } @@ -716,20 +716,20 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); // Copy pointer to buffer to start reading from - info->ptr_lin = &f->buffer[rd_ptr]; + info->linear.ptr = &f->buffer[rd_ptr]; // Check if there is a wrap around necessary if (wr_ptr > rd_ptr) { // Non wrapping case - info->len_lin = cnt; + info->linear.len = cnt; - info->len_wrap = 0; - info->ptr_wrap = NULL; + info->wrapped.len = 0; + info->wrapped.ptr = NULL; } else { - info->len_lin = f->depth - rd_ptr; // Also the case if FIFO was full + info->linear.len = f->depth - rd_ptr; // Also the case if FIFO was full - info->len_wrap = cnt - info->len_lin; - info->ptr_wrap = f->buffer; + info->wrapped.len = cnt - info->linear.len; + info->wrapped.ptr = f->buffer; } } @@ -754,10 +754,10 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { uint16_t remain = tu_ff_remaining_local(f->depth, wr_idx, rd_idx); if (remain == 0) { - info->len_lin = 0; - info->len_wrap = 0; - info->ptr_lin = NULL; - info->ptr_wrap = NULL; + info->linear.len = 0; + info->wrapped.len = 0; + info->linear.ptr = NULL; + info->wrapped.ptr = NULL; return; } @@ -766,16 +766,16 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); // Copy pointer to buffer to start writing to - info->ptr_lin = &f->buffer[wr_ptr]; + info->linear.ptr = &f->buffer[wr_ptr]; if (wr_ptr < rd_ptr) { // Non wrapping case - info->len_lin = rd_ptr - wr_ptr; - info->len_wrap = 0; - info->ptr_wrap = NULL; + info->linear.len = rd_ptr - wr_ptr; + info->wrapped.len = 0; + info->wrapped.ptr = NULL; } else { - info->len_lin = f->depth - wr_ptr; - info->len_wrap = remain - info->len_lin; // Remaining length - n already was limited to remain or FIFO depth - info->ptr_wrap = f->buffer; // Always start of buffer + info->linear.len = f->depth - wr_ptr; + info->wrapped.len = remain - info->linear.len; // Remaining length - n already was limited to remain or FIFO depth + info->wrapped.ptr = f->buffer; // Always start of buffer } } diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 005282824..d40fc4401 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -128,10 +128,10 @@ typedef struct { } tu_fifo_t; typedef struct { - uint16_t len_lin; ///< linear length in item size - uint16_t len_wrap; ///< wrapped length in item size - uint8_t *ptr_lin; ///< linear part start pointer - uint8_t *ptr_wrap; ///< wrapped part start pointer + struct { + uint16_t len; // length + uint8_t *ptr; // buffer pointer + } linear, wrapped; } tu_fifo_buffer_info_t; #define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \ @@ -198,7 +198,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_write_n(tu_fifo_t *f, const return tu_fifo_write_n_access(f, data, n, TU_FIFO_INC_ADDR_RW8); } - //--------------------------------------------------------------------+ // Index API //--------------------------------------------------------------------+ diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 34977378c..1e773bf96 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -523,6 +523,7 @@ //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_F1C100S) #define TUP_DCD_ENDPOINT_MAX 4 + #define TUP_DCD_EDPT_CLOSE_API //--------------------------------------------------------------------+ // WCH diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index c6d405e98..4a5e5c91f 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -545,19 +545,19 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ tu_fifo_get_write_info(ff, &fifo_info); } - if ( fifo_info.len_lin >= total_bytes ) + if ( fifo_info.linear.len >= total_bytes ) { // Linear length is enough for this transfer - qtd_init(p_qtd, fifo_info.ptr_lin, total_bytes); + qtd_init(p_qtd, fifo_info.linear.ptr, total_bytes); } else { // linear part is not enough // prepare TD up to linear length - qtd_init(p_qtd, fifo_info.ptr_lin, fifo_info.len_lin); + qtd_init(p_qtd, fifo_info.linear.ptr, fifo_info.linear.len); - if ( !tu_offset4k((uint32_t) fifo_info.ptr_wrap) && !tu_offset4k(tu_fifo_depth(ff)) ) + if ( !tu_offset4k((uint32_t) fifo_info.wrapped.ptr) && !tu_offset4k(tu_fifo_depth(ff)) ) { // If buffer is aligned to 4K & buffer size is multiple of 4K // We can make use of buffer page array to also combine the linear + wrapped length @@ -568,7 +568,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ // pick up buffer array where linear ends if (p_qtd->buffer[i] == 0) { - p_qtd->buffer[i] = (uint32_t) fifo_info.ptr_wrap + 4096 * page; + p_qtd->buffer[i] = (uint32_t) fifo_info.wrapped.ptr + 4096 * page; page++; } } diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 1e4ec0015..ad20d64bd 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -221,12 +221,12 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne tu_fifo_buffer_info_t info; ops[dir].tu_fifo_get_info(f, &info); unsigned total_len = len; - len = TU_MIN(total_len, info.len_lin); - ops[dir].pipe_read_write(info.ptr_lin, fifo, len); + len = TU_MIN(total_len, info.linear.len); + ops[dir].pipe_read_write(info.linear.ptr, fifo, len); unsigned rem = total_len - len; if (rem) { - len = TU_MIN(rem, info.len_wrap); - ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); + len = TU_MIN(rem, info.wrapped.len); + ops[dir].pipe_read_write(info.wrapped.ptr, fifo, len); rem -= len; } ops[dir].tu_fifo_advance(f, total_len - rem); diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index 4d54f9057..b0a053c01 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -697,7 +697,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ udd_dma_ctrl_wrap |= DEVDMACONTROL_END_TR_IT | DEVDMACONTROL_END_TR_EN; } else { tu_fifo_get_read_info(ff, &info); - if(info.len_wrap == 0) + if(info.wrapped.len == 0) { udd_dma_ctrl_lin |= DEVDMACONTROL_END_B_EN; } @@ -705,18 +705,18 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ } // Clean invalidate cache of linear part - CleanInValidateCache((uint32_t*) tu_align((uint32_t) info.ptr_lin, 4), info.len_lin + 31); + CleanInValidateCache((uint32_t*) tu_align((uint32_t) info.linear.ptr, 4), info.linear.len + 31); - USB_REG->DEVDMA[epnum - 1].DEVDMAADDRESS = (uint32_t)info.ptr_lin; - if (info.len_wrap) + USB_REG->DEVDMA[epnum - 1].DEVDMAADDRESS = (uint32_t)info.linear.ptr; + if (info.wrapped.len) { // Clean invalidate cache of wrapped part - CleanInValidateCache((uint32_t*) tu_align((uint32_t) info.ptr_wrap, 4), info.len_wrap + 31); + CleanInValidateCache((uint32_t*) tu_align((uint32_t) info.wrapped.ptr, 4), info.wrapped.len + 31); dma_desc[epnum - 1].next_desc = 0; - dma_desc[epnum - 1].buff_addr = (uint32_t)info.ptr_wrap; + dma_desc[epnum - 1].buff_addr = (uint32_t)info.wrapped.ptr; dma_desc[epnum - 1].chnl_ctrl = - udd_dma_ctrl_wrap | (info.len_wrap << DEVDMACONTROL_BUFF_LENGTH_Pos); + udd_dma_ctrl_wrap | (info.wrapped.len << DEVDMACONTROL_BUFF_LENGTH_Pos); // Clean cache of wrapped DMA descriptor CleanInValidateCache((uint32_t*)&dma_desc[epnum - 1], sizeof(dma_desc_t)); @@ -725,7 +725,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ } else { udd_dma_ctrl_lin |= DEVDMACONTROL_END_BUFFIT; } - udd_dma_ctrl_lin |= (info.len_lin << DEVDMACONTROL_BUFF_LENGTH_Pos); + udd_dma_ctrl_lin |= (info.linear.len << DEVDMACONTROL_BUFF_LENGTH_Pos); // Disable IRQs to have a short sequence // between read of EOT_STA and DMA enable uint32_t irq_state = __get_PRIMASK(); diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 7caf5d68a..786b8d980 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -213,13 +213,13 @@ static void pipe_write_packet_ff(rusb2_reg_t * rusb, tu_fifo_t *f, volatile void tu_fifo_buffer_info_t info; tu_fifo_get_read_info(f, &info); - uint16_t count = tu_min16(total_len, info.len_lin); - pipe_write_packet(rusb, info.ptr_lin, fifo, count); + uint16_t count = tu_min16(total_len, info.linear.len); + pipe_write_packet(rusb, info.linear.ptr, fifo, count); uint16_t rem = total_len - count; if (rem) { - rem = tu_min16(rem, info.len_wrap); - pipe_write_packet(rusb, info.ptr_wrap, fifo, rem); + rem = tu_min16(rem, info.wrapped.len); + pipe_write_packet(rusb, info.wrapped.ptr, fifo, rem); count += rem; } @@ -231,13 +231,13 @@ static void pipe_read_packet_ff(rusb2_reg_t * rusb, tu_fifo_t *f, volatile void tu_fifo_buffer_info_t info; tu_fifo_get_write_info(f, &info); - uint16_t count = tu_min16(total_len, info.len_lin); - pipe_read_packet(rusb, info.ptr_lin, fifo, count); + uint16_t count = tu_min16(total_len, info.linear.len); + pipe_read_packet(rusb, info.linear.ptr, fifo, count); uint16_t rem = total_len - count; if (rem) { - rem = tu_min16(rem, info.len_wrap); - pipe_read_packet(rusb, info.ptr_wrap, fifo, rem); + rem = tu_min16(rem, info.wrapped.len); + pipe_read_packet(rusb, info.wrapped.ptr, fifo, rem); count += rem; } diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 6276f0f07..64046ce17 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -927,15 +927,15 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNB tu_fifo_buffer_info_t info; tu_fifo_get_read_info(ff, &info); - uint16_t cnt_lin = tu_min16(wNBytes, info.len_lin); - uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.len_wrap); + uint16_t cnt_lin = tu_min16(wNBytes, info.linear.len); + uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.wrapped.len); uint16_t const cnt_total = cnt_lin + cnt_wrap; // We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part, // last lin byte will be combined with wrapped part To ensure PMA is always access aligned uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1); uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1); - uint8_t const *src8 = (uint8_t const*) info.ptr_lin; + uint8_t const *src8 = (uint8_t const*) info.linear.ptr; // write even linear part dcd_write_packet_memory(dst, src8, lin_even); @@ -943,7 +943,7 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNB src8 += lin_even; if (lin_odd == 0) { - src8 = (uint8_t const*) info.ptr_wrap; + src8 = (uint8_t const*) info.wrapped.ptr; } else { // Combine last linear bytes + first wrapped bytes to form fsdev bus width data fsdev_bus_t temp = 0; @@ -952,7 +952,7 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNB temp |= *src8++ << (i * 8); } - src8 = (uint8_t const*) info.ptr_wrap; + src8 = (uint8_t const*) info.wrapped.ptr; for(; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) { temp |= *src8++ << (i * 8); } @@ -977,8 +977,8 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBy tu_fifo_buffer_info_t info; tu_fifo_get_write_info(ff, &info); // We want to read from the FIFO - uint16_t cnt_lin = tu_min16(wNBytes, info.len_lin); - uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.len_wrap); + uint16_t cnt_lin = tu_min16(wNBytes, info.linear.len); + uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.wrapped.len); uint16_t cnt_total = cnt_lin + cnt_wrap; // We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part, @@ -986,7 +986,7 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBy uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1); uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1); - uint8_t *dst8 = (uint8_t *) info.ptr_lin; + uint8_t *dst8 = (uint8_t *) info.linear.ptr; // read even linear part dcd_read_packet_memory(dst8, src, lin_even); @@ -994,7 +994,7 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBy src += lin_even; if (lin_odd == 0) { - dst8 = (uint8_t *) info.ptr_wrap; + dst8 = (uint8_t *) info.wrapped.ptr; } else { // Combine last linear bytes + first wrapped bytes to form fsdev bus width data fsdev_bus_t temp; @@ -1007,7 +1007,7 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBy temp >>= 8; } - dst8 = (uint8_t *) info.ptr_wrap; + dst8 = (uint8_t *) info.wrapped.ptr; for (; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) { *dst8++ = (uint8_t) (temp & 0xfful); temp >>= 8; diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index d43ea1dc3..b413121a5 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -535,12 +535,12 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne tu_fifo_buffer_info_t info; ops[dir].tu_fifo_get_info(f, &info); unsigned total_len = len; - len = TU_MIN(total_len, info.len_lin); - ops[dir].pipe_read_write(info.ptr_lin, fifo, len); + len = TU_MIN(total_len, info.linear.len); + ops[dir].pipe_read_write(info.linear.ptr, fifo, len); unsigned rem = total_len - len; if (rem) { - len = TU_MIN(rem, info.len_wrap); - ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); + len = TU_MIN(rem, info.wrapped.len); + ops[dir].pipe_read_write(info.wrapped.ptr, fifo, len); rem -= len; } ops[dir].tu_fifo_advance(f, total_len - rem); diff --git a/test/unit-test/test/test_fifo.c b/test/unit-test/test/test_fifo.c index d1049b81d..ac93e7e38 100644 --- a/test/unit-test/test/test_fifo.c +++ b/test/unit-test/test/test_fifo.c @@ -236,11 +236,11 @@ void test_get_read_info_when_no_wrap() { tu_fifo_get_read_info(ff, &info); - TEST_ASSERT_EQUAL(4, info.len_lin); - TEST_ASSERT_EQUAL(0, info.len_wrap); + TEST_ASSERT_EQUAL(4, info.linear.len); + TEST_ASSERT_EQUAL(0, info.wrapped.len); - TEST_ASSERT_EQUAL_PTR(ff->buffer + 2, info.ptr_lin); - TEST_ASSERT_NULL(info.ptr_wrap); + TEST_ASSERT_EQUAL_PTR(ff->buffer + 2, info.linear.ptr); + TEST_ASSERT_NULL(info.wrapped.ptr); } void test_get_read_info_when_wrapped() { @@ -262,11 +262,11 @@ void test_get_read_info_when_wrapped() { tu_fifo_get_read_info(ff, &info); - TEST_ASSERT_EQUAL(FIFO_SIZE - 6, info.len_lin); - TEST_ASSERT_EQUAL(2, info.len_wrap); + TEST_ASSERT_EQUAL(FIFO_SIZE - 6, info.linear.len); + TEST_ASSERT_EQUAL(2, info.wrapped.len); - TEST_ASSERT_EQUAL_PTR(ff->buffer + 6, info.ptr_lin); - TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_wrap); + TEST_ASSERT_EQUAL_PTR(ff->buffer + 6, info.linear.ptr); + TEST_ASSERT_EQUAL_PTR(ff->buffer, info.wrapped.ptr); } void test_get_write_info_when_no_wrap() { @@ -278,12 +278,12 @@ void test_get_write_info_when_no_wrap() { tu_fifo_get_write_info(ff, &info); - TEST_ASSERT_EQUAL(FIFO_SIZE - 2, info.len_lin); - TEST_ASSERT_EQUAL(0, info.len_wrap); + TEST_ASSERT_EQUAL(FIFO_SIZE - 2, info.linear.len); + TEST_ASSERT_EQUAL(0, info.wrapped.len); - TEST_ASSERT_EQUAL_PTR(ff->buffer + 2, info.ptr_lin); + TEST_ASSERT_EQUAL_PTR(ff->buffer + 2, info.linear.ptr); // application should check len instead of ptr. - // TEST_ASSERT_NULL(info.ptr_wrap); + // TEST_ASSERT_NULL(info.wrapped.ptr); } void test_get_write_info_when_wrapped() { @@ -300,11 +300,11 @@ void test_get_write_info_when_wrapped() { tu_fifo_get_write_info(ff, &info); - TEST_ASSERT_EQUAL(FIFO_SIZE - 6, info.len_lin); - TEST_ASSERT_EQUAL(2, info.len_wrap); + TEST_ASSERT_EQUAL(FIFO_SIZE - 6, info.linear.len); + TEST_ASSERT_EQUAL(2, info.wrapped.len); - TEST_ASSERT_EQUAL_PTR(ff->buffer + 6, info.ptr_lin); - TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_wrap); + TEST_ASSERT_EQUAL_PTR(ff->buffer + 6, info.linear.ptr); + TEST_ASSERT_EQUAL_PTR(ff->buffer, info.wrapped.ptr); } void test_empty(void) { @@ -314,21 +314,21 @@ void test_empty(void) { // read info tu_fifo_get_read_info(ff, &info); - TEST_ASSERT_EQUAL(0, info.len_lin); - TEST_ASSERT_EQUAL(0, info.len_wrap); + TEST_ASSERT_EQUAL(0, info.linear.len); + TEST_ASSERT_EQUAL(0, info.wrapped.len); - TEST_ASSERT_NULL(info.ptr_lin); - TEST_ASSERT_NULL(info.ptr_wrap); + TEST_ASSERT_NULL(info.linear.ptr); + TEST_ASSERT_NULL(info.wrapped.ptr); // write info tu_fifo_get_write_info(ff, &info); - TEST_ASSERT_EQUAL(FIFO_SIZE, info.len_lin); - TEST_ASSERT_EQUAL(0, info.len_wrap); + TEST_ASSERT_EQUAL(FIFO_SIZE, info.linear.len); + TEST_ASSERT_EQUAL(0, info.wrapped.len); - TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_lin); + TEST_ASSERT_EQUAL_PTR(ff->buffer, info.linear.ptr); // application should check len instead of ptr. - // TEST_ASSERT_NULL(info.ptr_wrap); + // TEST_ASSERT_NULL(info.wrapped.ptr); // write 1 then re-check empty tu_fifo_write(ff, &temp); @@ -347,12 +347,12 @@ void test_full(void) { // read info tu_fifo_get_read_info(ff, &info); - TEST_ASSERT_EQUAL(FIFO_SIZE, info.len_lin); - TEST_ASSERT_EQUAL(0, info.len_wrap); + TEST_ASSERT_EQUAL(FIFO_SIZE, info.linear.len); + TEST_ASSERT_EQUAL(0, info.wrapped.len); - TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_lin); + TEST_ASSERT_EQUAL_PTR(ff->buffer, info.linear.ptr); // skip this, application must check len instead of buffer - // TEST_ASSERT_NULL(info.ptr_wrap); + // TEST_ASSERT_NULL(info.wrapped.ptr); // write info } @@ -511,18 +511,18 @@ void test_get_read_info_advanced_cases(void) { ff->wr_idx = 20; ff->rd_idx = 2; tu_fifo_get_read_info(ff, &info); - TEST_ASSERT_EQUAL(18, info.len_lin); - TEST_ASSERT_EQUAL(0, info.len_wrap); - TEST_ASSERT_EQUAL_PTR(ff->buffer + 2, info.ptr_lin); - TEST_ASSERT_NULL(info.ptr_wrap); + TEST_ASSERT_EQUAL(18, info.linear.len); + TEST_ASSERT_EQUAL(0, info.wrapped.len); + TEST_ASSERT_EQUAL_PTR(ff->buffer + 2, info.linear.ptr); + TEST_ASSERT_NULL(info.wrapped.ptr); ff->wr_idx = 68; // ptr = 4 ff->rd_idx = 56; // ptr = 56 tu_fifo_get_read_info(ff, &info); - TEST_ASSERT_EQUAL(8, info.len_lin); - TEST_ASSERT_EQUAL(4, info.len_wrap); - TEST_ASSERT_EQUAL_PTR(ff->buffer + 56, info.ptr_lin); - TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_wrap); + TEST_ASSERT_EQUAL(8, info.linear.len); + TEST_ASSERT_EQUAL(4, info.wrapped.len); + TEST_ASSERT_EQUAL_PTR(ff->buffer + 56, info.linear.ptr); + TEST_ASSERT_EQUAL_PTR(ff->buffer, info.wrapped.ptr); } void test_get_write_info_advanced_cases(void) { @@ -531,18 +531,18 @@ void test_get_write_info_advanced_cases(void) { ff->wr_idx = 10; ff->rd_idx = 104; // ptr = 40 tu_fifo_get_write_info(ff, &info); - TEST_ASSERT_EQUAL(30, info.len_lin); - TEST_ASSERT_EQUAL(0, info.len_wrap); - TEST_ASSERT_EQUAL_PTR(ff->buffer + 10, info.ptr_lin); - TEST_ASSERT_NULL(info.ptr_wrap); + TEST_ASSERT_EQUAL(30, info.linear.len); + TEST_ASSERT_EQUAL(0, info.wrapped.len); + TEST_ASSERT_EQUAL_PTR(ff->buffer + 10, info.linear.ptr); + TEST_ASSERT_NULL(info.wrapped.ptr); ff->wr_idx = 60; ff->rd_idx = 20; tu_fifo_get_write_info(ff, &info); - TEST_ASSERT_EQUAL(4, info.len_lin); - TEST_ASSERT_EQUAL(20, info.len_wrap); - TEST_ASSERT_EQUAL_PTR(ff->buffer + 60, info.ptr_lin); - TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_wrap); + TEST_ASSERT_EQUAL(4, info.linear.len); + TEST_ASSERT_EQUAL(20, info.wrapped.len); + TEST_ASSERT_EQUAL_PTR(ff->buffer + 60, info.linear.ptr); + TEST_ASSERT_EQUAL_PTR(ff->buffer, info.wrapped.ptr); } void test_correct_read_pointer_cases(void) { -- cgit v1.3.1 From d6c50c7ce2735999e16e05a3da60ff98f8032e96 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 27 Nov 2025 00:03:59 +0700 Subject: add tud_cdc_n_notify_msg() --- src/class/cdc/cdc_device.c | 62 +++++++++++++++++++++++----------------------- src/class/cdc/cdc_device.h | 6 +++++ 2 files changed, 37 insertions(+), 31 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index fbca5b574..a77dfb140 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -66,13 +66,11 @@ typedef struct { #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) -#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || CFG_TUD_CDC_NOTIFY -typedef struct { - // Don't use local EP buffer if dedicated hw FIFO is supported +// Skip local EP buffer if dedicated hw FIFO is supported #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 +typedef struct { TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE); TUD_EPBUF_DEF(epin, CFG_TUD_CDC_EP_BUFSIZE); - #endif #if CFG_TUD_CDC_NOTIFY TUD_EPBUF_TYPE_DEF(cdc_notify_msg_t, epnotify); @@ -172,42 +170,44 @@ void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t *coding) { } #if CFG_TUD_CDC_NOTIFY -bool tud_cdc_n_notify_uart_state (uint8_t itf, const cdc_notify_uart_state_t *state) { +bool tud_cdc_n_notify_msg(uint8_t itf, cdc_notify_msg_t *msg) { TU_VERIFY(itf < CFG_TUD_CDC); - cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[itf]; - TU_VERIFY(tud_ready() && p_cdc->ep_notify != 0); - TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_notify)); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[itf]; + cdc_notify_msg_t *notify_msg = &p_epbuf->epnotify; - cdc_notify_msg_t* notify_msg = &p_epbuf->epnotify; - notify_msg->request.bmRequestType = CDC_REQ_TYPE_NOTIF; - notify_msg->request.bRequest = CDC_NOTIF_SERIAL_STATE; - notify_msg->request.wValue = 0; + *notify_msg = *msg; notify_msg->request.wIndex = p_cdc->itf_num; - notify_msg->request.wLength = sizeof(cdc_notify_uart_state_t); - notify_msg->serial_state = *state; - - return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *)notify_msg, 8 + sizeof(cdc_notify_uart_state_t), false); -} -bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed_change_t* conn_speed_change) { - TU_VERIFY(itf < CFG_TUD_CDC); - cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[itf]; TU_VERIFY(tud_ready() && p_cdc->ep_notify != 0); TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_notify)); + return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *)msg, 8 + msg->request.wLength, false); +} - cdc_notify_msg_t* notify_msg = &p_epbuf->epnotify; - notify_msg->request.bmRequestType = CDC_REQ_TYPE_NOTIF; - notify_msg->request.bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE; - notify_msg->request.wValue = 0; - notify_msg->request.wIndex = p_cdc->itf_num; - notify_msg->request.wLength = sizeof(cdc_notify_conn_speed_change_t); - notify_msg->conn_speed_change = *conn_speed_change; +bool tud_cdc_n_notify_uart_state (uint8_t itf, const cdc_notify_uart_state_t *state) { + cdc_notify_msg_t notify_msg; + notify_msg.request.bmRequestType = CDC_REQ_TYPE_NOTIF; + notify_msg.request.bRequest = CDC_NOTIF_SERIAL_STATE; + notify_msg.request.wValue = 0; + notify_msg.request.wIndex = 0; // filled later + notify_msg.request.wLength = sizeof(cdc_notify_uart_state_t); + notify_msg.serial_state = *state; + + return tud_cdc_n_notify_msg(itf, ¬ify_msg); +} - return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *)notify_msg, 8 + sizeof(cdc_notify_conn_speed_change_t), false); +bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed_change_t* conn_speed_change) { + cdc_notify_msg_t notify_msg; + notify_msg.request.bmRequestType = CDC_REQ_TYPE_NOTIF; + notify_msg.request.bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE; + notify_msg.request.wValue = 0; + notify_msg.request.wIndex = 0; // filled later + notify_msg.request.wLength = sizeof(cdc_notify_conn_speed_change_t); + notify_msg.conn_speed_change = *conn_speed_change; + + return tud_cdc_n_notify_msg(itf, ¬ify_msg); } -#endif + #endif void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { TU_VERIFY(itf < CFG_TUD_CDC, ); diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 8b5761747..6596022df 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -141,12 +141,18 @@ bool tud_cdc_n_write_clear(uint8_t itf); #if CFG_TUD_CDC_NOTIFY +bool tud_cdc_n_notify_msg(uint8_t itf, cdc_notify_msg_t *msg); + // Send UART status notification: DCD, DSR etc .. bool tud_cdc_n_notify_uart_state(uint8_t itf, const cdc_notify_uart_state_t *state); // Send connection speed change notification bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed_change_t* conn_speed_change); +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_notify_msg(cdc_notify_msg_t *msg) { + return tud_cdc_n_notify_msg(0, msg); +} + TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_notify_uart_state(const cdc_notify_uart_state_t* state) { return tud_cdc_n_notify_uart_state(0, state); } -- cgit v1.3.1 From 726497af685b0f1f7f9b03815641c5b977f7d1ed Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 27 Nov 2025 00:16:39 +0700 Subject: omit cdc epnotify for dedicated hw fifo --- src/class/cdc/cdc_device.c | 40 ++++++++++------------------------------ src/class/cdc/cdc_device.h | 24 ++++++++++++++++++++++-- src/class/vendor/vendor_device.c | 22 ++++++++++------------ 3 files changed, 42 insertions(+), 44 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index a77dfb140..7ef8aa738 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -172,42 +172,22 @@ void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t *coding) { #if CFG_TUD_CDC_NOTIFY bool tud_cdc_n_notify_msg(uint8_t itf, cdc_notify_msg_t *msg) { TU_VERIFY(itf < CFG_TUD_CDC); - cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[itf]; - cdc_notify_msg_t *notify_msg = &p_epbuf->epnotify; - - *notify_msg = *msg; - notify_msg->request.wIndex = p_cdc->itf_num; - + const cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; TU_VERIFY(tud_ready() && p_cdc->ep_notify != 0); TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_notify)); - return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *)msg, 8 + msg->request.wLength, false); -} -bool tud_cdc_n_notify_uart_state (uint8_t itf, const cdc_notify_uart_state_t *state) { - cdc_notify_msg_t notify_msg; - notify_msg.request.bmRequestType = CDC_REQ_TYPE_NOTIF; - notify_msg.request.bRequest = CDC_NOTIF_SERIAL_STATE; - notify_msg.request.wValue = 0; - notify_msg.request.wIndex = 0; // filled later - notify_msg.request.wLength = sizeof(cdc_notify_uart_state_t); - notify_msg.serial_state = *state; + #if CFG_TUD_EDPT_DEDICATED_HWFIFO + cdc_notify_msg_t *msg_epbuf = msg; + #else + cdc_notify_msg_t *msg_epbuf = &_cdcd_epbuf[itf].epnotify; + *msg_epbuf = *msg; + #endif - return tud_cdc_n_notify_msg(itf, ¬ify_msg); -} - -bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed_change_t* conn_speed_change) { - cdc_notify_msg_t notify_msg; - notify_msg.request.bmRequestType = CDC_REQ_TYPE_NOTIF; - notify_msg.request.bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE; - notify_msg.request.wValue = 0; - notify_msg.request.wIndex = 0; // filled later - notify_msg.request.wLength = sizeof(cdc_notify_conn_speed_change_t); - notify_msg.conn_speed_change = *conn_speed_change; + msg_epbuf->request.wIndex = p_cdc->itf_num; - return tud_cdc_n_notify_msg(itf, ¬ify_msg); + return usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_notify, (uint8_t *)msg_epbuf, 8 + msg_epbuf->request.wLength, false); } - #endif +#endif void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { TU_VERIFY(itf < CFG_TUD_CDC, ); diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 6596022df..0809b578f 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -144,10 +144,30 @@ bool tud_cdc_n_write_clear(uint8_t itf); bool tud_cdc_n_notify_msg(uint8_t itf, cdc_notify_msg_t *msg); // Send UART status notification: DCD, DSR etc .. -bool tud_cdc_n_notify_uart_state(uint8_t itf, const cdc_notify_uart_state_t *state); +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_n_notify_uart_state(uint8_t itf, + const cdc_notify_uart_state_t *state) { + cdc_notify_msg_t notify_msg; + notify_msg.request.bmRequestType = CDC_REQ_TYPE_NOTIF; + notify_msg.request.bRequest = CDC_NOTIF_SERIAL_STATE; + notify_msg.request.wValue = 0; + notify_msg.request.wIndex = 0; // filled later + notify_msg.request.wLength = sizeof(cdc_notify_uart_state_t); + notify_msg.serial_state = *state; + return tud_cdc_n_notify_msg(itf, ¬ify_msg); +} // Send connection speed change notification -bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed_change_t* conn_speed_change); +TU_ATTR_ALWAYS_INLINE static inline bool +tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed_change_t *conn_speed_change) { + cdc_notify_msg_t notify_msg; + notify_msg.request.bmRequestType = CDC_REQ_TYPE_NOTIF; + notify_msg.request.bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE; + notify_msg.request.wValue = 0; + notify_msg.request.wIndex = 0; // filled later + notify_msg.request.wLength = sizeof(cdc_notify_conn_speed_change_t); + notify_msg.conn_speed_change = *conn_speed_change; + return tud_cdc_n_notify_msg(itf, ¬ify_msg); +} TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_notify_msg(cdc_notify_msg_t *msg) { return tud_cdc_n_notify_msg(0, msg); diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 7da4d2239..ee6cd7105 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -162,23 +162,21 @@ void vendord_init(void) { vendord_interface_t* p_itf = &_vendord_itf[i]; vendord_epbuf_t* p_epbuf = &_vendord_epbuf[i]; - uint8_t* rx_ff_buf = - #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - p_itf->rx.ff_buf; - #else - NULL; - #endif + #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 + uint8_t *rx_ff_buf = p_itf->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); - 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 + uint8_t *tx_ff_buf = p_itf->tx.ff_buf; + #else + 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, -- cgit v1.3.1 From 9a9bf0fd7b5a005fd4701ab6cb5b1728ecc0baa2 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 27 Nov 2025 18:41:57 +0700 Subject: change tud_vendor_rx_cb() behavior, buffer and bufsize only available when CFG_TUD_VENDOR_RX_BUFSIZE = 0 update vendor device to omit ep buf when dedicated hwfifo is supported --- examples/device/webusb_serial/src/main.c | 15 ++++++----- src/class/cdc/cdc_device.c | 11 +++----- src/class/vendor/vendor_device.c | 45 +++++++++++++++++++++++++------- src/class/vendor/vendor_device.h | 9 ++++--- src/common/tusb_types.h | 5 ++++ src/tusb.c | 25 +++++++++++------- 6 files changed, 73 insertions(+), 37 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c index 4fcddd724..50794bdba 100644 --- a/examples/device/webusb_serial/src/main.c +++ b/examples/device/webusb_serial/src/main.c @@ -211,15 +211,16 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ return false; } -void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint16_t bufsize) { +void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint32_t bufsize) { (void)idx; + (void)buffer; + (void)bufsize; -// since we used data without pulling it from RX FIFO, we need to discard number of items used -#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 - tud_vendor_read_discard(bufsize); -#endif - - echo_all(buffer, bufsize); + while (tud_vendor_available()) { + uint8_t buf[64]; + const uint32_t count = tud_vendor_read(buf, sizeof(buf)); + echo_all(buf, count); + } } //--------------------------------------------------------------------+ 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 c2393c25d..bb736aba8 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -59,20 +59,30 @@ typedef struct { 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 idx, const uint8_t *buffer, uint16_t 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; + (void)buffer; + (void)bufsize; } TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t idx, uint32_t sent_bytes) { @@ -153,7 +163,19 @@ void vendord_init(void) { for(uint8_t i=0; i 0 uint8_t *rx_ff_buf = p_itf->stream.rx_ff_buf; @@ -161,7 +183,7 @@ void vendord_init(void) { uint8_t *rx_ff_buf = NULL; #endif - tu_edpt_stream_init(&p_itf->stream.rx, false, false, false, rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, p_epbuf->epout, + 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 @@ -170,7 +192,7 @@ void vendord_init(void) { uint8_t *tx_ff_buf = NULL; #endif - tu_edpt_stream_init(&p_itf->stream.tx, false, true, false, tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, p_epbuf->epin, + 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); } } @@ -264,16 +286,19 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint const uint8_t idx = find_vendor_itf(ep_addr); TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_vendor = &_vendord_itf[idx]; - vendord_epbuf_t *p_epbuf = &_vendord_epbuf[idx]; 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->stream.rx, xferred_bytes); - // Invoked callback if any - tud_vendor_rx_cb(idx, 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->stream.rx); + tu_edpt_stream_read_xfer(rhport, &p_vendor->stream.rx); // prepare next data } else if (ep_addr == p_vendor->stream.tx.ep_addr) { // Send complete tud_vendor_tx_cb(idx, (uint16_t)xferred_bytes); diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index e9dec788b..05de84f20 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -121,9 +121,12 @@ 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 idx, const uint8_t *buffer, uint16_t bufsize); -// Invoked when last rx transfer finished +// 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); //--------------------------------------------------------------------+ diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 73c816e3e..d473e53e6 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -323,6 +323,11 @@ typedef struct { tusb_speed_t speed; } tusb_rhport_init_t; +typedef struct { + uint16_t len; + uint8_t *buffer; +} tusb_buffer_t; + //--------------------------------------------------------------------+ // USB Descriptors //--------------------------------------------------------------------+ diff --git a/src/tusb.c b/src/tusb.c index 2d122885b..94121b174 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -450,12 +450,19 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buf TU_VERIFY(bufsize > 0); // TODO support ZLP if (0 == tu_fifo_depth(&s->ff)) { - // non-fifo mode, ep_buf must be valid - TU_VERIFY(s->ep_buf != NULL, 0); + // non-fifo mode TU_VERIFY(stream_claim(hwid, s), 0); - const uint32_t xact_len = tu_min32(bufsize, s->ep_bufsize); - memcpy(s->ep_buf, buffer, xact_len); + uint32_t xact_len; + if (s->ep_buf != NULL) { + // using ep buf + xact_len = tu_min32(bufsize, s->ep_bufsize); + memcpy(s->ep_buf, buffer, xact_len); + } else { + // using hwfifo + xact_len = bufsize; + } TU_ASSERT(stream_xfer(hwid, s, (uint16_t) xact_len), 0); + return xact_len; } else { const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); @@ -494,7 +501,8 @@ uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s) { //--------------------------------------------------------------------+ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s) { if (0 == tu_fifo_depth(&s->ff)) { - // non-fifo mode + // non-fifo mode: RX need ep buffer + TU_VERIFY(s->ep_buf != NULL, 0); TU_VERIFY(stream_claim(hwid, s), 0); TU_ASSERT(stream_xfer(hwid, s, s->ep_bufsize), 0); return s->ep_bufsize; @@ -507,11 +515,8 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s) { // and slowly move it to the FIFO when read(). // This pre-check reduces endpoint claiming TU_VERIFY(available >= mps); - TU_VERIFY(stream_claim(hwid, s), 0); - - // get available again since fifo can be changed before endpoint is claimed - available = tu_fifo_remaining(&s->ff); + available = tu_fifo_remaining(&s->ff); // re-get available since fifo can be changed if (available >= mps) { // multiple of packet size limit by ep bufsize @@ -532,7 +537,7 @@ uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, ui if (tu_fifo_depth(&s->ff) > 0) { num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t)bufsize); } else { - // non-fifo mode + // non-fifo mode not support this num_read = 0; } -- cgit v1.3.1 From f1fc4c9c796e25111ad8249a4dab9245f5091c25 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Dec 2025 14:45:06 +0700 Subject: change tu_fifo_clear()/tu_edpt_stream_clear() from return bool to void --- .gitignore | 4 ++-- src/class/audio/audio_device.c | 6 ++++-- src/class/cdc/cdc_device.c | 3 ++- src/class/cdc/cdc_host.c | 7 ++++--- src/common/tusb_fifo.c | 3 +-- src/common/tusb_fifo.h | 2 +- src/common/tusb_private.h | 16 +++++++++++++--- src/tusb.c | 13 ------------- 8 files changed, 27 insertions(+), 27 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/.gitignore b/.gitignore index 93d13503f..162f9a019 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,8 @@ settings/ /examples/*/*/build* test_old/ tests_obsolete/ -_build +_build/ +build/ /examples/*/*/ses /examples/*/*/ozone /examples/obsolete @@ -47,7 +48,6 @@ cmake-build-* sdkconfig .PVS-Studio .vscode/ -build CMakeFiles Debug RelWithDebInfo diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 1dda8af99..77ef54222 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -485,7 +485,8 @@ uint16_t tud_audio_n_read(uint8_t func_id, void *buffer, uint16_t bufsize) { bool tud_audio_n_clear_ep_out_ff(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); - return tu_fifo_clear(&_audiod_fct[func_id].ep_out_ff); + tu_fifo_clear(&_audiod_fct[func_id].ep_out_ff); + return true; } tu_fifo_t *tud_audio_n_get_ep_out_ff(uint8_t func_id) { @@ -536,7 +537,8 @@ uint16_t tud_audio_n_write(uint8_t func_id, const void *data, uint16_t len) { bool tud_audio_n_clear_ep_in_ff(uint8_t func_id) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); - return tu_fifo_clear(&_audiod_fct[func_id].ep_in_ff); + tu_fifo_clear(&_audiod_fct[func_id].ep_in_ff); + return true; } tu_fifo_t *tud_audio_n_get_ep_in_ff(uint8_t func_id) { diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index d7792afe4..a446782e3 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -244,7 +244,8 @@ uint32_t tud_cdc_n_write_available(uint8_t itf) { bool tud_cdc_n_write_clear(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_clear(&p_cdc->stream.tx); + tu_edpt_stream_clear(&p_cdc->stream.tx); + return true; } //--------------------------------------------------------------------+ diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 35717ddf6..e069d9f71 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -482,7 +482,8 @@ uint32_t tuh_cdc_write_flush(uint8_t idx) { bool tuh_cdc_write_clear(uint8_t idx) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_clear(&p_cdc->stream.tx); + tu_edpt_stream_clear(&p_cdc->stream.tx); + return true; } uint32_t tuh_cdc_write_available(uint8_t idx) { @@ -517,9 +518,9 @@ bool tuh_cdc_read_clear (uint8_t idx) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - bool ret = tu_edpt_stream_clear(&p_cdc->stream.rx); + tu_edpt_stream_clear(&p_cdc->stream.rx); (void)tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); - return ret; + return true; } //--------------------------------------------------------------------+ diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 06b0d6a58..1313fc328 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -84,7 +84,7 @@ bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_si } // clear fifo by resetting read and write indices -bool tu_fifo_clear(tu_fifo_t *f) { +void tu_fifo_clear(tu_fifo_t *f) { ff_lock(f->mutex_wr); ff_lock(f->mutex_rd); @@ -93,7 +93,6 @@ bool tu_fifo_clear(tu_fifo_t *f) { ff_unlock(f->mutex_wr); ff_unlock(f->mutex_rd); - return true; } // Change the fifo overwritable mode diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 94ab421bb..5bc05b56c 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -158,7 +158,7 @@ typedef enum { //--------------------------------------------------------------------+ bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_size, bool overwritable); bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable); -bool tu_fifo_clear(tu_fifo_t *f); +void tu_fifo_clear(tu_fifo_t *f); #if OSAL_MUTEX_REQUIRED TU_ATTR_ALWAYS_INLINE static inline diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 0e9eef732..df518d5ff 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -108,7 +108,17 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize); // Deinit an endpoint stream -bool tu_edpt_stream_deinit(tu_edpt_stream_t* s); +TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_deinit(tu_edpt_stream_t *s) { + (void)s; +#if OSAL_MUTEX_REQUIRED + if (s->ff.mutex_wr) { + osal_mutex_delete(s->ff.mutex_wr); + } + if (s->ff.mutex_rd) { + osal_mutex_delete(s->ff.mutex_rd); + } +#endif +} // Open an endpoint stream TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { @@ -124,8 +134,8 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_close(tu_edpt_stream_t* s->ep_addr = 0; } -TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_clear(tu_edpt_stream_t* s) { - return tu_fifo_clear(&s->ff); +TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_clear(tu_edpt_stream_t *s) { + tu_fifo_clear(&s->ff); } TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_empty(tu_edpt_stream_t *s) { diff --git a/src/tusb.c b/src/tusb.c index ecdd569c4..fef5b1b75 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -358,19 +358,6 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove return true; } -bool tu_edpt_stream_deinit(tu_edpt_stream_t *s) { - (void)s; - #if OSAL_MUTEX_REQUIRED - if (s->ff.mutex_wr) { - osal_mutex_delete(s->ff.mutex_wr); - } - if (s->ff.mutex_rd) { - osal_mutex_delete(s->ff.mutex_rd); - } - #endif - return true; -} - static bool stream_claim(uint8_t hwid, tu_edpt_stream_t *s) { if (s->is_host) { #if CFG_TUH_ENABLED -- cgit v1.3.1 From fcc300770d9df7fdbefc2f899b63ef8fcb274b80 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Dec 2025 14:57:11 +0700 Subject: flatten cdc tx,rx stream --- src/class/cdc/cdc_device.c | 62 ++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 32 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index a446782e3..dfdee8bd4 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -55,13 +55,11 @@ typedef struct { TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; char wanted_char; - struct { - tu_edpt_stream_t tx; - tu_edpt_stream_t rx; + tu_edpt_stream_t tx_stream; + tu_edpt_stream_t rx_stream; - uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE]; - uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE]; - } stream; + uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE]; + uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE]; } cdcd_interface_t; #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) @@ -125,7 +123,7 @@ static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT(); TU_ATTR_ALWAYS_INLINE static inline uint8_t find_cdc_itf(uint8_t ep_addr) { for (uint8_t idx = 0; idx < CFG_TUD_CDC; idx++) { const cdcd_interface_t *p_cdc = &_cdcd_itf[idx]; - if (ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr || + if (ep_addr == p_cdc->rx_stream.ep_addr || ep_addr == p_cdc->tx_stream.ep_addr || (ep_addr == p_cdc->ep_notify && ep_addr != 0)) { return idx; } @@ -147,8 +145,8 @@ bool tud_cdc_n_ready(uint8_t itf) { TU_VERIFY(tud_ready()); const cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - const bool in_opened = tu_edpt_stream_is_opened(&p_cdc->stream.tx); - const bool out_opened = tu_edpt_stream_is_opened(&p_cdc->stream.rx); + const bool in_opened = tu_edpt_stream_is_opened(&p_cdc->tx_stream); + const bool out_opened = tu_edpt_stream_is_opened(&p_cdc->rx_stream); return in_opened && out_opened; } @@ -199,25 +197,25 @@ void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { //--------------------------------------------------------------------+ uint32_t tud_cdc_n_available(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); - return tu_edpt_stream_read_available(&_cdcd_itf[itf].stream.rx); + return tu_edpt_stream_read_available(&_cdcd_itf[itf].rx_stream); } uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_read(p_cdc->rhport, &p_cdc->stream.rx, buffer, bufsize); + return tu_edpt_stream_read(p_cdc->rhport, &p_cdc->rx_stream, buffer, bufsize); } bool tud_cdc_n_peek(uint8_t itf, uint8_t *chr) { TU_VERIFY(itf < CFG_TUD_CDC); - return tu_edpt_stream_peek(&_cdcd_itf[itf].stream.rx, chr); + return tu_edpt_stream_peek(&_cdcd_itf[itf].rx_stream, chr); } void tud_cdc_n_read_flush(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, ); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - tu_edpt_stream_clear(&p_cdc->stream.rx); - tu_edpt_stream_read_xfer(p_cdc->rhport, &p_cdc->stream.rx); + tu_edpt_stream_clear(&p_cdc->rx_stream); + tu_edpt_stream_read_xfer(p_cdc->rhport, &p_cdc->rx_stream); } //--------------------------------------------------------------------+ @@ -226,25 +224,25 @@ void tud_cdc_n_read_flush(uint8_t itf) { uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_write(p_cdc->rhport, &p_cdc->stream.tx, buffer, bufsize); + return tu_edpt_stream_write(p_cdc->rhport, &p_cdc->tx_stream, buffer, bufsize); } uint32_t tud_cdc_n_write_flush(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_write_xfer(p_cdc->rhport, &p_cdc->stream.tx); + return tu_edpt_stream_write_xfer(p_cdc->rhport, &p_cdc->tx_stream); } uint32_t tud_cdc_n_write_available(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_write_available(p_cdc->rhport, &p_cdc->stream.tx); + return tu_edpt_stream_write_available(p_cdc->rhport, &p_cdc->tx_stream); } bool tud_cdc_n_write_clear(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - tu_edpt_stream_clear(&p_cdc->stream.tx); + tu_edpt_stream_clear(&p_cdc->tx_stream); return true; } @@ -271,22 +269,22 @@ void cdcd_init(void) { 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, + tu_edpt_stream_init(&p_cdc->rx_stream, false, false, false, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, epout_buf, CFG_TUD_CDC_EP_BUFSIZE); // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not // know if data is actually polled by terminal. This way the most current data is prioritized. // Default: is overwritable - tu_edpt_stream_init(&p_cdc->stream.tx, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, - p_cdc->stream.tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE); + tu_edpt_stream_init(&p_cdc->tx_stream, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, + p_cdc->tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE); } } bool cdcd_deinit(void) { for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { cdcd_interface_t* p_cdc = &_cdcd_itf[i]; - tu_edpt_stream_deinit(&p_cdc->stream.rx); - tu_edpt_stream_deinit(&p_cdc->stream.tx); + tu_edpt_stream_deinit(&p_cdc->rx_stream); + tu_edpt_stream_deinit(&p_cdc->tx_stream); } return true; } @@ -298,9 +296,9 @@ void cdcd_reset(uint8_t rhport) { cdcd_interface_t* p_cdc = &_cdcd_itf[i]; tu_memclr(p_cdc, ITF_MEM_RESET_SIZE); - tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, _cdcd_cfg.tx_overwritabe_if_not_connected); // back to default - tu_edpt_stream_close(&p_cdc->stream.rx); - tu_edpt_stream_close(&p_cdc->stream.tx); + tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, _cdcd_cfg.tx_overwritabe_if_not_connected); // back to default + tu_edpt_stream_close(&p_cdc->rx_stream); + tu_edpt_stream_close(&p_cdc->tx_stream); } } @@ -351,7 +349,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_t *stream_tx = &p_cdc->stream.tx; + tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; tu_edpt_stream_open(stream_tx, desc_ep); if (_cdcd_cfg.tx_persistent) { @@ -360,7 +358,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 tu_edpt_stream_clear(stream_tx); } } else { - tu_edpt_stream_t *stream_rx = &p_cdc->stream.rx; + tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; tu_edpt_stream_open(stream_rx, desc_ep); if (!_cdcd_cfg.rx_persistent) { @@ -431,9 +429,9 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ // If enabled: fifo overwriting is disabled if DTR bit is set and vice versa if (_cdcd_cfg.tx_overwritabe_if_not_connected) { - tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, !dtr); + tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, !dtr); } else { - tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, false); + tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, false); } TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); @@ -467,8 +465,8 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ uint8_t itf = find_cdc_itf(ep_addr); TU_ASSERT(itf < CFG_TUD_CDC); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - tu_edpt_stream_t *stream_rx = &p_cdc->stream.rx; - tu_edpt_stream_t *stream_tx = &p_cdc->stream.tx; + tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; + tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; // Received new data, move to fifo if (ep_addr == stream_rx->ep_addr) { -- cgit v1.3.1 From 39853dfb25c8828490e197ad4c1dd9616949110a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Dec 2025 20:47:08 +0700 Subject: move hwid into edpt stream for consistent API --- src/class/cdc/cdc_device.c | 33 ++++++++-------- src/class/cdc/cdc_host.c | 20 +++++----- src/class/midi/midi_device.c | 35 +++++++++-------- src/class/midi/midi_host.c | 32 ++++++++-------- src/class/vendor/vendor_device.c | 29 +++++++------- src/common/tusb_private.h | 28 +++++++------- src/device/usbd.c | 14 +++---- src/tusb.c | 83 ++++++++++++++++++++-------------------- 8 files changed, 139 insertions(+), 135 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index dfdee8bd4..8ea4080cc 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -203,7 +203,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) { uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_read(p_cdc->rhport, &p_cdc->rx_stream, buffer, bufsize); + return tu_edpt_stream_read(&p_cdc->rx_stream, buffer, bufsize); } bool tud_cdc_n_peek(uint8_t itf, uint8_t *chr) { @@ -215,7 +215,7 @@ void tud_cdc_n_read_flush(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, ); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; tu_edpt_stream_clear(&p_cdc->rx_stream); - tu_edpt_stream_read_xfer(p_cdc->rhport, &p_cdc->rx_stream); + tu_edpt_stream_read_xfer(&p_cdc->rx_stream); } //--------------------------------------------------------------------+ @@ -224,19 +224,19 @@ void tud_cdc_n_read_flush(uint8_t itf) { uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_write(p_cdc->rhport, &p_cdc->tx_stream, buffer, bufsize); + return tu_edpt_stream_write(&p_cdc->tx_stream, buffer, bufsize); } uint32_t tud_cdc_n_write_flush(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_write_xfer(p_cdc->rhport, &p_cdc->tx_stream); + return tu_edpt_stream_write_xfer(&p_cdc->tx_stream); } uint32_t tud_cdc_n_write_available(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_write_available(p_cdc->rhport, &p_cdc->tx_stream); + return tu_edpt_stream_write_available(&p_cdc->tx_stream); } bool tud_cdc_n_write_clear(uint8_t itf) { @@ -269,14 +269,14 @@ void cdcd_init(void) { uint8_t *epin_buf = _cdcd_epbuf[i].epin; #endif - tu_edpt_stream_init(&p_cdc->rx_stream, false, false, false, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, - epout_buf, CFG_TUD_CDC_EP_BUFSIZE); + tu_edpt_stream_init(&p_cdc->rx_stream, false, false, false, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, epout_buf, + CFG_TUD_CDC_EP_BUFSIZE); // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not // know if data is actually polled by terminal. This way the most current data is prioritized. // Default: is overwritable - tu_edpt_stream_init(&p_cdc->tx_stream, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, - p_cdc->tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE); + tu_edpt_stream_init(&p_cdc->tx_stream, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, p_cdc->tx_ff_buf, + CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE); } } @@ -351,20 +351,20 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; - tu_edpt_stream_open(stream_tx, desc_ep); + tu_edpt_stream_open(stream_tx, rhport, desc_ep); if (_cdcd_cfg.tx_persistent) { - tu_edpt_stream_write_xfer(rhport, stream_tx); // flush pending data + tu_edpt_stream_write_xfer(stream_tx); // flush pending data } else { tu_edpt_stream_clear(stream_tx); } } else { tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; - tu_edpt_stream_open(stream_rx, desc_ep); + tu_edpt_stream_open(stream_rx, rhport, desc_ep); if (!_cdcd_cfg.rx_persistent) { tu_edpt_stream_clear(stream_rx); } - TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare for incoming data + TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare for incoming data } } @@ -460,6 +460,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ } bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void)rhport; (void)result; uint8_t itf = find_cdc_itf(ep_addr); @@ -510,7 +511,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ tud_cdc_rx_cb(itf); } - tu_edpt_stream_read_xfer(rhport, stream_rx); // prepare for more data + tu_edpt_stream_read_xfer(stream_rx); // prepare for more data } // Data sent to host, we continue to fetch from tx fifo to send. @@ -518,9 +519,9 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (ep_addr == stream_tx->ep_addr) { tud_cdc_tx_complete_cb(itf); // invoke callback to possibly refill tx fifo - if (0 == tu_edpt_stream_write_xfer(rhport, stream_tx)) { + if (0 == tu_edpt_stream_write_xfer(stream_tx)) { // If there is no data left, a ZLP should be sent if needed - tu_edpt_stream_write_zlp_if_needed(rhport, stream_tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(stream_tx, xferred_bytes); } } diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index e069d9f71..28abbf098 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -470,13 +470,13 @@ bool tuh_cdc_get_line_coding_local(uint8_t idx, cdc_line_coding_t * line_coding) uint32_t tuh_cdc_write(uint8_t idx, void const * buffer, uint32_t bufsize) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write(p_cdc->daddr, &p_cdc->stream.tx, buffer, bufsize); + return tu_edpt_stream_write(&p_cdc->stream.tx, buffer, bufsize); } uint32_t tuh_cdc_write_flush(uint8_t idx) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx); + return tu_edpt_stream_write_xfer(&p_cdc->stream.tx); } bool tuh_cdc_write_clear(uint8_t idx) { @@ -489,7 +489,7 @@ bool tuh_cdc_write_clear(uint8_t idx) { uint32_t tuh_cdc_write_available(uint8_t idx) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write_available(p_cdc->daddr, &p_cdc->stream.tx); + return tu_edpt_stream_write_available(&p_cdc->stream.tx); } //--------------------------------------------------------------------+ @@ -499,7 +499,7 @@ uint32_t tuh_cdc_write_available(uint8_t idx) { uint32_t tuh_cdc_read (uint8_t idx, void * buffer, uint32_t bufsize) { cdch_interface_t * p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_read(p_cdc->daddr, &p_cdc->stream.rx, buffer, bufsize); + return tu_edpt_stream_read(&p_cdc->stream.rx, buffer, bufsize); } uint32_t tuh_cdc_read_available(uint8_t idx) { @@ -519,7 +519,7 @@ bool tuh_cdc_read_clear (uint8_t idx) { TU_VERIFY(p_cdc); tu_edpt_stream_clear(&p_cdc->stream.rx); - (void)tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); + (void)tu_edpt_stream_read_xfer(&p_cdc->stream.rx); return true; } @@ -693,10 +693,10 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t if (ep_addr == p_cdc->stream.tx.ep_addr) { tuh_cdc_tx_complete_cb(idx); // invoke transmit complete callback - if (0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx)) { + if (0 == tu_edpt_stream_write_xfer(&p_cdc->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 - (void)tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes); + (void)tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes); } } else if (ep_addr == p_cdc->stream.rx.ep_addr) { #if CFG_TUH_CDC_FTDI @@ -716,7 +716,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t } // prepare for next transfer if needed - tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); + tu_edpt_stream_read_xfer(&p_cdc->stream.rx); } else if (ep_addr == p_cdc->ep_notif) { // TODO handle notification endpoint } else { @@ -736,7 +736,7 @@ static bool open_ep_stream_pair(cdch_interface_t *p_cdc, tusb_desc_endpoint_t co TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); tu_edpt_stream_t *stream = (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) ? &p_cdc->stream.rx : &p_cdc->stream.tx; - tu_edpt_stream_open(stream, desc_ep); + tu_edpt_stream_open(stream, p_cdc->daddr, desc_ep); tu_edpt_stream_clear(stream); desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_ep); @@ -799,7 +799,7 @@ static void set_config_complete(cdch_interface_t *p_cdc, bool success) { p_cdc->mounted = true; tuh_cdc_mount_cb(idx); // Prepare for incoming data - tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); + tu_edpt_stream_read_xfer(&p_cdc->stream.rx); } else { // clear the interface entry p_cdc->daddr = 0; diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 8d1dc7d4a..e0a5aa9c3 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -172,7 +172,7 @@ bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]) { midid_interface_t *p_midi = &_midid_itf[itf]; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; TU_VERIFY(tu_edpt_stream_is_opened(ep_str)); - return 4 == tu_edpt_stream_read(p_midi->rhport, ep_str, packet, 4); + return 4 == tu_edpt_stream_read(ep_str, packet, 4); } uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_packets) { @@ -180,7 +180,7 @@ uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_p tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0); - const uint32_t num_read = tu_edpt_stream_read(p_midi->rhport, ep_str, packets, 4u * max_packets); + const uint32_t num_read = tu_edpt_stream_read(ep_str, packets, 4u * max_packets); return num_read >> 2u; } @@ -195,7 +195,7 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t * uint32_t i = 0; while (i < bufsize) { - if (tu_edpt_stream_write_available(p_midi->rhport, ep_str) < 4) { + if (tu_edpt_stream_write_available(ep_str) < 4) { break; } @@ -268,7 +268,7 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t * stream->buffer[idx] = 0; } - const uint32_t count = tu_edpt_stream_write(p_midi->rhport, ep_str, stream->buffer, 4); + const uint32_t count = tu_edpt_stream_write(ep_str, stream->buffer, 4); // complete current event packet, reset stream stream->index = stream->total = 0; @@ -278,7 +278,7 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t * } } - (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str); + (void)tu_edpt_stream_write_xfer(ep_str); return i; } @@ -288,9 +288,9 @@ bool tud_midi_n_packet_write (uint8_t itf, const uint8_t packet[4]) { tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx; TU_VERIFY(tu_edpt_stream_is_opened(ep_str)); - TU_VERIFY(tu_edpt_stream_write_available(p_midi->rhport, ep_str) >= 4); - TU_VERIFY(tu_edpt_stream_write(p_midi->rhport, ep_str, packet, 4) > 0); - (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str); + TU_VERIFY(tu_edpt_stream_write_available(ep_str) >= 4); + TU_VERIFY(tu_edpt_stream_write(ep_str, packet, 4) > 0); + (void)tu_edpt_stream_write_xfer(ep_str); return true; } @@ -300,11 +300,11 @@ uint32_t tud_midi_n_packet_write_n(uint8_t itf, const uint8_t packets[], uint32_ tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx; TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0); - uint32_t n_bytes = tu_edpt_stream_write_available(p_midi->rhport, ep_str); + uint32_t n_bytes = tu_edpt_stream_write_available(ep_str); n_bytes = tu_min32(tu_align4(n_bytes), n_packets << 2u); - const uint32_t n_write = tu_edpt_stream_write(p_midi->rhport, ep_str, packets, n_bytes); - (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str); + const uint32_t n_write = tu_edpt_stream_write(ep_str, packets, n_bytes); + (void)tu_edpt_stream_write_xfer(ep_str); return n_write >> 2u; } @@ -411,13 +411,13 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint1 if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_midi->ep_stream.tx; - tu_edpt_stream_open(stream_tx, desc_ep); + tu_edpt_stream_open(stream_tx, rhport, desc_ep); tu_edpt_stream_clear(stream_tx); } else { tu_edpt_stream_t *stream_rx = &p_midi->ep_stream.rx; - tu_edpt_stream_open(stream_rx, desc_ep); + tu_edpt_stream_open(stream_rx, rhport, desc_ep); tu_edpt_stream_clear(stream_rx); - TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare to receive data + TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare to receive data } p_desc = tu_desc_next(p_desc); // skip CS Endpoint descriptor @@ -439,6 +439,7 @@ bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_req } bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void)rhport; (void)result; uint8_t idx = find_midi_itf(ep_addr); @@ -454,12 +455,12 @@ bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32 tu_edpt_stream_read_xfer_complete(ep_st_rx, xferred_bytes); tud_midi_rx_cb(idx); // invoke callback } - tu_edpt_stream_read_xfer(rhport, ep_st_rx); // prepare for next data + tu_edpt_stream_read_xfer(ep_st_rx); // prepare for next data } else if (ep_addr == ep_st_tx->ep_addr && result == XFER_RESULT_SUCCESS) { // sent complete: try to send more if possible - if (0 == tu_edpt_stream_write_xfer(rhport, ep_st_tx)) { + if (0 == tu_edpt_stream_write_xfer(ep_st_tx)) { // If there is no data left, a ZLP should be sent if needed - (void)tu_edpt_stream_write_zlp_if_needed(rhport, ep_st_tx, xferred_bytes); + (void)tu_edpt_stream_write_zlp_if_needed(ep_st_tx, xferred_bytes); } } else { return false; diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index 07062875c..b4f5ac445 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -175,14 +175,14 @@ bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint tuh_midi_rx_cb(idx, xferred_bytes); } - tu_edpt_stream_read_xfer(dev_addr, ep_str_rx); // prepare for next transfer + tu_edpt_stream_read_xfer(ep_str_rx); // prepare for next transfer } else if (ep_addr == ep_str_tx->ep_addr) { tuh_midi_tx_cb(idx, xferred_bytes); - if (0 == tu_edpt_stream_write_xfer(dev_addr, ep_str_tx)) { + if (0 == tu_edpt_stream_write_xfer(ep_str_tx)) { // If there is no data left, a ZLP should be sent if // xferred_bytes is multiple of EP size and not zero - tu_edpt_stream_write_zlp_if_needed(dev_addr, ep_str_tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(ep_str_tx, xferred_bytes); } } @@ -303,7 +303,7 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d ep_stream = &p_midi->ep_stream.rx; } TU_ASSERT(tuh_edpt_open(dev_addr, p_ep)); - tu_edpt_stream_open(ep_stream, p_ep); + tu_edpt_stream_open(ep_stream, dev_addr, p_ep); tu_edpt_stream_clear(ep_stream); break; @@ -335,7 +335,7 @@ bool midih_set_config(uint8_t dev_addr, uint8_t itf_num) { }; tuh_midi_mount_cb(idx, &mount_cb_data); - tu_edpt_stream_read_xfer(dev_addr, &p_midi->ep_stream.rx); // prepare for incoming data + tu_edpt_stream_read_xfer(&p_midi->ep_stream.rx); // prepare for incoming data // No special config things to do for MIDI usbh_driver_set_config_complete(dev_addr, p_midi->bInterfaceNumber); @@ -414,7 +414,7 @@ uint32_t tuh_midi_read_available(uint8_t idx) { uint32_t tuh_midi_write_flush(uint8_t idx) { TU_VERIFY(idx < CFG_TUH_MIDI); midih_interface_t *p_midi = &_midi_host[idx]; - return tu_edpt_stream_write_xfer(p_midi->daddr, &p_midi->ep_stream.tx); + return tu_edpt_stream_write_xfer(&p_midi->ep_stream.tx); } //--------------------------------------------------------------------+ @@ -427,7 +427,7 @@ uint32_t tuh_midi_packet_read_n(uint8_t idx, uint8_t* buffer, uint32_t bufsize) uint32_t count4 = tu_min32(bufsize, tu_edpt_stream_read_available(&p_midi->ep_stream.rx)); count4 = tu_align4(count4); // round down to multiple of 4 TU_VERIFY(count4 > 0, 0); - return tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, buffer, count4); + return tu_edpt_stream_read(&p_midi->ep_stream.rx, buffer, count4); } uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t* buffer, uint32_t bufsize) { @@ -436,7 +436,7 @@ uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t* buffer, uint32_t bu const uint32_t bufsize4 = tu_align4(bufsize); TU_VERIFY(bufsize4 > 0, 0); - return tu_edpt_stream_write(p_midi->daddr, &p_midi->ep_stream.tx, buffer, bufsize4); + return tu_edpt_stream_write(&p_midi->ep_stream.tx, buffer, bufsize4); } //--------------------------------------------------------------------+ @@ -450,8 +450,8 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu midi_driver_stream_t *stream = &p_midi->stream_write; uint32_t byte_count = 0; - while ((byte_count < bufsize) && (tu_edpt_stream_write_available(p_midi->daddr, &p_midi->ep_stream.tx) >= 4)) { - uint8_t const data = buffer[byte_count]; + while ((byte_count < bufsize) && (tu_edpt_stream_write_available(&p_midi->ep_stream.tx) >= 4)) { + const uint8_t data = buffer[byte_count]; byte_count++; if (data >= MIDI_STATUS_SYSREAL_TIMING_CLOCK) { // real-time messages need to be sent right away @@ -460,7 +460,7 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu streamrt.buffer[1] = data; streamrt.index = 2; streamrt.total = 2; - uint32_t const count = tu_edpt_stream_write(p_midi->daddr, &p_midi->ep_stream.tx, streamrt.buffer, 4); + const uint32_t count = tu_edpt_stream_write(&p_midi->ep_stream.tx, streamrt.buffer, 4); TU_ASSERT(count == 4, byte_count); // Check FIFO overflown, since we already check fifo remaining. It is probably race condition } else if (stream->index == 0) { //------------- New event packet -------------// @@ -529,7 +529,7 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu } TU_LOG3_MEM(stream->buffer, 4, 2); - const uint32_t count = tu_edpt_stream_write(p_midi->daddr, &p_midi->ep_stream.tx, stream->buffer, 4); + const uint32_t count = tu_edpt_stream_write(&p_midi->ep_stream.tx, stream->buffer, 4); // complete current event packet, reset stream stream->index = 0; @@ -551,7 +551,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff return 0; } *p_cable_num = (one_byte >> 4) & 0xf; - uint32_t nread = tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); + uint32_t nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); static uint16_t cable_sysex_in_progress;// bit i is set if received MIDI_STATUS_SYSEX_START but not MIDI_STATUS_SYSEX_END while (nread == 4 && bytes_buffered < bufsize) { *p_cable_num = (p_midi->stream_read.buffer[0] >> 4) & 0x0f; @@ -579,7 +579,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff } else { // bad packet discard - nread = tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); + nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); continue; } } else if (status < MIDI_STATUS_SYSEX_START) { @@ -626,7 +626,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff } else { // bad packet discard - nread = tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); + nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); continue; } @@ -639,7 +639,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff uint8_t new_cable = (one_byte >> 4) & 0xf; if (new_cable == *p_cable_num) { // still on the same cable. Continue reading the stream - nread = tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); + nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4); } } } diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index eb78a13c4..9972911e0 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -119,14 +119,14 @@ bool tud_vendor_n_peek(uint8_t idx, uint8_t *u8) { 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); + return tu_edpt_stream_read(&p_itf->stream.rx, buffer, bufsize); } 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); + tu_edpt_stream_read_xfer(&p_itf->stream.rx); } #endif @@ -134,7 +134,7 @@ void tud_vendor_n_read_flush(uint8_t idx) { 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); + return tu_edpt_stream_read_xfer(&p_itf->stream.rx); } #endif @@ -145,20 +145,20 @@ bool tud_vendor_n_read_xfer(uint8_t idx) { 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); + return tu_edpt_stream_write(&p_itf->stream.tx, buffer, (uint16_t)bufsize); } #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); + return tu_edpt_stream_write_xfer(&p_itf->stream.tx); } 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); + return tu_edpt_stream_write_available(&p_itf->stream.tx); } #endif @@ -270,15 +270,15 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uin if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { 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 + tu_edpt_stream_open(stream_tx, rhport, desc_ep); + tu_edpt_stream_write_xfer(stream_tx); // flush pending data } } else { tu_edpt_stream_t *stream_rx = &p_vendor->stream.rx; if (stream_rx->ep_addr == 0) { - tu_edpt_stream_open(stream_rx, desc_ep); + tu_edpt_stream_open(stream_rx, rhport, 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 + TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare for incoming data #endif } } @@ -291,7 +291,8 @@ 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; + (void)rhport; + (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]; @@ -310,7 +311,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint #endif #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 - tu_edpt_stream_read_xfer(rhport, &p_vendor->stream.rx); // prepare next data + tu_edpt_stream_read_xfer(&p_vendor->stream.rx); // prepare next data #endif } else if (ep_addr == p_vendor->stream.tx.ep_addr) { // Send complete @@ -318,9 +319,9 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 // try to send more if possible - if (0 == tu_edpt_stream_write_xfer(rhport, &p_vendor->stream.tx)) { + if (0 == tu_edpt_stream_write_xfer(&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->stream.tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(&p_vendor->stream.tx, xferred_bytes); } #endif } diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 69e82cda1..5cea7b5a0 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -65,17 +65,17 @@ typedef struct TU_ATTR_PACKED { } tu_edpt_state_t; typedef struct { - bool is_host; // 1: host, 0: device + uint8_t hwid; // device: rhport, host: daddr + bool is_host; // 1: host, 0: device uint8_t ep_addr; - uint16_t ep_bufsize; + uint16_t mps; + uint16_t ep_bufsize; uint8_t *ep_buf; // set to NULL to use xfer_fifo when CFG_TUD_EDPT_DEDICATED_HWFIFO = 1 tu_fifo_t ff; - uint16_t mps; // mutex: read if rx, otherwise write OSAL_MUTEX_DEF(ff_mutexdef); - }tu_edpt_stream_t; //--------------------------------------------------------------------+ @@ -112,8 +112,8 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex); //--------------------------------------------------------------------+ // Init an endpoint stream -bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, - void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize); +bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf, + uint16_t ff_bufsize, uint8_t *ep_buf, uint16_t ep_bufsize); // Deinit an endpoint stream TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_deinit(tu_edpt_stream_t *s) { @@ -129,7 +129,9 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_deinit(tu_edpt_stream_t } // Open an endpoint stream -TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { +TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t *s, uint8_t hwid, + const tusb_desc_endpoint_t *desc_ep) { + s->hwid = hwid; s->ep_addr = desc_ep->bEndpointAddress; s->mps = tu_edpt_packet_size(desc_ep); } @@ -155,27 +157,27 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_empty(tu_edpt_stream_t * //--------------------------------------------------------------------+ // Write to stream -uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize); +uint32_t tu_edpt_stream_write(tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize); // Start an usb transfer if endpoint is not busy. Return number of queued bytes -uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s); +uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s); // Start an zero-length packet if needed -bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes); +bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t *s, uint32_t last_xferred_bytes); // Get the number of bytes available for writing to FIFO // Note: if no fifo, return endpoint size if not busy, 0 otherwise -uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s); +uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t *s); //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ // Read from stream -uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize); +uint32_t tu_edpt_stream_read(tu_edpt_stream_t *s, void *buffer, uint32_t bufsize); // Start an usb transfer if endpoint is not busy -uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s); +uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s); // Complete read transfer by writing EP -> FIFO. Must be called in the transfer complete callback TU_ATTR_ALWAYS_INLINE static inline diff --git a/src/device/usbd.c b/src/device/usbd.c index 86cbcac26..80d9fee3e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -503,9 +503,9 @@ bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { return true; // skip if already initialized } TU_ASSERT(rh_init); -#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL + #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL char const* speed_str = 0; - switch (rh_init->speed) { + switch (rh_init->speed) { case TUSB_SPEED_HIGH: speed_str = "High"; break; @@ -651,7 +651,9 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { } #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL - if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG_USBD("\r\n"); // extra line for setup + if (event.event_id == DCD_EVENT_SETUP_RECEIVED) { + TU_LOG_USBD("\r\n"); // extra line for setup + } TU_LOG_USBD("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED"); #endif @@ -1047,7 +1049,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) { while (p_desc < desc_end) { uint8_t assoc_itf_count = 1; - // Class will always starts with Interface Association (if any) and then Interface descriptor + // Class will always start with Interface Association (if any) and then Interface descriptor if (TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc)) { const tusb_desc_interface_assoc_t *desc_iad = (const tusb_desc_interface_assoc_t *)p_desc; @@ -1136,9 +1138,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) { // bind all endpoints to found driver tu_edpt_bind_driver(_usbd_dev.ep2drv, desc_itf, drv_len, drv_id); - // next Interface - p_desc += drv_len; - + p_desc += drv_len; // next Interface break; // exit driver find loop } } diff --git a/src/tusb.c b/src/tusb.c index fc1ef7e1a..14b388d04 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -336,8 +336,8 @@ uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, // Endpoint Stream Helper for both Host and Device stack //--------------------------------------------------------------------+ -bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, - void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize) { +bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf, + uint16_t ff_bufsize, uint8_t *ep_buf, uint16_t ep_bufsize) { (void) is_tx; #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED == 0 // FIFO is required @@ -362,45 +362,45 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove return true; } -static bool stream_claim(uint8_t hwid, tu_edpt_stream_t *s) { +static bool stream_claim(tu_edpt_stream_t *s) { if (s->is_host) { #if CFG_TUH_ENABLED - return usbh_edpt_claim(hwid, s->ep_addr); - #endif + return usbh_edpt_claim(s->hwid, s->ep_addr); + #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_claim(hwid, s->ep_addr); - #endif + return usbd_edpt_claim(s->hwid, s->ep_addr); + #endif } return false; } -static bool stream_xfer(uint8_t hwid, tu_edpt_stream_t *s, uint16_t count) { +static bool stream_xfer(tu_edpt_stream_t *s, uint16_t count) { if (s->is_host) { #if CFG_TUH_ENABLED - return usbh_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count); - #endif + return usbh_edpt_xfer(s->hwid, s->ep_addr, count ? s->ep_buf : NULL, count); + #endif } else { #if CFG_TUD_ENABLED if (s->ep_buf == NULL) { - return usbd_edpt_xfer_fifo(hwid, s->ep_addr, &s->ff, count, false); + return usbd_edpt_xfer_fifo(s->hwid, s->ep_addr, &s->ff, count, false); } else { - return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false); + return usbd_edpt_xfer(s->hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false); } #endif } return false; } -static bool stream_release(uint8_t hwid, tu_edpt_stream_t *s) { +static bool stream_release(tu_edpt_stream_t *s) { if (s->is_host) { #if CFG_TUH_ENABLED - return usbh_edpt_release(hwid, s->ep_addr); - #endif + return usbh_edpt_release(s->hwid, s->ep_addr); + #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_release(hwid, s->ep_addr); - #endif + return usbd_edpt_release(s->hwid, s->ep_addr); + #endif } return false; } @@ -408,18 +408,18 @@ static bool stream_release(uint8_t hwid, tu_edpt_stream_t *s) { //--------------------------------------------------------------------+ // Stream Write //--------------------------------------------------------------------+ -bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { +bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t *s, uint32_t last_xferred_bytes) { // ZLP condition: no pending data, last transferred bytes is multiple of packet size TU_VERIFY(tu_fifo_empty(&s->ff) && last_xferred_bytes > 0 && (0 == (last_xferred_bytes & (s->mps - 1)))); - TU_VERIFY(stream_claim(hwid, s)); - TU_ASSERT(stream_xfer(hwid, s, 0)); + TU_VERIFY(stream_claim(s)); + TU_ASSERT(stream_xfer(s, 0)); return true; } -uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) { +uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s) { const uint16_t ff_count = tu_fifo_count(&s->ff); TU_VERIFY(ff_count > 0, 0); // skip if no data - TU_VERIFY(stream_claim(hwid, s), 0); + TU_VERIFY(stream_claim(s), 0); // Pull data from FIFO -> EP buf uint16_t count; @@ -430,23 +430,23 @@ uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) { } if (count > 0) { - TU_ASSERT(stream_xfer(hwid, s, count), 0); + TU_ASSERT(stream_xfer(s, count), 0); return count; } else { // Release endpoint since we don't make any transfer // Note: data is dropped if terminal is not connected - stream_release(hwid, s); + stream_release(s); return 0; } } -uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize) { +uint32_t tu_edpt_stream_write(tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize) { TU_VERIFY(bufsize > 0); #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED if (0 == tu_fifo_depth(&s->ff)) { // non-fifo mode - TU_VERIFY(stream_claim(hwid, s), 0); + TU_VERIFY(stream_claim(s), 0); uint32_t xact_len; if (s->ep_buf != NULL) { // using ep buf @@ -456,7 +456,7 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buf // using hwfifo xact_len = bufsize; } - TU_ASSERT(stream_xfer(hwid, s, (uint16_t) xact_len), 0); + TU_ASSERT(stream_xfer(s, (uint16_t)xact_len), 0); return xact_len; } else @@ -467,31 +467,30 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buf // flush if fifo has more than packet size or // in rare case: fifo depth is configured too small (which never reach packet size) if ((tu_fifo_count(&s->ff) >= s->mps) || (tu_fifo_depth(&s->ff) < s->mps)) { - tu_edpt_stream_write_xfer(hwid, s); + tu_edpt_stream_write_xfer(s); } return ret; } } -uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t *s) { +uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t *s) { #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED if (0 == tu_fifo_depth(&s->ff)) { // non-fifo mode bool is_busy = true; if (s->is_host) { #if CFG_TUH_ENABLED - is_busy = usbh_edpt_busy(hwid, s->ep_addr); - #endif + is_busy = usbh_edpt_busy(s->hwid, s->ep_addr); + #endif } else { #if CFG_TUD_ENABLED - is_busy = usbd_edpt_busy(hwid, s->ep_addr); - #endif + is_busy = usbd_edpt_busy(s->hwid, s->ep_addr); + #endif } return is_busy ? 0 : s->ep_bufsize; } else #endif { - (void)hwid; return (uint32_t)tu_fifo_remaining(&s->ff); } } @@ -499,13 +498,13 @@ uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t *s) { //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ -uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t *s) { +uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s) { #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED if (0 == tu_fifo_depth(&s->ff)) { // non-fifo mode: RX need ep buffer TU_VERIFY(s->ep_buf != NULL, 0); - TU_VERIFY(stream_claim(hwid, s), 0); - TU_ASSERT(stream_xfer(hwid, s, s->ep_bufsize), 0); + TU_VERIFY(stream_claim(s), 0); + TU_ASSERT(stream_xfer(s, s->ep_bufsize), 0); return s->ep_bufsize; } else #endif @@ -517,7 +516,7 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t *s) { // and slowly move it to the FIFO when read(). // This pre-check reduces endpoint claiming TU_VERIFY(available >= s->mps); - TU_VERIFY(stream_claim(hwid, s), 0); + TU_VERIFY(stream_claim(s), 0); available = tu_fifo_remaining(&s->ff); // re-get available since fifo can be changed if (available >= s->mps) { @@ -526,19 +525,19 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t *s) { if (s->ep_buf != NULL) { count = tu_min16(count, s->ep_bufsize); } - TU_ASSERT(stream_xfer(hwid, s, count), 0); + TU_ASSERT(stream_xfer(s, count), 0); return count; } else { // Release endpoint since we don't make any transfer - stream_release(hwid, s); + stream_release(s); return 0; } } } -uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) { +uint32_t tu_edpt_stream_read(tu_edpt_stream_t *s, void *buffer, uint32_t bufsize) { const uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t)bufsize); - tu_edpt_stream_read_xfer(hwid, s); + tu_edpt_stream_read_xfer(s); return num_read; } -- cgit v1.3.1 From 2f5d4dbab3a4b051eda35c7026d2568c7355decd Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 12 Dec 2025 00:51:57 +0700 Subject: fix edpt stream write/read to endpoint not yet opened --- src/class/cdc/cdc_device.c | 2 -- src/class/midi/midi_device.c | 3 --- src/common/tusb_fifo.c | 4 ++-- src/tusb.c | 2 ++ 4 files changed, 4 insertions(+), 7 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 8ea4080cc..e2819ae4b 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -43,8 +43,6 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) - typedef struct { uint8_t rhport; uint8_t itf_num; diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index e0a5aa9c3..023a81595 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -171,15 +171,12 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, ui bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]) { midid_interface_t *p_midi = &_midid_itf[itf]; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; - TU_VERIFY(tu_edpt_stream_is_opened(ep_str)); return 4 == tu_edpt_stream_read(ep_str, packet, 4); } uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_packets) { midid_interface_t *p_midi = &_midid_itf[itf]; tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx; - TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0); - const uint32_t num_read = tu_edpt_stream_read(ep_str, packets, 4u * max_packets); return num_read >> 2u; } diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index ef787c6e6..2faf72ba8 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -289,7 +289,7 @@ static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd // Advance an absolute index // "absolute" index is only in the range of [0..2*depth) -TU_ATTR_ALWAYS_INLINE static inline uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) { +static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) { // We limit the index space of p such that a correct wrap around happens // Check for a wrap around or if we are in unused index space - This has to be checked first!! // We are exploiting the wrap around to the correct index @@ -313,7 +313,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t idx2ptr(uint16_t depth, uint16_t id // Works on local copies of w // When an overwritable fifo is overflowed, rd_idx will be re-index so that it forms a full fifo -TU_ATTR_ALWAYS_INLINE static inline uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) { +static uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) { uint16_t rd_idx; if (wr_idx >= f->depth) { rd_idx = wr_idx - f->depth; diff --git a/src/tusb.c b/src/tusb.c index f6ca3fabc..8ba9f0fff 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -332,6 +332,7 @@ bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool ove } static bool stream_claim(tu_edpt_stream_t *s) { + TU_VERIFY(s->ep_addr != 0); // must be opened if (s->is_host) { #if CFG_TUH_ENABLED return usbh_edpt_claim(s->hwid, s->ep_addr); @@ -446,6 +447,7 @@ uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t *s) { #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED if (0 == tu_fifo_depth(&s->ff)) { // non-fifo mode + TU_VERIFY(s->ep_addr > 0); // must be opened bool is_busy = true; if (s->is_host) { #if CFG_TUH_ENABLED -- cgit v1.3.1 From 135a130ba51d2e41b30f13fbd998f1db32a47470 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 11 Feb 2026 22:04:44 +0100 Subject: fix rx transfer length when high speed capable device/host working at full speed Signed-off-by: HiFiPhile --- src/class/cdc/cdc_device.c | 12 ++++++------ src/class/cdc/cdc_device.h | 2 ++ src/class/cdc/cdc_host.c | 8 ++++---- src/class/midi/midi_device.c | 8 ++++---- src/class/midi/midi_host.c | 6 +++--- src/class/vendor/vendor_device.c | 36 +++++++++++++++++++++--------------- src/class/vendor/vendor_device.h | 17 ++++++++++++++++- src/common/tusb_private.h | 7 ++++--- src/tusb.c | 7 +++---- 9 files changed, 63 insertions(+), 40 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index e2819ae4b..eca4d0ad6 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -74,7 +74,7 @@ typedef struct { } cdcd_epbuf_t; CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; -#endif + #endif //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available @@ -267,14 +267,13 @@ void cdcd_init(void) { uint8_t *epin_buf = _cdcd_epbuf[i].epin; #endif - tu_edpt_stream_init(&p_cdc->rx_stream, false, false, false, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, epout_buf, - CFG_TUD_CDC_EP_BUFSIZE); + tu_edpt_stream_init(&p_cdc->rx_stream, false, false, false, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, epout_buf); // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not // know if data is actually polled by terminal. This way the most current data is prioritized. // Default: is overwritable tu_edpt_stream_init(&p_cdc->tx_stream, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, p_cdc->tx_ff_buf, - CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE); + CFG_TUD_CDC_TX_BUFSIZE, epin_buf); } } @@ -349,7 +348,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; - tu_edpt_stream_open(stream_tx, rhport, desc_ep); + tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_CDC_EP_BUFSIZE); if (_cdcd_cfg.tx_persistent) { tu_edpt_stream_write_xfer(stream_tx); // flush pending data } else { @@ -358,7 +357,8 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 } else { tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; - tu_edpt_stream_open(stream_rx, rhport, desc_ep); + tu_edpt_stream_open(stream_rx, rhport, desc_ep, + _cdcd_cfg.rx_multiple_packet_transfer ? CFG_TUD_CDC_EP_BUFSIZE : tu_edpt_packet_size(desc_ep)); if (!_cdcd_cfg.rx_persistent) { tu_edpt_stream_clear(stream_rx); } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 0809b578f..2d3a81f60 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -64,6 +64,7 @@ typedef struct TU_ATTR_PACKED { bool rx_persistent : 1; // keep rx fifo data even with bus reset or disconnect bool tx_persistent : 1; // keep tx fifo data even with reset or disconnect bool tx_overwritabe_if_not_connected : 1; // if not connected, tx fifo can be overwritten + bool rx_multiple_packet_transfer : 1; // allow transfer more than one packet in a single transfer, increase throughput but requires host sending ZLP at the end of transfer } tud_cdc_configure_t; TU_VERIFY_STATIC(sizeof(tud_cdc_configure_t) == 1, "size is not correct"); @@ -71,6 +72,7 @@ TU_VERIFY_STATIC(sizeof(tud_cdc_configure_t) == 1, "size is not correct"); .rx_persistent = false, \ .tx_persistent = false, \ .tx_overwritabe_if_not_connected = true, \ + .rx_multiple_packet_transfer = false, \ } // Configure CDC driver behavior diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index f19c4a327..8b5667aac 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -648,10 +648,10 @@ bool cdch_init(void) { for (size_t i = 0; i < CFG_TUH_CDC; i++) { cdch_interface_t *p_cdc = &cdch_data[i]; cdch_epbuf_t *epbuf = &cdch_epbuf[i]; - TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, - epbuf->tx, CFG_TUH_CDC_TX_EPSIZE)); + TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, + CFG_TUH_CDC_TX_BUFSIZE, epbuf->tx)); TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, p_cdc->stream.rx_ff_buf, - CFG_TUH_CDC_RX_BUFSIZE, epbuf->rx, CFG_TUH_CDC_RX_EPSIZE)); + CFG_TUH_CDC_RX_BUFSIZE, epbuf->rx)); } return true; @@ -735,7 +735,7 @@ static bool open_ep_stream_pair(cdch_interface_t *p_cdc, tusb_desc_endpoint_t co TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); const uint8_t ep_dir = tu_edpt_dir(desc_ep->bEndpointAddress); tu_edpt_stream_t *stream = (ep_dir == TUSB_DIR_IN) ? &p_cdc->stream.rx : &p_cdc->stream.tx; - tu_edpt_stream_open(stream, p_cdc->daddr, desc_ep); + tu_edpt_stream_open(stream, p_cdc->daddr, desc_ep, desc_ep->wMaxPacketSize); tu_edpt_stream_clear(stream); desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_ep); diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 023a81595..173baf53e 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -324,10 +324,10 @@ void midid_init(void) { #endif tu_edpt_stream_init(&p_midi->ep_stream.rx, false, false, false, p_midi->ep_stream.rx_ff_buf, - CFG_TUD_MIDI_RX_BUFSIZE, epout_buf, CFG_TUD_MIDI_EP_BUFSIZE); + CFG_TUD_MIDI_RX_BUFSIZE, epout_buf); tu_edpt_stream_init(&p_midi->ep_stream.tx, false, true, false, p_midi->ep_stream.tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, - epin_buf, CFG_TUD_MIDI_EP_BUFSIZE); + epin_buf); } } @@ -408,11 +408,11 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint1 if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_midi->ep_stream.tx; - tu_edpt_stream_open(stream_tx, rhport, desc_ep); + tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_MIDI_EP_BUFSIZE); tu_edpt_stream_clear(stream_tx); } else { tu_edpt_stream_t *stream_rx = &p_midi->ep_stream.rx; - tu_edpt_stream_open(stream_rx, rhport, desc_ep); + tu_edpt_stream_open(stream_rx, rhport, desc_ep, tu_edpt_packet_size(desc_ep)); tu_edpt_stream_clear(stream_rx); TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare to receive data } diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index 5548a0ba8..a3d61a02f 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -121,9 +121,9 @@ bool midih_init(void) { for (int inst = 0; inst < CFG_TUH_MIDI; inst++) { midih_interface_t *p_midi_host = &_midi_host[inst]; tu_edpt_stream_init(&p_midi_host->ep_stream.rx, true, false, false, - p_midi_host->ep_stream.rx_ff_buf, CFG_TUH_MIDI_RX_BUFSIZE, _midi_epbuf->rx, TUH_EPSIZE_BULK_MPS); + p_midi_host->ep_stream.rx_ff_buf, CFG_TUH_MIDI_RX_BUFSIZE, _midi_epbuf->rx); tu_edpt_stream_init(&p_midi_host->ep_stream.tx, true, true, false, - p_midi_host->ep_stream.tx_ff_buf, CFG_TUH_MIDI_TX_BUFSIZE, _midi_epbuf->tx, TUH_EPSIZE_BULK_MPS); + p_midi_host->ep_stream.tx_ff_buf, CFG_TUH_MIDI_TX_BUFSIZE, _midi_epbuf->tx); } return true; } @@ -306,7 +306,7 @@ uint16_t midih_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_ ep_stream = &p_midi->ep_stream.rx; } TU_ASSERT(tuh_edpt_open(dev_addr, p_ep), 0); - tu_edpt_stream_open(ep_stream, dev_addr, p_ep); + tu_edpt_stream_open(ep_stream, dev_addr, p_ep, p_ep->wMaxPacketSize); tu_edpt_stream_clear(ep_stream); break; diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index b917c8dc7..b2dd8f394 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -49,8 +49,7 @@ typedef struct { #else uint8_t ep_in; uint8_t ep_out; - uint16_t ep_in_mps; - uint16_t ep_out_mps; + uint16_t rx_xfer_len; #endif } vendord_interface_t; @@ -72,6 +71,8 @@ typedef struct { CFG_TUD_MEM_SECTION static vendord_epbuf_t _vendord_epbuf[CFG_TUD_VENDOR]; #endif +static tud_vendor_configure_t _vendord_cfg = TUD_VENDOR_CONFIGURE_DEFAULT(); + //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ @@ -89,6 +90,12 @@ TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t idx, uint32_t sent_bytes) { //-------------------------------------------------------------------- // Application API //-------------------------------------------------------------------- +bool tud_vendor_configure(const tud_vendor_configure_t* driver_cfg) { + TU_VERIFY(driver_cfg != NULL); + _vendord_cfg = *driver_cfg; + return true; +} + bool tud_vendor_n_mounted(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_itf = &_vendord_itf[idx]; @@ -128,9 +135,9 @@ void tud_vendor_n_read_flush(uint8_t idx) { tu_edpt_stream_clear(&p_itf->rx_stream); tu_edpt_stream_read_xfer(&p_itf->rx_stream); } -#endif + #endif -#if CFG_TUD_VENDOR_RX_MANUAL_XFER + #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]; @@ -141,7 +148,7 @@ bool tud_vendor_n_read_xfer(uint8_t idx) { #else // Non-FIFO mode TU_VERIFY(usbd_edpt_claim(p_itf->rhport, p_itf->ep_out)); - return usbd_edpt_xfer(p_itf->rhport, p_itf->ep_out, _vendord_epbuf[idx].epout, CFG_TUD_VENDOR_EPSIZE, false); + return usbd_edpt_xfer(p_itf->rhport, p_itf->ep_out, _vendord_epbuf[idx].epout, p_itf->rx_xfer_len, false); #endif } #endif @@ -215,12 +222,10 @@ void vendord_init(void) { #endif uint8_t *rx_ff_buf = p_itf->rx_ff_buf; - tu_edpt_stream_init(&p_itf->rx_stream, false, false, false, rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, epout_buf, - CFG_TUD_VENDOR_EPSIZE); + tu_edpt_stream_init(&p_itf->rx_stream, false, false, false, rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, epout_buf); uint8_t *tx_ff_buf = p_itf->tx_ff_buf; - tu_edpt_stream_init(&p_itf->tx_stream, false, true, false, tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, epin_buf, - CFG_TUD_VENDOR_EPSIZE); + tu_edpt_stream_init(&p_itf->tx_stream, false, true, false, tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, epin_buf); } #endif } @@ -302,30 +307,31 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uin const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); + uint16_t rx_xfer_len = _vendord_cfg.rx_multiple_packet_transfer ? CFG_TUD_VENDOR_EPSIZE : tu_edpt_packet_size(desc_ep); + #if CFG_TUD_VENDOR_TXRX_BUFFERED // open endpoint stream if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *tx_stream = &p_vendor->tx_stream; - tu_edpt_stream_open(tx_stream, rhport, desc_ep); + tu_edpt_stream_open(tx_stream, rhport, desc_ep, CFG_TUD_VENDOR_EPSIZE); tu_edpt_stream_write_xfer(tx_stream); // flush pending data } else { tu_edpt_stream_t *rx_stream = &p_vendor->rx_stream; - tu_edpt_stream_open(rx_stream, rhport, desc_ep); + tu_edpt_stream_open(rx_stream, rhport, desc_ep, rx_xfer_len); #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 TU_ASSERT(tu_edpt_stream_read_xfer(rx_stream) > 0, 0); // prepare for incoming data #endif } #else + p_vendor->rx_xfer_len = rx_xfer_len; // Non-FIFO mode: store endpoint info if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { p_vendor->ep_in = desc_ep->bEndpointAddress; - p_vendor->ep_in_mps = tu_edpt_packet_size(desc_ep); } else { p_vendor->ep_out = desc_ep->bEndpointAddress; - p_vendor->ep_out_mps = tu_edpt_packet_size(desc_ep); #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 // Prepare for incoming data - TU_ASSERT(usbd_edpt_xfer(rhport, p_vendor->ep_out, _vendord_epbuf[idx].epout, CFG_TUD_VENDOR_EPSIZE, false), 0); + TU_ASSERT(usbd_edpt_xfer(rhport, p_vendor->ep_out, _vendord_epbuf[idx].epout, rx_xfer_len, false), 0); #endif } #endif @@ -367,7 +373,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint // Non-FIFO mode: invoke callback with buffer tud_vendor_rx_cb(idx, _vendord_epbuf[idx].epout, xferred_bytes); #if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0 - usbd_edpt_xfer(rhport, p_vendor->ep_out, _vendord_epbuf[idx].epout, CFG_TUD_VENDOR_EPSIZE, false); + usbd_edpt_xfer(rhport, p_vendor->ep_out, _vendord_epbuf[idx].epout, p_vendor->rx_xfer_len, false); #endif } else if (ep_addr == p_vendor->ep_in) { // Send complete diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 101765bb1..594da19cb 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -37,7 +37,7 @@ extern "C" { // Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUD_VENDOR_EPSIZE - #define CFG_TUD_VENDOR_EPSIZE 64 + #define CFG_TUD_VENDOR_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #endif // RX FIFO can be disabled by setting this value to 0 @@ -62,6 +62,21 @@ extern "C" { #define CFG_TUD_VENDOR_RX_MANUAL_XFER 0 #endif +//--------------------------------------------------------------------+ +// Driver Configuration +//--------------------------------------------------------------------+ +typedef struct TU_ATTR_PACKED { + bool rx_multiple_packet_transfer : 1; // allow transfer more than one packet in a single transfer, increase throughput but requires host sending ZLP at the end of transfer +} tud_vendor_configure_t; +TU_VERIFY_STATIC(sizeof(tud_vendor_configure_t) == 1, "size is not correct"); + +#define TUD_VENDOR_CONFIGURE_DEFAULT() { \ + .rx_multiple_packet_transfer = false, \ +} + +// Configure CDC driver behavior +bool tud_vendor_configure(const tud_vendor_configure_t* driver_cfg); + //--------------------------------------------------------------------+ // Application API (Multiple Interfaces) i.e CFG_TUD_VENDOR > 1 //--------------------------------------------------------------------+ diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 43ce7a1df..7795d7122 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -62,7 +62,7 @@ typedef struct { uint8_t ep_addr; uint16_t mps; - uint16_t ep_bufsize; + uint16_t xfer_len; uint8_t *ep_buf; // set to NULL to use xfer_fifo when CFG_TUD_EDPT_DEDICATED_HWFIFO = 1 tu_fifo_t ff; @@ -101,7 +101,7 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex); // Init an endpoint stream bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf, - uint16_t ff_bufsize, uint8_t *ep_buf, uint16_t ep_bufsize); + uint16_t ff_bufsize, uint8_t *ep_buf); // Deinit an endpoint stream TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_deinit(tu_edpt_stream_t *s) { @@ -118,10 +118,11 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_deinit(tu_edpt_stream_t // Open an endpoint stream TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t *s, uint8_t hwid, - const tusb_desc_endpoint_t *desc_ep) { + const tusb_desc_endpoint_t *desc_ep, uint16_t xfer_len) { s->hwid = hwid; s->ep_addr = desc_ep->bEndpointAddress; s->mps = tu_edpt_packet_size(desc_ep); + s->xfer_len = xfer_len; } TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_is_opened(const tu_edpt_stream_t *s) { diff --git a/src/tusb.c b/src/tusb.c index 6075e9db4..27864cb51 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -306,7 +306,7 @@ bool tu_bind_driver_to_ep_itf(uint8_t driver_id, uint8_t ep2drv[][2], uint8_t it //--------------------------------------------------------------------+ bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf, - uint16_t ff_bufsize, uint8_t *ep_buf, uint16_t ep_bufsize) { + uint16_t ff_bufsize, uint8_t *ep_buf) { (void) is_tx; if (ff_buf == NULL || ff_bufsize == 0) { @@ -324,7 +324,6 @@ bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool ove #endif s->ep_buf = ep_buf; - s->ep_bufsize = ep_bufsize; return true; } @@ -394,7 +393,7 @@ uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s) { if (s->ep_buf == NULL) { count = tu_fifo_count(&s->ff); // re-get count since fifo can be changed } else { - count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); + count = tu_fifo_read_n(&s->ff, s->ep_buf, s->xfer_len); } if (count > 0) { @@ -441,7 +440,7 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s) { if (available >= s->mps) { // multiple of packet size limit by ep bufsize uint16_t count = (uint16_t) (available & ~(s->mps - 1)); - count = tu_min16(count, s->ep_bufsize); + count = tu_min16(count, s->xfer_len); TU_ASSERT(stream_xfer(s, count), 0); return count; } else { -- cgit v1.3.1 From d74559ab70c7c4804ee8cf65d9c65d910af06870 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 11 Mar 2026 20:11:41 +0700 Subject: rename .rx_multiple_packet_transfer to .rx_need_zlp --- examples/dual/host_info_to_device_cdc/src/main.c | 2 +- src/class/cdc/cdc_device.c | 6 ++---- src/class/cdc/cdc_device.h | 26 +++++++++++++----------- src/class/vendor/vendor_device.c | 4 ++-- src/class/vendor/vendor_device.h | 11 ++++++---- src/common/tusb_private.h | 3 ++- 6 files changed, 28 insertions(+), 24 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/examples/dual/host_info_to_device_cdc/src/main.c b/examples/dual/host_info_to_device_cdc/src/main.c index 7cf43aef3..fe2199a69 100644 --- a/examples/dual/host_info_to_device_cdc/src/main.c +++ b/examples/dual/host_info_to_device_cdc/src/main.c @@ -106,7 +106,7 @@ static void usb_device_init(void) { .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); - tud_cdc_configure_t cdc_cfg = TUD_CDC_CONFIGURE_DEFAULT(); + tud_cdc_configure_t cdc_cfg = CFG_TUD_CDC_CONFIGURE_DEFAULT(); cdc_cfg.tx_persistent = true; cdc_cfg.tx_overwritabe_if_not_connected = false; tud_cdc_configure(&cdc_cfg); diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index eca4d0ad6..2be3b8ade 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -116,7 +116,7 @@ TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) { // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; -static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT(); +static tud_cdc_configure_t _cdcd_cfg = CFG_TUD_CDC_CONFIGURE_DEFAULT(); TU_ATTR_ALWAYS_INLINE static inline uint8_t find_cdc_itf(uint8_t ep_addr) { for (uint8_t idx = 0; idx < CFG_TUD_CDC; idx++) { @@ -347,7 +347,6 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; - tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_CDC_EP_BUFSIZE); if (_cdcd_cfg.tx_persistent) { tu_edpt_stream_write_xfer(stream_tx); // flush pending data @@ -356,9 +355,8 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 } } else { tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; - tu_edpt_stream_open(stream_rx, rhport, desc_ep, - _cdcd_cfg.rx_multiple_packet_transfer ? CFG_TUD_CDC_EP_BUFSIZE : tu_edpt_packet_size(desc_ep)); + _cdcd_cfg.rx_need_zlp ? CFG_TUD_CDC_EP_BUFSIZE : tu_edpt_packet_size(desc_ep)); if (!_cdcd_cfg.rx_persistent) { tu_edpt_stream_clear(stream_rx); } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 2d3a81f60..64e58e5ec 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -64,16 +64,19 @@ typedef struct TU_ATTR_PACKED { bool rx_persistent : 1; // keep rx fifo data even with bus reset or disconnect bool tx_persistent : 1; // keep tx fifo data even with reset or disconnect bool tx_overwritabe_if_not_connected : 1; // if not connected, tx fifo can be overwritten - bool rx_multiple_packet_transfer : 1; // allow transfer more than one packet in a single transfer, increase throughput but requires host sending ZLP at the end of transfer + bool rx_need_zlp : 1; // requires host support ZLP, allow transfer more than one packet in a single transfer, better throughput. } tud_cdc_configure_t; TU_VERIFY_STATIC(sizeof(tud_cdc_configure_t) == 1, "size is not correct"); -#define TUD_CDC_CONFIGURE_DEFAULT() { \ - .rx_persistent = false, \ - .tx_persistent = false, \ - .tx_overwritabe_if_not_connected = true, \ - .rx_multiple_packet_transfer = false, \ -} +#ifndef CFG_TUD_CDC_CONFIGURE_DEFAULT + #define CFG_TUD_CDC_CONFIGURE_DEFAULT() \ + { \ + .rx_persistent = false, \ + .tx_persistent = false, \ + .tx_overwritabe_if_not_connected = true, \ + .rx_need_zlp = false \ + } +#endif // Configure CDC driver behavior bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg); @@ -86,13 +89,13 @@ bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg); // Application API (Multiple Ports) i.e. CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ -// Check if interface is ready +// Check if the interface is ready bool tud_cdc_n_ready(uint8_t itf); -// Check if terminal is connected to this port +// Check if the terminal is connected to this port bool tud_cdc_n_connected(uint8_t itf); -// Get current line state. Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send) +// Get the current line state. Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send) uint8_t tud_cdc_n_get_line_state(uint8_t itf); // Get current line encoding: bit rate, stop bits parity etc .. @@ -138,10 +141,9 @@ uint32_t tud_cdc_n_write_flush(uint8_t itf); // Return the number of bytes (characters) available for writing to TX FIFO buffer in a single n_write operation. uint32_t tud_cdc_n_write_available(uint8_t itf); -// Clear the transmit FIFO +// Clear the TX FIFO bool tud_cdc_n_write_clear(uint8_t itf); - #if CFG_TUD_CDC_NOTIFY bool tud_cdc_n_notify_msg(uint8_t itf, cdc_notify_msg_t *msg); diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index b2dd8f394..c7ad8bd8c 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -71,7 +71,7 @@ typedef struct { CFG_TUD_MEM_SECTION static vendord_epbuf_t _vendord_epbuf[CFG_TUD_VENDOR]; #endif -static tud_vendor_configure_t _vendord_cfg = TUD_VENDOR_CONFIGURE_DEFAULT(); +static tud_vendor_configure_t _vendord_cfg = CFG_TUD_VENDOR_CONFIGURE_DEFAULT(); //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available @@ -307,7 +307,7 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uin const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); - uint16_t rx_xfer_len = _vendord_cfg.rx_multiple_packet_transfer ? CFG_TUD_VENDOR_EPSIZE : tu_edpt_packet_size(desc_ep); + uint16_t rx_xfer_len = _vendord_cfg.rx_need_zlp ? CFG_TUD_VENDOR_EPSIZE : tu_edpt_packet_size(desc_ep); #if CFG_TUD_VENDOR_TXRX_BUFFERED // open endpoint stream diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 594da19cb..54f3548c7 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -66,13 +66,16 @@ extern "C" { // Driver Configuration //--------------------------------------------------------------------+ typedef struct TU_ATTR_PACKED { - bool rx_multiple_packet_transfer : 1; // allow transfer more than one packet in a single transfer, increase throughput but requires host sending ZLP at the end of transfer + bool rx_need_zlp : 1; // requires host support ZLP, allow transfer more than one packet in a single transfer, better throughput. } tud_vendor_configure_t; TU_VERIFY_STATIC(sizeof(tud_vendor_configure_t) == 1, "size is not correct"); -#define TUD_VENDOR_CONFIGURE_DEFAULT() { \ - .rx_multiple_packet_transfer = false, \ -} +#ifndef CFG_TUD_VENDOR_CONFIGURE_DEFAULT + #define CFG_TUD_VENDOR_CONFIGURE_DEFAULT() \ + { \ + .rx_need_zlp = false, \ + } +#endif // Configure CDC driver behavior bool tud_vendor_configure(const tud_vendor_configure_t* driver_cfg); diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 543921553..91d213755 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -62,8 +62,9 @@ typedef struct { uint8_t hwid; // device: rhport, host: daddr bool is_host; // 1: host, 0: device uint8_t ep_addr; - uint16_t mps; + // 1 byte padding + uint16_t mps; uint16_t xfer_len; uint8_t *ep_buf; // set to NULL to use xfer_fifo when CFG_TUD_EDPT_DEDICATED_HWFIFO = 1 tu_fifo_t ff; -- cgit v1.3.1 From 78bbc7dc2e80daba79351bc37e11b13243fd6f8c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Mar 2026 11:43:32 +0700 Subject: refactor(config): separate endpoint buffer sizes into RX and TX definitions for clarity and flexibility --- examples/device/cdc_dual_ports/src/tusb_config.h | 6 +-- examples/device/cdc_msc/src/tusb_config.h | 6 +-- examples/device/cdc_msc_freertos/src/tusb_config.h | 6 +-- examples/device/cdc_uac2/src/tusb_config.h | 6 +-- examples/device/printer_to_cdc/src/tusb_config.h | 6 ++- examples/dual/dynamic_switch/src/tusb_config.h | 3 +- .../dual/host_hid_to_device_cdc/src/tusb_config.h | 3 +- .../dual/host_info_to_device_cdc/src/tusb_config.h | 3 +- src/class/cdc/cdc_device.c | 14 +++--- src/class/cdc/cdc_device.h | 57 ++++++++++++---------- src/class/cdc/cdc_host.h | 8 +-- src/class/midi/midi_device.c | 6 +-- src/class/midi/midi_device.h | 17 +++++-- src/class/midi/midi_host.c | 4 +- src/class/midi/midi_host.h | 6 +-- src/class/printer/printer_device.c | 22 ++++----- src/class/printer/printer_device.h | 15 +++++- src/class/vendor/vendor_device.c | 18 +++---- src/class/vendor/vendor_device.h | 16 +++++- src/common/tusb_types.h | 4 ++ src/host/usbh.h | 3 +- test/fuzz/device/cdc/src/tusb_config.h | 3 +- test/fuzz/device/msc/src/tusb_config.h | 3 +- test/fuzz/device/net/src/tusb_config.h | 3 +- 24 files changed, 143 insertions(+), 95 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/examples/device/cdc_dual_ports/src/tusb_config.h b/examples/device/cdc_dual_ports/src/tusb_config.h index 710c01ee2..f8c36a90d 100644 --- a/examples/device/cdc_dual_ports/src/tusb_config.h +++ b/examples/device/cdc_dual_ports/src/tusb_config.h @@ -104,9 +104,9 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -// Leave it as default size (512 for HS, 64 for FS) unless your host application -// is able to send ZLP (Zero Length Packet) to terminate transfer ! -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +// Only increase RX_EPSIZE if your host driver/application support zero-length packet (ZLP) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index 3f2f05f20..c4f4374a2 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -104,9 +104,9 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -// Leave it as default size (512 for HS, 64 for FS) unless your host application -// is able to send ZLP (Zero Length Packet) to terminate transfer ! -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +// Only increase RX_EPSIZE if your host driver/application support zero-length packet (ZLP) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 diff --git a/examples/device/cdc_msc_freertos/src/tusb_config.h b/examples/device/cdc_msc_freertos/src/tusb_config.h index 8277b1604..33342819e 100644 --- a/examples/device/cdc_msc_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_freertos/src/tusb_config.h @@ -111,9 +111,9 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -// Leave it as default size (512 for HS, 64 for FS) unless your host application -// is able to send ZLP (Zero Length Packet) to terminate transfer ! -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +// Only increase RX_EPSIZE if your host driver/application support zero-length packet (ZLP) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 diff --git a/examples/device/cdc_uac2/src/tusb_config.h b/examples/device/cdc_uac2/src/tusb_config.h index 5eb2e8f74..6724b83b3 100644 --- a/examples/device/cdc_uac2/src/tusb_config.h +++ b/examples/device/cdc_uac2/src/tusb_config.h @@ -160,9 +160,9 @@ extern "C" { #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -// Leave it as default size (512 for HS, 64 for FS) unless your host application -// is able to send ZLP (Zero Length Packet) to terminate transfer ! -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +// Only increase RX_EPSIZE if your host driver/application support zero-length packet (ZLP) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } diff --git a/examples/device/printer_to_cdc/src/tusb_config.h b/examples/device/printer_to_cdc/src/tusb_config.h index c38e8e1ee..d12313ce5 100644 --- a/examples/device/printer_to_cdc/src/tusb_config.h +++ b/examples/device/printer_to_cdc/src/tusb_config.h @@ -103,12 +103,14 @@ extern "C" { #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // Printer buffer sizes #define CFG_TUD_PRINTER_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_PRINTER_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -#define CFG_TUD_PRINTER_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_PRINTER_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_PRINTER_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus } diff --git a/examples/dual/dynamic_switch/src/tusb_config.h b/examples/dual/dynamic_switch/src/tusb_config.h index af0d55f14..f9500f923 100644 --- a/examples/dual/dynamic_switch/src/tusb_config.h +++ b/examples/dual/dynamic_switch/src/tusb_config.h @@ -130,7 +130,8 @@ extern "C" { #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) //-------------------------------------------------------------------- // HOST CONFIGURATION diff --git a/examples/dual/host_hid_to_device_cdc/src/tusb_config.h b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h index 2843e0b83..0a7137d29 100644 --- a/examples/dual/host_hid_to_device_cdc/src/tusb_config.h +++ b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h @@ -115,7 +115,8 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) //-------------------------------------------------------------------- // HOST CONFIGURATION diff --git a/examples/dual/host_info_to_device_cdc/src/tusb_config.h b/examples/dual/host_info_to_device_cdc/src/tusb_config.h index 601c27dae..8f3ed6357 100644 --- a/examples/dual/host_info_to_device_cdc/src/tusb_config.h +++ b/examples/dual/host_info_to_device_cdc/src/tusb_config.h @@ -115,7 +115,8 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 256) // CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) //-------------------------------------------------------------------- // HOST CONFIGURATION diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 2be3b8ade..3f207462e 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -63,10 +63,10 @@ typedef struct { #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) // Skip local EP buffer if dedicated hw FIFO is supported - #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { - TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE); - TUD_EPBUF_DEF(epin, CFG_TUD_CDC_EP_BUFSIZE); + TUD_EPBUF_DEF(epout, CFG_TUD_CDC_RX_EPSIZE); + TUD_EPBUF_DEF(epin, CFG_TUD_CDC_TX_EPSIZE); #if CFG_TUD_CDC_NOTIFY TUD_EPBUF_TYPE_DEF(cdc_notify_msg_t, epnotify); @@ -74,7 +74,7 @@ typedef struct { } cdcd_epbuf_t; CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; - #endif +#endif //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available @@ -347,7 +347,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; - tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_CDC_EP_BUFSIZE); + tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_CDC_TX_EPSIZE); if (_cdcd_cfg.tx_persistent) { tu_edpt_stream_write_xfer(stream_tx); // flush pending data } else { @@ -356,7 +356,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 } else { tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; tu_edpt_stream_open(stream_rx, rhport, desc_ep, - _cdcd_cfg.rx_need_zlp ? CFG_TUD_CDC_EP_BUFSIZE : tu_edpt_packet_size(desc_ep)); + _cdcd_cfg.rx_need_zlp ? CFG_TUD_CDC_RX_EPSIZE : tu_edpt_packet_size(desc_ep)); if (!_cdcd_cfg.rx_persistent) { tu_edpt_stream_clear(stream_rx); } @@ -511,7 +511,7 @@ 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) { tud_cdc_tx_complete_cb(itf); // invoke callback to possibly refill tx fifo diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 64e58e5ec..3baf84d00 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -29,6 +29,10 @@ #include "cdc.h" +#ifdef __cplusplus + extern "C" { +#endif + //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ @@ -37,46 +41,49 @@ #endif #ifndef CFG_TUD_CDC_TX_BUFSIZE - #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + #define CFG_TUD_CDC_TX_BUFSIZE TUD_EPSIZE_BULK_MAX #endif #ifndef CFG_TUD_CDC_RX_BUFSIZE - #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + #define CFG_TUD_CDC_RX_BUFSIZE TUD_EPSIZE_BULK_MAX #endif -#if !defined(CFG_TUD_CDC_EP_BUFSIZE) && defined(CFG_TUD_CDC_EPSIZE) - #warning CFG_TUD_CDC_EPSIZE is renamed to CFG_TUD_CDC_EP_BUFSIZE, please update to use the new name - #define CFG_TUD_CDC_EP_BUFSIZE CFG_TUD_CDC_EPSIZE +// EP_BUFSIZE is separated to RX_EPSIZE and TX_EPSIZE +#ifndef CFG_TUD_CDC_RX_EPSIZE + #ifdef CFG_TUD_CDC_EP_BUFSIZE + #define CFG_TUD_CDC_RX_EPSIZE CFG_TUD_CDC_EP_BUFSIZE + #else + #define CFG_TUD_CDC_RX_EPSIZE TUD_EPSIZE_BULK_MAX + #endif #endif -#ifndef CFG_TUD_CDC_EP_BUFSIZE - #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#ifndef CFG_TUD_CDC_TX_EPSIZE + #ifdef CFG_TUD_CDC_EP_BUFSIZE + #define CFG_TUD_CDC_TX_EPSIZE CFG_TUD_CDC_EP_BUFSIZE + #else + #define CFG_TUD_CDC_TX_EPSIZE TUD_EPSIZE_BULK_MAX + #endif #endif -#ifdef __cplusplus - extern "C" { +#ifndef CFG_TUD_CDC_CONFIGURE_DEFAULT + #define CFG_TUD_CDC_CONFIGURE_DEFAULT() \ + { \ + .rx_persistent = false, \ + .tx_persistent = false, \ + .tx_overwritabe_if_not_connected = true, \ + .rx_need_zlp = false \ + } #endif //--------------------------------------------------------------------+ // Driver Configuration //--------------------------------------------------------------------+ -typedef struct TU_ATTR_PACKED { - bool rx_persistent : 1; // keep rx fifo data even with bus reset or disconnect - bool tx_persistent : 1; // keep tx fifo data even with reset or disconnect - bool tx_overwritabe_if_not_connected : 1; // if not connected, tx fifo can be overwritten - bool rx_need_zlp : 1; // requires host support ZLP, allow transfer more than one packet in a single transfer, better throughput. +typedef struct { + bool rx_persistent; // keep rx fifo data even with bus reset or disconnect + bool tx_persistent; // keep tx fifo data even with reset or disconnect + bool tx_overwritabe_if_not_connected; // if not connected, tx fifo can be overwritten + bool rx_need_zlp; // requires host support ZLP, allow transfer more than one packet in a single transfer, better throughput. } tud_cdc_configure_t; -TU_VERIFY_STATIC(sizeof(tud_cdc_configure_t) == 1, "size is not correct"); - -#ifndef CFG_TUD_CDC_CONFIGURE_DEFAULT - #define CFG_TUD_CDC_CONFIGURE_DEFAULT() \ - { \ - .rx_persistent = false, \ - .tx_persistent = false, \ - .tx_overwritabe_if_not_connected = true, \ - .rx_need_zlp = false \ - } -#endif // Configure CDC driver behavior bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg); diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 57919c7ff..1b1709b18 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -39,22 +39,22 @@ extern "C" { // RX FIFO size #ifndef CFG_TUH_CDC_RX_BUFSIZE - #define CFG_TUH_CDC_RX_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_CDC_RX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif // RX Endpoint size #ifndef CFG_TUH_CDC_RX_EPSIZE - #define CFG_TUH_CDC_RX_EPSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_CDC_RX_EPSIZE TUH_EPSIZE_BULK_MAX #endif // TX FIFO size #ifndef CFG_TUH_CDC_TX_BUFSIZE - #define CFG_TUH_CDC_TX_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_CDC_TX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif // TX Endpoint size #ifndef CFG_TUH_CDC_TX_EPSIZE - #define CFG_TUH_CDC_TX_EPSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_CDC_TX_EPSIZE TUH_EPSIZE_BULK_MAX #endif //--------------------------------------------------------------------+ diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index e5e0f52a5..de4ff5dd8 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -74,8 +74,8 @@ static midid_interface_t _midid_itf[CFG_TUD_MIDI]; #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 // Endpoint Transfer buffer: not used if dedicated hw FIFO is available typedef struct { - TUD_EPBUF_DEF(epin, CFG_TUD_MIDI_EP_BUFSIZE); - TUD_EPBUF_DEF(epout, CFG_TUD_MIDI_EP_BUFSIZE); + TUD_EPBUF_DEF(epin, CFG_TUD_MIDI_TX_EPSIZE); + TUD_EPBUF_DEF(epout, CFG_TUD_MIDI_RX_EPSIZE); } midid_epbuf_t; CFG_TUD_MEM_SECTION static midid_epbuf_t _midid_epbuf[CFG_TUD_MIDI]; @@ -510,7 +510,7 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint1 if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_midi->ep_stream.tx; - tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_MIDI_EP_BUFSIZE); + tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_MIDI_TX_EPSIZE); tu_edpt_stream_clear(stream_tx); } else { tu_edpt_stream_t *stream_rx = &p_midi->ep_stream.rx; diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index b80ad544a..57eabec1f 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -34,13 +34,20 @@ // Class Driver Configuration //--------------------------------------------------------------------+ -#if !defined(CFG_TUD_MIDI_EP_BUFSIZE) && defined(CFG_TUD_MIDI_EPSIZE) - #warning CFG_TUD_MIDI_EPSIZE is renamed to CFG_TUD_MIDI_EP_BUFSIZE, please update to use the new name - #define CFG_TUD_MIDI_EP_BUFSIZE CFG_TUD_MIDI_EPSIZE +#ifndef CFG_TUD_MIDI_RX_EPSIZE + #ifdef CFG_TUD_MIDI_EP_BUFSIZE + #define CFG_TUD_MIDI_RX_EPSIZE CFG_TUD_MIDI_EP_BUFSIZE + #else + #define CFG_TUD_MIDI_RX_EPSIZE TUD_EPSIZE_BULK_MAX + #endif #endif -#ifndef CFG_TUD_MIDI_EP_BUFSIZE - #define CFG_TUD_MIDI_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#ifndef CFG_TUD_MIDI_TX_EPSIZE + #ifdef CFG_TUD_MIDI_EP_BUFSIZE + #define CFG_TUD_MIDI_TX_EPSIZE CFG_TUD_MIDI_EP_BUFSIZE + #else + #define CFG_TUD_MIDI_TX_EPSIZE TUD_EPSIZE_BULK_MAX + #endif #endif #ifdef __cplusplus diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c index bef4d46bf..0feb5106d 100644 --- a/src/class/midi/midi_host.c +++ b/src/class/midi/midi_host.c @@ -83,8 +83,8 @@ typedef struct { }midih_interface_t; typedef struct { - TUH_EPBUF_DEF(tx, TUH_EPSIZE_BULK_MPS); - TUH_EPBUF_DEF(rx, TUH_EPSIZE_BULK_MPS); + TUH_EPBUF_DEF(tx, TUH_EPSIZE_BULK_MAX); + TUH_EPBUF_DEF(rx, TUH_EPSIZE_BULK_MAX); } midih_epbuf_t; static midih_interface_t _midi_host[CFG_TUH_MIDI]; diff --git a/src/class/midi/midi_host.h b/src/class/midi/midi_host.h index 8a8dccab4..b9ab0130d 100644 --- a/src/class/midi/midi_host.h +++ b/src/class/midi/midi_host.h @@ -38,15 +38,15 @@ extern "C" { // Class Driver Configuration //--------------------------------------------------------------------+ #ifndef CFG_TUH_MIDI_RX_BUFSIZE - #define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif #ifndef CFG_TUH_MIDI_TX_BUFSIZE - #define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MAX #endif #ifndef CFG_TUH_MIDI_EP_BUFSIZE - #define CFG_TUH_MIDI_EP_BUFSIZE TUH_EPSIZE_BULK_MPS + #define CFG_TUH_MIDI_EP_BUFSIZE TUH_EPSIZE_BULK_MAX #endif // Enable the MIDI stream read/write API. Some library can work with raw USB MIDI packet diff --git a/src/class/printer/printer_device.c b/src/class/printer/printer_device.c index f5bb33795..d2dc9b163 100644 --- a/src/class/printer/printer_device.c +++ b/src/class/printer/printer_device.c @@ -53,8 +53,8 @@ typedef struct { #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { - TUD_EPBUF_DEF(epout, CFG_TUD_PRINTER_EP_BUFSIZE); - TUD_EPBUF_DEF(epin, CFG_TUD_PRINTER_EP_BUFSIZE); + TUD_EPBUF_DEF(epout, CFG_TUD_PRINTER_RX_EPSIZE); + TUD_EPBUF_DEF(epin, CFG_TUD_PRINTER_TX_EPSIZE); } printer_epbuf_t; CFG_TUD_MEM_SECTION static printer_epbuf_t _printer_epbuf[CFG_TUD_PRINTER]; @@ -173,12 +173,10 @@ void printerd_init(void) { #endif tu_edpt_stream_init(&p->rx_stream, false, false, false, - p->rx_ff_buf, CFG_TUD_PRINTER_RX_BUFSIZE, - epout_buf, CFG_TUD_PRINTER_EP_BUFSIZE); + p->rx_ff_buf, CFG_TUD_PRINTER_RX_BUFSIZE, epout_buf); tu_edpt_stream_init(&p->tx_stream, false, true, true, - p->tx_ff_buf, CFG_TUD_PRINTER_TX_BUFSIZE, - epin_buf, CFG_TUD_PRINTER_EP_BUFSIZE); + p->tx_ff_buf, CFG_TUD_PRINTER_TX_BUFSIZE, epin_buf); } } @@ -226,12 +224,14 @@ uint16_t printerd_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, ui TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p->tx_stream, rhport, desc_ep); - tu_edpt_stream_clear(&p->tx_stream); + tu_edpt_stream_t *stream_tx = &p->tx_stream; + tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_PRINTER_TX_EPSIZE); + tu_edpt_stream_clear(stream_tx); } else { - tu_edpt_stream_open(&p->rx_stream, rhport, desc_ep); - tu_edpt_stream_clear(&p->rx_stream); - TU_ASSERT(tu_edpt_stream_read_xfer(&p->rx_stream) > 0, 0); + tu_edpt_stream_t *stream_rx = &p->rx_stream; + tu_edpt_stream_open(stream_rx, rhport, desc_ep, tu_edpt_packet_size(desc_ep)); + tu_edpt_stream_clear(stream_rx); + TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); } drv_len += sizeof(tusb_desc_endpoint_t); diff --git a/src/class/printer/printer_device.h b/src/class/printer/printer_device.h index a6b7052cb..afde1f022 100644 --- a/src/class/printer/printer_device.h +++ b/src/class/printer/printer_device.h @@ -27,12 +27,23 @@ #ifndef TUSB_PRINTER_DEVICE_H_ #define TUSB_PRINTER_DEVICE_H_ -#include "printer.h" - #ifdef __cplusplus extern "C" { #endif +#include "printer.h" + +//--------------------------------------------------------------------+ +// Configuration +//--------------------------------------------------------------------+ +#ifndef CFG_TUD_PRINTER_RX_EPSIZE + #define CFG_TUD_PRINTER_RX_EPSIZE TUD_EPSIZE_BULK_MAX +#endif + +#ifndef CFG_TUD_PRINTER_TX_EPSIZE + #define CFG_TUD_PRINTER_TX_EPSIZE TUD_EPSIZE_BULK_MAX +#endif + //--------------------------------------------------------------------+ // Application API (Multiple Ports) i.e. CFG_TUD_PRINTER > 1 //--------------------------------------------------------------------+ diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index c7ad8bd8c..c55cad627 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -61,15 +61,15 @@ typedef struct { static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; - // Skip local EP buffer if dedicated hw FIFO is supported or no fifo mode - #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || !CFG_TUD_VENDOR_TXRX_BUFFERED +// Skip local EP buffer if dedicated hw FIFO is supported or no fifo mode +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || !CFG_TUD_VENDOR_TXRX_BUFFERED typedef struct { - TUD_EPBUF_DEF(epout, CFG_TUD_VENDOR_EPSIZE); - TUD_EPBUF_DEF(epin, CFG_TUD_VENDOR_EPSIZE); + TUD_EPBUF_DEF(epout, CFG_TUD_VENDOR_RX_EPSIZE); + TUD_EPBUF_DEF(epin, CFG_TUD_VENDOR_TX_EPSIZE); } vendord_epbuf_t; CFG_TUD_MEM_SECTION static vendord_epbuf_t _vendord_epbuf[CFG_TUD_VENDOR]; - #endif +#endif static tud_vendor_configure_t _vendord_cfg = CFG_TUD_VENDOR_CONFIGURE_DEFAULT(); @@ -167,7 +167,7 @@ uint32_t tud_vendor_n_write(uint8_t idx, const void *buffer, uint32_t bufsize) { #else // non-fifo mode: direct transfer TU_VERIFY(usbd_edpt_claim(p_itf->rhport, p_itf->ep_in), 0); - const uint32_t xact_len = tu_min32(bufsize, CFG_TUD_VENDOR_EPSIZE); + const uint32_t xact_len = tu_min32(bufsize, CFG_TUD_VENDOR_TX_EPSIZE); memcpy(_vendord_epbuf[idx].epin, buffer, xact_len); TU_ASSERT(usbd_edpt_xfer(p_itf->rhport, p_itf->ep_in, _vendord_epbuf[idx].epin, (uint16_t)xact_len, false), 0); return xact_len; @@ -184,7 +184,7 @@ uint32_t tud_vendor_n_write_available(uint8_t idx) { #else // Non-FIFO mode TU_VERIFY(p_itf->ep_in > 0, 0); // must be opened - return usbd_edpt_busy(p_itf->rhport, p_itf->ep_in) ? 0 : CFG_TUD_VENDOR_EPSIZE; + return usbd_edpt_busy(p_itf->rhport, p_itf->ep_in) ? 0 : CFG_TUD_VENDOR_TX_EPSIZE; #endif } @@ -307,13 +307,13 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uin const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); - uint16_t rx_xfer_len = _vendord_cfg.rx_need_zlp ? CFG_TUD_VENDOR_EPSIZE : tu_edpt_packet_size(desc_ep); + uint16_t rx_xfer_len = _vendord_cfg.rx_need_zlp ? CFG_TUD_VENDOR_RX_EPSIZE : tu_edpt_packet_size(desc_ep); #if CFG_TUD_VENDOR_TXRX_BUFFERED // open endpoint stream if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *tx_stream = &p_vendor->tx_stream; - tu_edpt_stream_open(tx_stream, rhport, desc_ep, CFG_TUD_VENDOR_EPSIZE); + tu_edpt_stream_open(tx_stream, rhport, desc_ep, CFG_TUD_VENDOR_TX_EPSIZE); tu_edpt_stream_write_xfer(tx_stream); // flush pending data } else { tu_edpt_stream_t *rx_stream = &p_vendor->rx_stream; diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 54f3548c7..491a7d7fb 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -36,8 +36,20 @@ extern "C" { //--------------------------------------------------------------------+ // Configuration //--------------------------------------------------------------------+ -#ifndef CFG_TUD_VENDOR_EPSIZE - #define CFG_TUD_VENDOR_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#ifndef CFG_TUD_VENDOR_RX_EPSIZE + #ifdef CFG_TUD_VENDOR_EPSIZE + #define CFG_TUD_VENDOR_RX_EPSIZE CFG_TUD_VENDOR_EPSIZE + #else + #define CFG_TUD_VENDOR_RX_EPSIZE TUD_EPSIZE_BULK_MAX + #endif +#endif + +#ifndef CFG_TUD_VENDOR_TX_EPSIZE + #ifdef CFG_TUD_VENDOR_EPSIZE + #define CFG_TUD_VENDOR_TX_EPSIZE CFG_TUD_VENDOR_EPSIZE + #else + #define CFG_TUD_VENDOR_TX_EPSIZE TUD_EPSIZE_BULK_MAX + #endif #endif // RX FIFO can be disabled by setting this value to 0 diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 8a48a0f04..a18f9feb7 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -115,6 +115,10 @@ enum { TUSB_EPSIZE_ISO_HS_MAX = 1024, }; +// Endpoint Bulk size depending on host/device max speed +#define TUD_EPSIZE_BULK_MAX (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define TUH_EPSIZE_BULK_MAX (TUH_OPT_HIGH_SPEED ? 512 : 64) + /// Isochronous Endpoint Attributes typedef enum { TUSB_ISO_EP_ATT_NO_SYNC = 0x00, diff --git a/src/host/usbh.h b/src/host/usbh.h index 143d36f8c..7ddec35b7 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -41,8 +41,7 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -// Endpoint Bulk size depending on host mx speed -#define TUH_EPSIZE_BULK_MPS (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS) + // forward declaration struct tuh_xfer_s; diff --git a/test/fuzz/device/cdc/src/tusb_config.h b/test/fuzz/device/cdc/src/tusb_config.h index 76f44619e..b4b45d798 100644 --- a/test/fuzz/device/cdc/src/tusb_config.h +++ b/test/fuzz/device/cdc/src/tusb_config.h @@ -102,7 +102,8 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 diff --git a/test/fuzz/device/msc/src/tusb_config.h b/test/fuzz/device/msc/src/tusb_config.h index abd8cd4ce..3400c141d 100644 --- a/test/fuzz/device/msc/src/tusb_config.h +++ b/test/fuzz/device/msc/src/tusb_config.h @@ -102,7 +102,8 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 diff --git a/test/fuzz/device/net/src/tusb_config.h b/test/fuzz/device/net/src/tusb_config.h index 4fe98e043..46fc10cdb 100644 --- a/test/fuzz/device/net/src/tusb_config.h +++ b/test/fuzz/device/net/src/tusb_config.h @@ -107,7 +107,8 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // CDC Endpoint transfer buffer size, more is faster -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 -- cgit v1.3.1 From aea4f6046e9a07d5f169de9fcc31bca2b667ea45 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Mar 2026 12:16:57 +0700 Subject: refactor(vendor/cdc): add CFG_TUD_CDC_RX_NEED_ZLP and CFG_TUD_VENDOR_RX_NEED_ZLP --- examples/device/cdc_dual_ports/src/tusb_config.h | 4 ++-- examples/device/cdc_msc/src/tusb_config.h | 4 ++-- examples/device/cdc_msc_freertos/src/tusb_config.h | 4 ++-- examples/device/cdc_uac2/src/tusb_config.h | 4 ++-- examples/device/printer_to_cdc/src/tusb_config.h | 3 ++- examples/dual/dynamic_switch/src/tusb_config.h | 3 ++- .../dual/host_hid_to_device_cdc/src/tusb_config.h | 3 ++- .../dual/host_info_to_device_cdc/src/tusb_config.h | 3 ++- src/class/cdc/cdc_device.c | 2 +- src/class/cdc/cdc_device.h | 7 +++++-- src/class/vendor/vendor_device.c | 13 +------------ src/class/vendor/vendor_device.h | 19 +++---------------- test/fuzz/device/cdc/src/tusb_config.h | 3 ++- test/fuzz/device/msc/src/tusb_config.h | 3 ++- test/fuzz/device/net/src/tusb_config.h | 3 ++- 15 files changed, 32 insertions(+), 46 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/examples/device/cdc_dual_ports/src/tusb_config.h b/examples/device/cdc_dual_ports/src/tusb_config.h index f8c36a90d..633a3faea 100644 --- a/examples/device/cdc_dual_ports/src/tusb_config.h +++ b/examples/device/cdc_dual_ports/src/tusb_config.h @@ -103,8 +103,8 @@ #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -// CDC Endpoint transfer buffer size, more is faster -// Only increase RX_EPSIZE if your host driver/application support zero-length packet (ZLP) +// CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. +// Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index c4f4374a2..f0709d8fb 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -103,8 +103,8 @@ #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -// CDC Endpoint transfer buffer size, more is faster -// Only increase RX_EPSIZE if your host driver/application support zero-length packet (ZLP) +// CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. +// Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/examples/device/cdc_msc_freertos/src/tusb_config.h b/examples/device/cdc_msc_freertos/src/tusb_config.h index 33342819e..a78f2ea05 100644 --- a/examples/device/cdc_msc_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_freertos/src/tusb_config.h @@ -110,8 +110,8 @@ #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -// CDC Endpoint transfer buffer size, more is faster -// Only increase RX_EPSIZE if your host driver/application support zero-length packet (ZLP) +// CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. +// Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/examples/device/cdc_uac2/src/tusb_config.h b/examples/device/cdc_uac2/src/tusb_config.h index 6724b83b3..358ff6747 100644 --- a/examples/device/cdc_uac2/src/tusb_config.h +++ b/examples/device/cdc_uac2/src/tusb_config.h @@ -159,8 +159,8 @@ extern "C" { #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -// CDC Endpoint transfer buffer size, more is faster -// Only increase RX_EPSIZE if your host driver/application support zero-length packet (ZLP) +// CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. +// Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/examples/device/printer_to_cdc/src/tusb_config.h b/examples/device/printer_to_cdc/src/tusb_config.h index d12313ce5..74b96c8f6 100644 --- a/examples/device/printer_to_cdc/src/tusb_config.h +++ b/examples/device/printer_to_cdc/src/tusb_config.h @@ -102,7 +102,8 @@ extern "C" { #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -// CDC Endpoint transfer buffer size +// CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. +// Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/examples/dual/dynamic_switch/src/tusb_config.h b/examples/dual/dynamic_switch/src/tusb_config.h index f9500f923..f3e016305 100644 --- a/examples/dual/dynamic_switch/src/tusb_config.h +++ b/examples/dual/dynamic_switch/src/tusb_config.h @@ -129,7 +129,8 @@ extern "C" { #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -// CDC Endpoint transfer buffer size, more is faster +// CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. +// Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/examples/dual/host_hid_to_device_cdc/src/tusb_config.h b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h index 0a7137d29..fb2a401b5 100644 --- a/examples/dual/host_hid_to_device_cdc/src/tusb_config.h +++ b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h @@ -114,7 +114,8 @@ #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -// CDC Endpoint transfer buffer size, more is faster +// CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. +// Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/examples/dual/host_info_to_device_cdc/src/tusb_config.h b/examples/dual/host_info_to_device_cdc/src/tusb_config.h index 8f3ed6357..99e9315a4 100644 --- a/examples/dual/host_info_to_device_cdc/src/tusb_config.h +++ b/examples/dual/host_info_to_device_cdc/src/tusb_config.h @@ -114,7 +114,8 @@ #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 256) -// CDC Endpoint transfer buffer size, more is faster +// CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. +// Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 3f207462e..c7547c92b 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -356,7 +356,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 } else { tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; tu_edpt_stream_open(stream_rx, rhport, desc_ep, - _cdcd_cfg.rx_need_zlp ? CFG_TUD_CDC_RX_EPSIZE : tu_edpt_packet_size(desc_ep)); + CFG_TUD_CDC_RX_NEED_ZLP ? CFG_TUD_CDC_RX_EPSIZE : tu_edpt_packet_size(desc_ep)); if (!_cdcd_cfg.rx_persistent) { tu_edpt_stream_clear(stream_rx); } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 3baf84d00..0348bd2ec 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -65,13 +65,17 @@ #endif #endif +// Enable multi-packet RX transfer with ZLP termination for better throughput. Requires host support for ZLP. +#ifndef CFG_TUD_CDC_RX_NEED_ZLP + #define CFG_TUD_CDC_RX_NEED_ZLP 0 +#endif + #ifndef CFG_TUD_CDC_CONFIGURE_DEFAULT #define CFG_TUD_CDC_CONFIGURE_DEFAULT() \ { \ .rx_persistent = false, \ .tx_persistent = false, \ .tx_overwritabe_if_not_connected = true, \ - .rx_need_zlp = false \ } #endif @@ -82,7 +86,6 @@ typedef struct { bool rx_persistent; // keep rx fifo data even with bus reset or disconnect bool tx_persistent; // keep tx fifo data even with reset or disconnect bool tx_overwritabe_if_not_connected; // if not connected, tx fifo can be overwritten - bool rx_need_zlp; // requires host support ZLP, allow transfer more than one packet in a single transfer, better throughput. } tud_cdc_configure_t; // Configure CDC driver behavior diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index c55cad627..e1017ba48 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -71,8 +71,6 @@ typedef struct { CFG_TUD_MEM_SECTION static vendord_epbuf_t _vendord_epbuf[CFG_TUD_VENDOR]; #endif -static tud_vendor_configure_t _vendord_cfg = CFG_TUD_VENDOR_CONFIGURE_DEFAULT(); - //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ @@ -87,15 +85,6 @@ TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t idx, uint32_t sent_bytes) { (void) sent_bytes; } -//-------------------------------------------------------------------- -// Application API -//-------------------------------------------------------------------- -bool tud_vendor_configure(const tud_vendor_configure_t* driver_cfg) { - TU_VERIFY(driver_cfg != NULL); - _vendord_cfg = *driver_cfg; - return true; -} - bool tud_vendor_n_mounted(uint8_t idx) { TU_VERIFY(idx < CFG_TUD_VENDOR); vendord_interface_t *p_itf = &_vendord_itf[idx]; @@ -307,7 +296,7 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uin const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); - uint16_t rx_xfer_len = _vendord_cfg.rx_need_zlp ? CFG_TUD_VENDOR_RX_EPSIZE : tu_edpt_packet_size(desc_ep); + uint16_t rx_xfer_len = CFG_TUD_VENDOR_RX_NEED_ZLP ? CFG_TUD_VENDOR_RX_EPSIZE : tu_edpt_packet_size(desc_ep); #if CFG_TUD_VENDOR_TXRX_BUFFERED // open endpoint stream diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 491a7d7fb..28accc698 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -74,24 +74,11 @@ extern "C" { #define CFG_TUD_VENDOR_RX_MANUAL_XFER 0 #endif -//--------------------------------------------------------------------+ -// Driver Configuration -//--------------------------------------------------------------------+ -typedef struct TU_ATTR_PACKED { - bool rx_need_zlp : 1; // requires host support ZLP, allow transfer more than one packet in a single transfer, better throughput. -} tud_vendor_configure_t; -TU_VERIFY_STATIC(sizeof(tud_vendor_configure_t) == 1, "size is not correct"); - -#ifndef CFG_TUD_VENDOR_CONFIGURE_DEFAULT - #define CFG_TUD_VENDOR_CONFIGURE_DEFAULT() \ - { \ - .rx_need_zlp = false, \ - } +// Enable multi-packet RX transfer with ZLP termination for better throughput. Requires host support for ZLP. +#ifndef CFG_TUD_VENDOR_RX_NEED_ZLP + #define CFG_TUD_VENDOR_RX_NEED_ZLP 0 #endif -// Configure CDC driver behavior -bool tud_vendor_configure(const tud_vendor_configure_t* driver_cfg); - //--------------------------------------------------------------------+ // Application API (Multiple Interfaces) i.e CFG_TUD_VENDOR > 1 //--------------------------------------------------------------------+ diff --git a/test/fuzz/device/cdc/src/tusb_config.h b/test/fuzz/device/cdc/src/tusb_config.h index b4b45d798..14b7b627d 100644 --- a/test/fuzz/device/cdc/src/tusb_config.h +++ b/test/fuzz/device/cdc/src/tusb_config.h @@ -101,7 +101,8 @@ #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -// CDC Endpoint transfer buffer size, more is faster +// CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. +// Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/test/fuzz/device/msc/src/tusb_config.h b/test/fuzz/device/msc/src/tusb_config.h index 3400c141d..7a4a24fb8 100644 --- a/test/fuzz/device/msc/src/tusb_config.h +++ b/test/fuzz/device/msc/src/tusb_config.h @@ -101,7 +101,8 @@ #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -// CDC Endpoint transfer buffer size, more is faster +// CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. +// Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/test/fuzz/device/net/src/tusb_config.h b/test/fuzz/device/net/src/tusb_config.h index 46fc10cdb..de45e9ead 100644 --- a/test/fuzz/device/net/src/tusb_config.h +++ b/test/fuzz/device/net/src/tusb_config.h @@ -106,7 +106,8 @@ #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -// CDC Endpoint transfer buffer size, more is faster +// CDC Endpoint transfer buffer size, default to max bulk packet size (HS 512, FS 64). Larger is faster. +// Larger RX_EPSIZE requires CFG_TUD_CDC_RX_NEED_ZLP = 1 and host ZLP support #define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_EPSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -- cgit v1.3.1 From 222af862aa2b3898980e3ed8f28e70fe6c9a7ee9 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Mar 2026 15:22:52 +0700 Subject: refactor(cdc): remove runtime CDC driver configuration in favor of compile-time macros for simplicity and reduced complexity --- examples/dual/host_info_to_device_cdc/src/main.c | 4 --- src/class/cdc/cdc_device.c | 44 +++++++++++------------- src/class/cdc/cdc_device.h | 34 +++++++----------- 3 files changed, 32 insertions(+), 50 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/examples/dual/host_info_to_device_cdc/src/main.c b/examples/dual/host_info_to_device_cdc/src/main.c index fe2199a69..cf3430464 100644 --- a/examples/dual/host_info_to_device_cdc/src/main.c +++ b/examples/dual/host_info_to_device_cdc/src/main.c @@ -106,10 +106,6 @@ static void usb_device_init(void) { .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); - tud_cdc_configure_t cdc_cfg = CFG_TUD_CDC_CONFIGURE_DEFAULT(); - cdc_cfg.tx_persistent = true; - cdc_cfg.tx_overwritabe_if_not_connected = false; - tud_cdc_configure(&cdc_cfg); board_init_after_tusb(); } diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index c7547c92b..60fc38cab 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -116,7 +116,6 @@ TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) { // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; -static tud_cdc_configure_t _cdcd_cfg = CFG_TUD_CDC_CONFIGURE_DEFAULT(); TU_ATTR_ALWAYS_INLINE static inline uint8_t find_cdc_itf(uint8_t ep_addr) { for (uint8_t idx = 0; idx < CFG_TUD_CDC; idx++) { @@ -132,12 +131,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t find_cdc_itf(uint8_t ep_addr) { //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ -bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg) { - TU_VERIFY(driver_cfg != NULL); - _cdcd_cfg = *driver_cfg; - return true; -} - bool tud_cdc_n_ready(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC); TU_VERIFY(tud_ready()); @@ -272,7 +265,7 @@ void cdcd_init(void) { // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not // know if data is actually polled by terminal. This way the most current data is prioritized. // Default: is overwritable - tu_edpt_stream_init(&p_cdc->tx_stream, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, p_cdc->tx_ff_buf, + tu_edpt_stream_init(&p_cdc->tx_stream, false, true, CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED, p_cdc->tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, epin_buf); } } @@ -293,7 +286,7 @@ void cdcd_reset(uint8_t rhport) { cdcd_interface_t* p_cdc = &_cdcd_itf[i]; tu_memclr(p_cdc, ITF_MEM_RESET_SIZE); - tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, _cdcd_cfg.tx_overwritabe_if_not_connected); // back to default + tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED); // back to default tu_edpt_stream_close(&p_cdc->rx_stream); tu_edpt_stream_close(&p_cdc->tx_stream); } @@ -348,18 +341,21 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_CDC_TX_EPSIZE); - if (_cdcd_cfg.tx_persistent) { - tu_edpt_stream_write_xfer(stream_tx); // flush pending data - } else { - tu_edpt_stream_clear(stream_tx); - } + #if CFG_TUD_CDC_TX_PERSISTENT + tu_edpt_stream_write_xfer(stream_tx); // flush pending data + #else + tu_edpt_stream_clear(stream_tx); + #endif } else { tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; - tu_edpt_stream_open(stream_rx, rhport, desc_ep, - CFG_TUD_CDC_RX_NEED_ZLP ? CFG_TUD_CDC_RX_EPSIZE : tu_edpt_packet_size(desc_ep)); - if (!_cdcd_cfg.rx_persistent) { - tu_edpt_stream_clear(stream_rx); - } + #if CFG_TUD_CDC_RX_NEED_ZLP + tu_edpt_stream_open(stream_rx, rhport, desc_ep, CFG_TUD_CDC_RX_EPSIZE); + #else + tu_edpt_stream_open(stream_rx, rhport, desc_ep, tu_edpt_packet_size(desc_ep)); + #endif + #if !CFG_TUD_CDC_RX_PERSISTENT + tu_edpt_stream_clear(stream_rx); + #endif TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare for incoming data } } @@ -424,11 +420,11 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ p_cdc->line_state = (uint8_t) request->wValue; // If enabled: fifo overwriting is disabled if DTR bit is set and vice versa - if (_cdcd_cfg.tx_overwritabe_if_not_connected) { - tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, !dtr); - } else { - tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, false); - } + #if CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED + tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, !dtr); + #else + tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, false); + #endif TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); tud_cdc_line_state_cb(itf, dtr, rts); // invoke callback diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 0348bd2ec..e44d425b9 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -70,30 +70,20 @@ #define CFG_TUD_CDC_RX_NEED_ZLP 0 #endif -#ifndef CFG_TUD_CDC_CONFIGURE_DEFAULT - #define CFG_TUD_CDC_CONFIGURE_DEFAULT() \ - { \ - .rx_persistent = false, \ - .tx_persistent = false, \ - .tx_overwritabe_if_not_connected = true, \ - } +// Keep rx fifo data even with bus reset or disconnect +#ifndef CFG_TUD_CDC_RX_PERSISTENT + #define CFG_TUD_CDC_RX_PERSISTENT 0 #endif -//--------------------------------------------------------------------+ -// Driver Configuration -//--------------------------------------------------------------------+ -typedef struct { - bool rx_persistent; // keep rx fifo data even with bus reset or disconnect - bool tx_persistent; // keep tx fifo data even with reset or disconnect - bool tx_overwritabe_if_not_connected; // if not connected, tx fifo can be overwritten -} tud_cdc_configure_t; - -// Configure CDC driver behavior -bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg); - -// Backward compatible -#define tud_cdc_configure_fifo_t tud_cdc_configure_t -#define tud_cdc_configure_fifo tud_cdc_configure +// Keep tx fifo data even with bus reset or disconnect +#ifndef CFG_TUD_CDC_TX_PERSISTENT + #define CFG_TUD_CDC_TX_PERSISTENT 0 +#endif + +// If not connected, tx fifo can be overwritten +#ifndef CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED + #define CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED 1 +#endif //--------------------------------------------------------------------+ // Application API (Multiple Ports) i.e. CFG_TUD_CDC > 1 -- cgit v1.3.1 From cd60008e8921a9c1d1d98c44e67c4fd1ceca075c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Mar 2026 15:56:48 +0700 Subject: clean up --- src/class/cdc/cdc_device.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'src/class/cdc/cdc_device.c') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 60fc38cab..c499756b9 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -341,21 +341,26 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream; tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_CDC_TX_EPSIZE); - #if CFG_TUD_CDC_TX_PERSISTENT + + #if CFG_TUD_CDC_TX_PERSISTENT tu_edpt_stream_write_xfer(stream_tx); // flush pending data - #else + #else tu_edpt_stream_clear(stream_tx); - #endif + #endif } else { tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream; - #if CFG_TUD_CDC_RX_NEED_ZLP - tu_edpt_stream_open(stream_rx, rhport, desc_ep, CFG_TUD_CDC_RX_EPSIZE); - #else - tu_edpt_stream_open(stream_rx, rhport, desc_ep, tu_edpt_packet_size(desc_ep)); - #endif - #if !CFG_TUD_CDC_RX_PERSISTENT + #if CFG_TUD_CDC_RX_NEED_ZLP + const uint16_t xfer_len = CFG_TUD_CDC_RX_EPSIZE; + #else + const uint16_t xfer_len = tu_edpt_packet_size(desc_ep); + #endif + + tu_edpt_stream_open(stream_rx, rhport, desc_ep, xfer_len); + + #if !CFG_TUD_CDC_RX_PERSISTENT tu_edpt_stream_clear(stream_rx); - #endif + #endif + TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare for incoming data } } @@ -420,12 +425,13 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ p_cdc->line_state = (uint8_t) request->wValue; // If enabled: fifo overwriting is disabled if DTR bit is set and vice versa - #if CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED - tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, !dtr); - #else - tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, false); - #endif + #if CFG_TUD_CDC_TX_OVERWRITABLE_IF_NOT_CONNECTED + const bool is_overwritable = !dtr; + #else + const bool is_overwritable = false; + #endif + tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, is_overwritable); TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); tud_cdc_line_state_cb(itf, dtr, rts); // invoke callback } else { -- cgit v1.3.1