From 9257a0f562a1cb939a902e7c41de5032b0f7de19 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 18 Aug 2023 12:48:12 +0700 Subject: - update nrf52 bsp for cmake - add empty tuh_int_handler/tud_int_handler if corresponidng stack not enabled - add hcd_template.c --- src/device/usbd.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/device/usbd.h') diff --git a/src/device/usbd.h b/src/device/usbd.h index b11c1a09d..782f538fd 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -50,8 +50,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr); // Task function should be called in main/rtos loop TU_ATTR_ALWAYS_INLINE static inline -void tud_task (void) -{ +void tud_task (void) { tud_task_ext(UINT32_MAX, false); } @@ -80,8 +79,7 @@ bool tud_suspended(void); // Check if device is ready to transfer TU_ATTR_ALWAYS_INLINE static inline -bool tud_ready(void) -{ +bool tud_ready(void) { return tud_mounted() && !tud_suspended(); } -- cgit v1.3.1 From 2d802e03e9a86ff3306398f1db59b8218f625c7f Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 24 Oct 2023 22:14:24 +0200 Subject: Update audio_4_channel_mic example for HS device. --- examples/device/audio_4_channel_mic/src/main.c | 30 ++++++++++++---------- .../device/audio_4_channel_mic/src/tusb_config.h | 4 +-- src/device/usbd.h | 6 ++--- 3 files changed, 22 insertions(+), 18 deletions(-) (limited to 'src/device/usbd.h') diff --git a/examples/device/audio_4_channel_mic/src/main.c b/examples/device/audio_4_channel_mic/src/main.c index 9c37315c8..1de4f9dac 100644 --- a/examples/device/audio_4_channel_mic/src/main.c +++ b/examples/device/audio_4_channel_mic/src/main.c @@ -71,10 +71,10 @@ audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range stat #if CFG_TUD_AUDIO_ENABLE_ENCODING // Audio test data, each buffer contains 2 channels, buffer[0] for CH0-1, buffer[1] for CH1-2 -uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ/2]; // Ensure half word aligned +uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000/CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; #else // Audio test data, 4 channels muxed together, buffer[0] for CH0, buffer[1] for CH1, buffer[2] for CH2, buffer[3] for CH3 -uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_EP_SZ_IN]; // Ensure half word aligned +uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000]; #endif void led_blinking_task(void); @@ -185,8 +185,21 @@ void tud_resume_cb(void) void audio_task(void) { - // Yet to be filled - e.g. put meas data into TX FIFOs etc. - // asm("nop"); + // Yet to be filled - e.g. read audio from I2S buffer. + // Here we simulate a I2S receive callback every 1ms. + static uint32_t start_ms = 0; + uint32_t curr_ms = board_millis(); + if ( start_ms == curr_ms ) return; // not enough time + start_ms = curr_ms; +#if CFG_TUD_AUDIO_ENABLE_ENCODING + // Write I2S buffer into FIFO + for (uint8_t cnt=0; cnt < 2; cnt++) + { + tud_audio_write_support_ff(cnt, i2s_dummy_buffer[cnt], AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX); + } +#else + tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX); +#endif } //--------------------------------------------------------------------+ @@ -453,15 +466,6 @@ bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, u // tud_audio_write_support_ff(channel, data, samples * N_BYTES_PER_SAMPLE * N_CHANNEL_PER_FIFO); // } -#if CFG_TUD_AUDIO_ENABLE_ENCODING - // Write I2S buffer into FIFO - for (uint8_t cnt=0; cnt < 2; cnt++) - { - tud_audio_write_support_ff(cnt, i2s_dummy_buffer[cnt], AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX); - } -#else - tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX); -#endif return true; } diff --git a/examples/device/audio_4_channel_mic/src/tusb_config.h b/examples/device/audio_4_channel_mic/src/tusb_config.h index cf44918e2..46484f847 100644 --- a/examples/device/audio_4_channel_mic/src/tusb_config.h +++ b/examples/device/audio_4_channel_mic/src/tusb_config.h @@ -126,12 +126,12 @@ extern "C" { #define CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING 1 #define CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX 2 // One I2S stream contains two channels, each stream is saved within one support FIFO - this value is currently fixed, the driver does not support a changing value #define CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX) -#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ 4 * (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) // Minimum 4*EP size is needed for flow control +#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) // Example write FIFO every 1ms, so it should be 8 times larger for HS device #else #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ 4 * CFG_TUD_AUDIO_EP_SZ_IN // Minimum 4*EP size is needed for flow control +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device #endif diff --git a/src/device/usbd.h b/src/device/usbd.h index 782f538fd..93a2033c4 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -465,7 +465,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) @@ -514,7 +514,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) @@ -562,7 +562,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ -- cgit v1.3.1 From 6e5c7f43906bac8ab47642e56c153297b83f3679 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 Nov 2023 16:08:06 +0700 Subject: rename to CFG_TUD_BTH_HISTORICAL_COMPATIBLE, move CFG_TUD_BTH_ISO_ALT_COUNT to tusb_option.h and mandatory for BTH driver --- src/class/bth/bth_device.c | 4 +++- src/class/bth/bth_device.h | 12 ++++++------ src/device/usbd.h | 4 ---- src/tusb_option.h | 13 +++++++++---- 4 files changed, 18 insertions(+), 15 deletions(-) (limited to 'src/device/usbd.h') diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index be36e8c11..f145e2ead 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -204,7 +204,9 @@ bool btd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t c request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE) { // HCI command packet addressing for single function Primary Controllers - TU_VERIFY((CFG_TUD_BTH_HISTORICAL_COMPAT && request->bRequest == 0xe0) || (request->bRequest == 0 && request->wValue == 0 && request->wIndex == 0)); + // also compatible with historical mode if enabled + TU_VERIFY((request->bRequest == 0 && request->wValue == 0 && request->wIndex == 0) || + (CFG_TUD_BTH_HISTORICAL_COMPATIBLE && request->bRequest == 0xe0)); } else if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE) { diff --git a/src/class/bth/bth_device.h b/src/class/bth/bth_device.h index c23e74bfb..e782c532b 100755 --- a/src/class/bth/bth_device.h +++ b/src/class/bth/bth_device.h @@ -36,15 +36,15 @@ #ifndef CFG_TUD_BTH_EVENT_EPSIZE #define CFG_TUD_BTH_EVENT_EPSIZE 16 #endif + #ifndef CFG_TUD_BTH_DATA_EPSIZE #define CFG_TUD_BTH_DATA_EPSIZE 64 #endif -#ifndef CFG_TUD_BTH_HISTORICAL_COMPAT -#define CFG_TUD_BTH_HISTORICAL_COMPAT 0 -#endif -#ifndef CFG_TUD_BTH_ISO_ALT_COUNT -// See Bluetooth Core v5.3, Vol. 4, Part B, Section 2.1 -#error You must tell the driver the number of ISO endpoints to use + +// Allow BTH class to work in historically compatibility mode where the bRequest is always 0xe0. +// See Bluetooth Core v5.3, Vol. 4, Part B, Section 2.2 +#ifndef CFG_TUD_BTH_HISTORICAL_COMPATIBLE +#define CFG_TUD_BTH_HISTORICAL_COMPATIBLE 0 #endif typedef struct TU_ATTR_PACKED diff --git a/src/device/usbd.h b/src/device/usbd.h index 93a2033c4..e14e3d6de 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -771,10 +771,6 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb #define TUD_BT_PROTOCOL_PRIMARY_CONTROLLER 0x01 #define TUD_BT_PROTOCOL_AMP_CONTROLLER 0x02 -#ifndef CFG_TUD_BTH_ISO_ALT_COUNT -#define CFG_TUD_BTH_ISO_ALT_COUNT 0 -#endif - // Length of template descriptor: 38 bytes + number of ISO alternatives * 23 #define TUD_BTH_DESC_LEN (8 + 9 + 7 + 7 + 7 + (CFG_TUD_BTH_ISO_ALT_COUNT) * (9 + 7 + 7)) diff --git a/src/tusb_option.h b/src/tusb_option.h index b8509a069..7920fbf35 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -342,6 +342,15 @@ #define CFG_TUD_INTERFACE_MAX 16 #endif +//------------- Device Class Driver -------------// +#ifndef CFG_TUD_BTH + #define CFG_TUD_BTH 0 +#endif + +#if CFG_TUD_BTH && !defined(CFG_TUD_BTH_ISO_ALT_COUNT) +#error CFG_TUD_BTH_ISO_ALT_COUNT must be defined to tell Bluetooth driver the number of ISO endpoints to use +#endif + #ifndef CFG_TUD_CDC #define CFG_TUD_CDC 0 #endif @@ -382,10 +391,6 @@ #define CFG_TUD_DFU 0 #endif -#ifndef CFG_TUD_BTH - #define CFG_TUD_BTH 0 -#endif - #ifndef CFG_TUD_ECM_RNDIS #ifdef CFG_TUD_NET #warning "CFG_TUD_NET is renamed to CFG_TUD_ECM_RNDIS" -- cgit v1.3.1 From 188fbd8ed9b5e0f5cc3ddb5e89f7afd421fc7c06 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 Nov 2023 18:21:24 +0700 Subject: add optional event hook callback tud_event_hook_cb() and tuh_event_hook_cb() --- src/device/usbd.c | 83 +++++++++++++++++++++++-------------------------------- src/device/usbd.h | 3 ++ src/host/usbh.c | 18 ++++++------ src/host/usbh.h | 5 +++- src/tusb_option.h | 12 -------- 5 files changed, 52 insertions(+), 69 deletions(-) (limited to 'src/device/usbd.h') diff --git a/src/device/usbd.c b/src/device/usbd.c index 2b6d07a96..59466b42e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -242,22 +242,17 @@ tu_static uint8_t _app_driver_count = 0; // virtually joins built-in and application drivers together. // Application is positioned first to allow overwriting built-in ones. -static inline usbd_class_driver_t const * get_driver(uint8_t drvid) -{ +TU_ATTR_ALWAYS_INLINE static inline usbd_class_driver_t const * get_driver(uint8_t drvid) { usbd_class_driver_t const * driver = NULL; - if ( drvid < _app_driver_count ) { // Application drivers driver = &_app_driver[drvid]; } else if ( drvid < TOTAL_DRIVER_COUNT && BUILTIN_DRIVER_COUNT > 0 ){ driver = &_usbd_driver[drvid - _app_driver_count]; } - return driver; } - - //--------------------------------------------------------------------+ // DCD Event //--------------------------------------------------------------------+ @@ -278,6 +273,11 @@ tu_static osal_queue_t _usbd_q; #define _usbd_mutex NULL #endif +TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) { + bool ret = osal_queue_send(_usbd_q, event, in_isr); + if (tud_event_hook_cb) tud_event_hook_cb(event->rhport, event->event_id, in_isr); + return ret; +} //--------------------------------------------------------------------+ // Prototypes @@ -374,8 +374,7 @@ bool tud_connect(void) //--------------------------------------------------------------------+ // USBD Task //--------------------------------------------------------------------+ -bool tud_inited(void) -{ +bool tud_inited(void) { return _usbd_rhport != RHPORT_INVALID; } @@ -1077,73 +1076,64 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const //--------------------------------------------------------------------+ // DCD Event Handler //--------------------------------------------------------------------+ -TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) -{ +TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) { bool send = false; - switch (event->event_id) - { + switch (event->event_id) { case DCD_EVENT_UNPLUGGED: - _usbd_dev.connected = 0; - _usbd_dev.addressed = 0; - _usbd_dev.cfg_num = 0; - _usbd_dev.suspended = 0; + _usbd_dev.connected = 0; + _usbd_dev.addressed = 0; + _usbd_dev.cfg_num = 0; + _usbd_dev.suspended = 0; send = true; - break; + break; case DCD_EVENT_SUSPEND: // NOTE: When plugging/unplugging device, the D+/D- state are unstable and // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ). // In addition, some MCUs such as SAMD or boards that haven no VBUS detection cannot distinguish // suspended vs disconnected. We will skip handling SUSPEND/RESUME event if not currently connected - if ( _usbd_dev.connected ) - { + if (_usbd_dev.connected) { _usbd_dev.suspended = 1; send = true; } - break; + break; case DCD_EVENT_RESUME: // skip event if not connected (especially required for SAMD) - if ( _usbd_dev.connected ) - { + if (_usbd_dev.connected) { _usbd_dev.suspended = 0; send = true; } - break; + break; case DCD_EVENT_SOF: - // SOF driver handler in ISR context - for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) - { - usbd_class_driver_t const * driver = get_driver(i); - if (driver && driver->sof) - { - driver->sof(event->rhport, event->sof.frame_count); - } - } - // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational - if ( _usbd_dev.suspended ) - { + if (_usbd_dev.suspended) { _usbd_dev.suspended = 0; - dcd_event_t const event_resume = { .rhport = event->rhport, .event_id = DCD_EVENT_RESUME }; - osal_queue_send(_usbd_q, &event_resume, in_isr); - CFG_TUD_EVENT_HOOK(&event_resume, in_isr); + dcd_event_t const event_resume = {.rhport = event->rhport, .event_id = DCD_EVENT_RESUME}; + queue_event(&event_resume, in_isr); + } + + // SOF driver handler in ISR context + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); + if (driver && driver->sof) { + driver->sof(event->rhport, event->sof.frame_count); + } } // skip osal queue for SOF in usbd task - break; + break; default: send = true; - break; + break; } if (send) { - osal_queue_send(_usbd_q, event, in_isr); - CFG_TUD_EVENT_HOOK(event, in_isr); + queue_event(event, in_isr); } } @@ -1187,18 +1177,15 @@ bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count } // Helper to defer an isr function -void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) -{ - dcd_event_t event = - { +void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) { + dcd_event_t event = { .rhport = 0, .event_id = USBD_EVENT_FUNC_CALL, }; - event.func_call.func = func; event.func_call.param = param; - dcd_event_handler(&event, in_isr); + queue_event(&event, in_isr); } //--------------------------------------------------------------------+ diff --git a/src/device/usbd.h b/src/device/usbd.h index 93a2033c4..1e2f31b06 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -146,6 +146,9 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en); // Invoked when usb bus is resumed TU_ATTR_WEAK void tud_resume_cb(void); +// Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext() +TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); + // Invoked when received control request with VENDOR TYPE TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/host/usbh.c b/src/host/usbh.c index 2fdc8216d..bbda99ea2 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -247,9 +247,7 @@ CFG_TUH_MEM_SECTION struct //------------- Helper Function -------------// -TU_ATTR_ALWAYS_INLINE -static inline usbh_device_t* get_device(uint8_t dev_addr) -{ +TU_ATTR_ALWAYS_INLINE static inline usbh_device_t* get_device(uint8_t dev_addr) { TU_VERIFY(dev_addr > 0 && dev_addr <= TOTAL_DEVICES, NULL); return &_usbh_devices[dev_addr-1]; } @@ -268,6 +266,12 @@ TU_ATTR_WEAK void osal_task_delay(uint32_t msec) { } #endif +TU_ATTR_ALWAYS_INLINE static inline bool queue_event(hcd_event_t const * event, bool in_isr) { + bool ret = osal_queue_send(_usbh_q, event, in_isr); + if (tuh_event_hook_cb) tuh_event_hook_cb(event->rhport, event->event_id, in_isr); + return ret; +} + //--------------------------------------------------------------------+ // Device API //--------------------------------------------------------------------+ @@ -433,7 +437,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport); bool is_empty = osal_queue_empty(_usbh_q); - osal_queue_send(_usbh_q, &event, in_isr); + queue_event(&event, in_isr); if (is_empty) { // Exit if this is the only event in the queue, otherwise we may loop forever @@ -779,8 +783,7 @@ void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr) { event.func_call.func = func; event.func_call.param = param; - osal_queue_send(_usbh_q, &event, in_isr); - CFG_TUH_EVENT_HOOK(event, in_isr); + queue_event(&event, in_isr); } //--------------------------------------------------------------------+ @@ -936,8 +939,7 @@ TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) default: break; } - osal_queue_send(_usbh_q, event, in_isr); - CFG_TUH_EVENT_HOOK(event, in_isr); + queue_event(event, in_isr); } //--------------------------------------------------------------------+ diff --git a/src/host/usbh.h b/src/host/usbh.h index 770d70dfe..7591c7672 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -90,9 +90,12 @@ TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr); // Invoked when a device failed to mount during enumeration process // TU_ATTR_WEAK void tuh_mount_failed_cb (uint8_t daddr); -/// Invoked when a device is unmounted (detached) +// Invoked when a device is unmounted (detached) TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr); +// Invoked when there is a new usb event, which need to be processed by tuh_task()/tuh_task_ext() +TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); + //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ diff --git a/src/tusb_option.h b/src/tusb_option.h index cf774a41c..b8509a069 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -486,18 +486,6 @@ #define tuc_int_handler(_p) #endif -//--------------------------------------------------------------------+ -// Optional event hook functions for platform integration (defaults) -//--------------------------------------------------------------------+ - -#ifndef CFG_TUD_EVENT_HOOK -#define CFG_TUD_EVENT_HOOK(EVENT, IN_ISR) -#endif - -#ifndef CFG_TUH_EVENT_HOOK -#define CFG_TUH_EVENT_HOOK(EVENT, IN_ISR) -#endif - //------------------------------------------------------------------ // Configuration Validation //------------------------------------------------------------------ -- cgit v1.3.1 From 290f4bea91e739979217eb91d589a75f9ac0f6a7 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 12 Jan 2024 15:47:08 +0700 Subject: - change tuh_event_hook_cb, tud_event_hook_cb to weak default implementation - change code style --- src/device/usbd.c | 362 +++++++++++++++++++++++----------------------- src/device/usbd.h | 2 +- src/device/usbd_control.c | 33 ++--- src/host/usbh.c | 126 ++++++++-------- src/host/usbh.h | 2 +- 5 files changed, 255 insertions(+), 270 deletions(-) (limited to 'src/device/usbd.h') diff --git a/src/device/usbd.c b/src/device/usbd.c index 59466b42e..5c94ebcc5 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -38,11 +38,19 @@ //--------------------------------------------------------------------+ // USBD Configuration //--------------------------------------------------------------------+ - #ifndef CFG_TUD_TASK_QUEUE_SZ #define CFG_TUD_TASK_QUEUE_SZ 16 #endif +//--------------------------------------------------------------------+ +// Callback weak stubs (called if application does not provide) +//--------------------------------------------------------------------+ +TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { + (void)rhport; + (void)eventid; + (void)in_isr; +} + //--------------------------------------------------------------------+ // Device Data //--------------------------------------------------------------------+ @@ -50,10 +58,8 @@ // Invalid driver ID in itf2drv[] ep2drv[][] mapping enum { DRVID_INVALID = 0xFFu }; -typedef struct -{ - struct TU_ATTR_PACKED - { +typedef struct { + struct TU_ATTR_PACKED { volatile uint8_t connected : 1; volatile uint8_t addressed : 1; volatile uint8_t suspended : 1; @@ -85,151 +91,150 @@ tu_static usbd_device_t _usbd_dev; #endif // Built-in class drivers -tu_static usbd_class_driver_t const _usbd_driver[] = -{ - #if CFG_TUD_CDC - { - DRIVER_NAME("CDC") - .init = cdcd_init, - .reset = cdcd_reset, - .open = cdcd_open, - .control_xfer_cb = cdcd_control_xfer_cb, - .xfer_cb = cdcd_xfer_cb, - .sof = NULL - }, - #endif - - #if CFG_TUD_MSC - { - DRIVER_NAME("MSC") - .init = mscd_init, - .reset = mscd_reset, - .open = mscd_open, - .control_xfer_cb = mscd_control_xfer_cb, - .xfer_cb = mscd_xfer_cb, - .sof = NULL - }, - #endif - - #if CFG_TUD_HID - { - DRIVER_NAME("HID") - .init = hidd_init, - .reset = hidd_reset, - .open = hidd_open, - .control_xfer_cb = hidd_control_xfer_cb, - .xfer_cb = hidd_xfer_cb, - .sof = NULL - }, - #endif - - #if CFG_TUD_AUDIO - { - DRIVER_NAME("AUDIO") - .init = audiod_init, - .reset = audiod_reset, - .open = audiod_open, - .control_xfer_cb = audiod_control_xfer_cb, - .xfer_cb = audiod_xfer_cb, - .sof = audiod_sof_isr - }, - #endif - - #if CFG_TUD_VIDEO - { - DRIVER_NAME("VIDEO") - .init = videod_init, - .reset = videod_reset, - .open = videod_open, - .control_xfer_cb = videod_control_xfer_cb, - .xfer_cb = videod_xfer_cb, - .sof = NULL - }, - #endif - - #if CFG_TUD_MIDI - { - DRIVER_NAME("MIDI") - .init = midid_init, - .open = midid_open, - .reset = midid_reset, - .control_xfer_cb = midid_control_xfer_cb, - .xfer_cb = midid_xfer_cb, - .sof = NULL - }, - #endif - - #if CFG_TUD_VENDOR - { - DRIVER_NAME("VENDOR") - .init = vendord_init, - .reset = vendord_reset, - .open = vendord_open, - .control_xfer_cb = tud_vendor_control_xfer_cb, - .xfer_cb = vendord_xfer_cb, - .sof = NULL - }, - #endif - - #if CFG_TUD_USBTMC - { - DRIVER_NAME("TMC") - .init = usbtmcd_init_cb, - .reset = usbtmcd_reset_cb, - .open = usbtmcd_open_cb, - .control_xfer_cb = usbtmcd_control_xfer_cb, - .xfer_cb = usbtmcd_xfer_cb, - .sof = NULL - }, - #endif - - #if CFG_TUD_DFU_RUNTIME - { - DRIVER_NAME("DFU-RUNTIME") - .init = dfu_rtd_init, - .reset = dfu_rtd_reset, - .open = dfu_rtd_open, - .control_xfer_cb = dfu_rtd_control_xfer_cb, - .xfer_cb = NULL, - .sof = NULL - }, - #endif - - #if CFG_TUD_DFU - { - DRIVER_NAME("DFU") - .init = dfu_moded_init, - .reset = dfu_moded_reset, - .open = dfu_moded_open, - .control_xfer_cb = dfu_moded_control_xfer_cb, - .xfer_cb = NULL, - .sof = NULL - }, - #endif - - #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM - { - DRIVER_NAME("NET") - .init = netd_init, - .reset = netd_reset, - .open = netd_open, - .control_xfer_cb = netd_control_xfer_cb, - .xfer_cb = netd_xfer_cb, - .sof = NULL, - }, - #endif - - #if CFG_TUD_BTH - { - DRIVER_NAME("BTH") - .init = btd_init, - .reset = btd_reset, - .open = btd_open, - .control_xfer_cb = btd_control_xfer_cb, - .xfer_cb = btd_xfer_cb, - .sof = NULL - }, - #endif +tu_static usbd_class_driver_t const _usbd_driver[] = { + #if CFG_TUD_CDC + { + DRIVER_NAME("CDC") + .init = cdcd_init, + .reset = cdcd_reset, + .open = cdcd_open, + .control_xfer_cb = cdcd_control_xfer_cb, + .xfer_cb = cdcd_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_MSC + { + DRIVER_NAME("MSC") + .init = mscd_init, + .reset = mscd_reset, + .open = mscd_open, + .control_xfer_cb = mscd_control_xfer_cb, + .xfer_cb = mscd_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_HID + { + DRIVER_NAME("HID") + .init = hidd_init, + .reset = hidd_reset, + .open = hidd_open, + .control_xfer_cb = hidd_control_xfer_cb, + .xfer_cb = hidd_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_AUDIO + { + DRIVER_NAME("AUDIO") + .init = audiod_init, + .reset = audiod_reset, + .open = audiod_open, + .control_xfer_cb = audiod_control_xfer_cb, + .xfer_cb = audiod_xfer_cb, + .sof = audiod_sof_isr + }, + #endif + + #if CFG_TUD_VIDEO + { + DRIVER_NAME("VIDEO") + .init = videod_init, + .reset = videod_reset, + .open = videod_open, + .control_xfer_cb = videod_control_xfer_cb, + .xfer_cb = videod_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_MIDI + { + DRIVER_NAME("MIDI") + .init = midid_init, + .open = midid_open, + .reset = midid_reset, + .control_xfer_cb = midid_control_xfer_cb, + .xfer_cb = midid_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_VENDOR + { + DRIVER_NAME("VENDOR") + .init = vendord_init, + .reset = vendord_reset, + .open = vendord_open, + .control_xfer_cb = tud_vendor_control_xfer_cb, + .xfer_cb = vendord_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_USBTMC + { + DRIVER_NAME("TMC") + .init = usbtmcd_init_cb, + .reset = usbtmcd_reset_cb, + .open = usbtmcd_open_cb, + .control_xfer_cb = usbtmcd_control_xfer_cb, + .xfer_cb = usbtmcd_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_DFU_RUNTIME + { + DRIVER_NAME("DFU-RUNTIME") + .init = dfu_rtd_init, + .reset = dfu_rtd_reset, + .open = dfu_rtd_open, + .control_xfer_cb = dfu_rtd_control_xfer_cb, + .xfer_cb = NULL, + .sof = NULL + }, + #endif + + #if CFG_TUD_DFU + { + DRIVER_NAME("DFU") + .init = dfu_moded_init, + .reset = dfu_moded_reset, + .open = dfu_moded_open, + .control_xfer_cb = dfu_moded_control_xfer_cb, + .xfer_cb = NULL, + .sof = NULL + }, + #endif + + #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM + { + DRIVER_NAME("NET") + .init = netd_init, + .reset = netd_reset, + .open = netd_open, + .control_xfer_cb = netd_control_xfer_cb, + .xfer_cb = netd_xfer_cb, + .sof = NULL, + }, + #endif + + #if CFG_TUD_BTH + { + DRIVER_NAME("BTH") + .init = btd_init, + .reset = btd_reset, + .open = btd_open, + .control_xfer_cb = btd_control_xfer_cb, + .xfer_cb = btd_xfer_cb, + .sof = NULL + }, + #endif }; enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) }; @@ -275,7 +280,7 @@ tu_static osal_queue_t _usbd_q; TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) { bool ret = osal_queue_send(_usbd_q, event, in_isr); - if (tud_event_hook_cb) tud_event_hook_cb(event->rhport, event->event_id, in_isr); + tud_event_hook_cb(event->rhport, event->event_id, in_isr); return ret; } @@ -297,27 +302,23 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, // Debug //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL -tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] = -{ - "Invalid" , - "Bus Reset" , - "Unplugged" , - "SOF" , - "Suspend" , - "Resume" , - "Setup Received" , - "Xfer Complete" , - "Func Call" +tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] = { + "Invalid", + "Bus Reset", + "Unplugged", + "SOF", + "Suspend", + "Resume", + "Setup Received", + "Xfer Complete", + "Func Call" }; // for usbd_control to print the name of control complete driver -void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) -{ - for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) - { - usbd_class_driver_t const * driver = get_driver(i); - if ( driver && driver->control_xfer_cb == callback ) - { +void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) { + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); + if (driver && driver->control_xfer_cb == callback) { TU_LOG_USBD(" %s control complete\r\n", driver->name); return; } @@ -329,43 +330,36 @@ void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ -tusb_speed_t tud_speed_get(void) -{ +tusb_speed_t tud_speed_get(void) { return (tusb_speed_t) _usbd_dev.speed; } -bool tud_connected(void) -{ +bool tud_connected(void) { return _usbd_dev.connected; } -bool tud_mounted(void) -{ +bool tud_mounted(void) { return _usbd_dev.cfg_num ? true : false; } -bool tud_suspended(void) -{ +bool tud_suspended(void) { return _usbd_dev.suspended; } -bool tud_remote_wakeup(void) -{ +bool tud_remote_wakeup(void) { // only wake up host if this feature is supported and enabled and we are suspended - TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en ); + TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en); dcd_remote_wakeup(_usbd_rhport); return true; } -bool tud_disconnect(void) -{ +bool tud_disconnect(void) { TU_VERIFY(dcd_disconnect); dcd_disconnect(_usbd_rhport); return true; } -bool tud_connect(void) -{ +bool tud_connect(void) { TU_VERIFY(dcd_connect); dcd_connect(_usbd_rhport); return true; diff --git a/src/device/usbd.h b/src/device/usbd.h index 5456148bf..3ab6c813f 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -147,7 +147,7 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en); TU_ATTR_WEAK void tud_resume_cb(void); // Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext() -TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); +void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); // Invoked when received control request with VENDOR TYPE TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index a6081060e..ea18b28da 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -32,24 +32,32 @@ #include "tusb.h" #include "device/usbd_pvt.h" +//--------------------------------------------------------------------+ +// Callback weak stubs (called if application does not provide) +//--------------------------------------------------------------------+ +TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) { + (void)rhport; + (void)request; +} + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback); #endif -enum -{ +enum { EDPT_CTRL_OUT = 0x00, EDPT_CTRL_IN = 0x80 }; -typedef struct -{ +typedef struct { tusb_control_request_t request; - uint8_t* buffer; uint16_t data_len; uint16_t total_xferred; - usbd_control_xfer_cb_t complete_cb; } usbd_control_xfer_t; @@ -134,23 +142,12 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo //--------------------------------------------------------------------+ // USBD API //--------------------------------------------------------------------+ - -TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) -{ - (void)rhport; - (void)request; - - // this is the default implementation that is called when no "real" implementation - // of the function exists -} - void usbd_control_reset(void); void usbd_control_set_request(tusb_control_request_t const *request); void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp ); bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); -void usbd_control_reset(void) -{ +void usbd_control_reset(void) { tu_varclr(&_ctrl_xfer); } diff --git a/src/host/usbh.c b/src/host/usbh.c index 53e8a654b..dfe6ddb42 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -36,7 +36,6 @@ //--------------------------------------------------------------------+ // USBH Configuration //--------------------------------------------------------------------+ - #ifndef CFG_TUH_TASK_QUEUE_SZ #define CFG_TUH_TASK_QUEUE_SZ 16 #endif @@ -46,11 +45,18 @@ #endif //--------------------------------------------------------------------+ -// USBH-HCD common data structure +// Callback weak stubs (called if application does not provide) //--------------------------------------------------------------------+ +TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { + (void) rhport; + (void) eventid; + (void) in_isr; +} -typedef struct -{ +//--------------------------------------------------------------------+ +// USBH-HCD common data structure +//--------------------------------------------------------------------+ +typedef struct { // port uint8_t rhport; uint8_t hub_addr; @@ -112,60 +118,58 @@ typedef struct { //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ - #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL #define DRIVER_NAME(_name) .name = _name, #else #define DRIVER_NAME(_name) #endif -static usbh_class_driver_t const usbh_class_drivers[] = -{ - #if CFG_TUH_CDC +static usbh_class_driver_t const usbh_class_drivers[] = { + #if CFG_TUH_CDC { - DRIVER_NAME("CDC") - .init = cdch_init, - .open = cdch_open, - .set_config = cdch_set_config, - .xfer_cb = cdch_xfer_cb, - .close = cdch_close + DRIVER_NAME("CDC") + .init = cdch_init, + .open = cdch_open, + .set_config = cdch_set_config, + .xfer_cb = cdch_xfer_cb, + .close = cdch_close }, - #endif + #endif - #if CFG_TUH_MSC + #if CFG_TUH_MSC { - DRIVER_NAME("MSC") - .init = msch_init, - .open = msch_open, - .set_config = msch_set_config, - .xfer_cb = msch_xfer_cb, - .close = msch_close + DRIVER_NAME("MSC") + .init = msch_init, + .open = msch_open, + .set_config = msch_set_config, + .xfer_cb = msch_xfer_cb, + .close = msch_close }, - #endif + #endif - #if CFG_TUH_HID + #if CFG_TUH_HID { - DRIVER_NAME("HID") - .init = hidh_init, - .open = hidh_open, - .set_config = hidh_set_config, - .xfer_cb = hidh_xfer_cb, - .close = hidh_close + DRIVER_NAME("HID") + .init = hidh_init, + .open = hidh_open, + .set_config = hidh_set_config, + .xfer_cb = hidh_xfer_cb, + .close = hidh_close }, - #endif + #endif - #if CFG_TUH_HUB + #if CFG_TUH_HUB { - DRIVER_NAME("HUB") - .init = hub_init, - .open = hub_open, - .set_config = hub_set_config, - .xfer_cb = hub_xfer_cb, - .close = hub_close + DRIVER_NAME("HUB") + .init = hub_init, + .open = hub_open, + .set_config = hub_set_config, + .xfer_cb = hub_xfer_cb, + .close = hub_close }, - #endif + #endif - #if CFG_TUH_VENDOR + #if CFG_TUH_VENDOR { DRIVER_NAME("VENDOR") .init = cush_init, @@ -173,7 +177,7 @@ static usbh_class_driver_t const usbh_class_drivers[] = .xfer_cb = cush_isr, .close = cush_close } - #endif + #endif }; enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; @@ -233,8 +237,7 @@ static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; // Control transfers: since most controllers do not support multiple control transfers // on multiple devices concurrently and control transfers are not used much except for // enumeration, we will only execute control transfers one at a time. -CFG_TUH_MEM_SECTION struct -{ +CFG_TUH_MEM_SECTION struct { CFG_TUH_MEM_ALIGN tusb_control_request_t request; uint8_t* buffer; tuh_xfer_cb_t complete_cb; @@ -268,7 +271,7 @@ TU_ATTR_WEAK void osal_task_delay(uint32_t msec) { TU_ATTR_ALWAYS_INLINE static inline bool queue_event(hcd_event_t const * event, bool in_isr) { bool ret = osal_queue_send(_usbh_q, event, in_isr); - if (tuh_event_hook_cb) tuh_event_hook_cb(event->rhport, event->event_id, in_isr); + tuh_event_hook_cb(event->rhport, event->event_id, in_isr); return ret; } @@ -367,17 +370,14 @@ bool tuh_init(uint8_t controller_id) { tu_memclr(_usbh_devices, sizeof(_usbh_devices)); tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer)); - for(uint8_t i=0; iname); driver->init(); } @@ -545,8 +545,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { // Control transfer //--------------------------------------------------------------------+ -static void _control_blocking_complete_cb(tuh_xfer_t* xfer) -{ +static void _control_blocking_complete_cb(tuh_xfer_t* xfer) { // update result *((xfer_result_t*) xfer->user_data) = xfer->result; } @@ -625,21 +624,18 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) { return true; } -TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) -{ +TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) { (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); _ctrl_xfer.stage = stage; (void) osal_mutex_unlock(_usbh_mutex); } -static void _xfer_complete(uint8_t daddr, xfer_result_t result) -{ +static void _xfer_complete(uint8_t daddr, xfer_result_t result) { TU_LOG_USBH("\r\n"); // duplicate xfer since user can execute control transfer within callback tusb_control_request_t const request = _ctrl_xfer.request; - tuh_xfer_t xfer_temp = - { + tuh_xfer_t xfer_temp = { .daddr = daddr, .ep_addr = 0, .result = result, @@ -652,8 +648,7 @@ static void _xfer_complete(uint8_t daddr, xfer_result_t result) _set_control_xfer_stage(CONTROL_STAGE_IDLE); - if (xfer_temp.complete_cb) - { + if (xfer_temp.complete_cb) { xfer_temp.complete_cb(&xfer_temp); } } @@ -710,17 +705,16 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result // //--------------------------------------------------------------------+ -bool tuh_edpt_xfer(tuh_xfer_t* xfer) -{ - uint8_t const daddr = xfer->daddr; +bool tuh_edpt_xfer(tuh_xfer_t* xfer) { + uint8_t const daddr = xfer->daddr; uint8_t const ep_addr = xfer->ep_addr; TU_VERIFY(daddr && ep_addr); TU_VERIFY(usbh_edpt_claim(daddr, ep_addr)); - if ( !usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, xfer->complete_cb, xfer->user_data) ) - { + if (!usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, + xfer->complete_cb, xfer->user_data)) { usbh_edpt_release(daddr, ep_addr); return false; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 7591c7672..9ff118543 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -94,7 +94,7 @@ TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr); TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr); // Invoked when there is a new usb event, which need to be processed by tuh_task()/tuh_task_ext() -TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); +void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); //--------------------------------------------------------------------+ // APPLICATION API -- cgit v1.3.1 From f9c85ae47b0aacd6716b671a5b6ea289b43275c0 Mon Sep 17 00:00:00 2001 From: henneboi Date: Wed, 6 Mar 2024 17:46:47 +0100 Subject: IAR Warning: Fixed due to an boolean operation between enum (Pa089) Warning[Pa089]: enumerated type mixed with another enumerated type ...tusb_uac2_audio.c 199 This issue stops the build if we treat warning as error --- src/device/usbd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/device/usbd.h') diff --git a/src/device/usbd.h b/src/device/usbd.h index 3ab6c813f..cf500143a 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -421,7 +421,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */ #define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN 7 #define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(_ep, _interval) \ - TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN, TUSB_DESC_ENDPOINT, _ep, (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_NO_SYNC | TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(4), _interval + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN, TUSB_DESC_ENDPOINT, _ep, (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_NO_SYNC | (uint8_t)TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(4), _interval // AUDIO simple descriptor (UAC2) for 1 microphone input // - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source -- cgit v1.3.1 From 05f9cab1916195ceb55d73efa56d226b2451f5d1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 1 Apr 2024 19:48:45 +0200 Subject: UAC2: refactor interrupt endpoint support. --- src/class/audio/audio.h | 25 +++++++++ src/class/audio/audio_device.c | 114 ++++++++++++++++++----------------------- src/class/audio/audio_device.h | 51 +++--------------- src/device/usbd.h | 11 ++-- 4 files changed, 88 insertions(+), 113 deletions(-) (limited to 'src/device/usbd.h') diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index 70d431282..d6f3e22e2 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -924,6 +924,31 @@ typedef struct TU_ATTR_PACKED { } subrange[numSubRanges]; \ } +// 6.1 Interrupt Data Message Format +typedef struct TU_ATTR_PACKED +{ + uint8_t bInfo; + uint8_t bAttribute; + union + { + uint16_t wValue; + struct + { + uint8_t wValue_cn_or_mcn; + uint8_t wValue_cs; + }; + }; + union + { + uint16_t wIndex; + struct + { + uint8_t wIndex_ep_or_int; + uint8_t wIndex_entity_id; + }; + }; +} audio_interrupt_data_t; + /** @} */ #ifdef __cplusplus diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index f4e7de0c8..93e995c56 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -301,8 +301,8 @@ typedef struct #endif -#if CFG_TUD_AUDIO_INT_EPSIZE_IN - uint8_t ep_int; // Audio control interrupt EP. +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP + uint8_t ep_int; // Audio control interrupt EP. #endif /*------------- From this point, data is not cleared by bus reset -------------*/ @@ -358,8 +358,8 @@ typedef struct #endif // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) -#if CFG_TUD_AUDIO_INT_EPSIZE_IN - CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[CFG_TUD_AUDIO_INT_EP_IN_SW_BUFFER_SIZE]; +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP + CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[6]; #endif // Decoding parameters - parameters are set when alternate AS interface is set by host @@ -826,26 +826,29 @@ tu_fifo_t* tud_audio_n_get_tx_support_ff(uint8_t func_id, uint8_t ff_idx) #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP - // If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_done_cb() is called in inform user -uint16_t tud_audio_int_n_write(uint8_t func_id, uint8_t const* buffer, uint16_t len) +bool tud_audio_int_n_write(uint8_t func_id, const audio_interrupt_data_t * data) { - TU_VERIFY(_audiod_fct[func_id].ep_int != 0); - TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); + TU_VERIFY(_audiod_fct[func_id].ep_int != 0); + // We write directly into the EP's buffer - abort if previous transfer not complete - TU_VERIFY(!usbd_edpt_busy(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int)); + TU_VERIFY(usbd_edpt_claim(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int)); // Check length - TU_VERIFY(tu_memcpy_s(_audiod_fct[func_id].ep_int_buf, CFG_TUD_AUDIO_INT_EP_IN_SW_BUFFER_SIZE, buffer, len)==0); - - // Schedule transmit - TU_VERIFY(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int, _audiod_fct[func_id].ep_int_buf, len)); + if (tu_memcpy_s(_audiod_fct[func_id].ep_int_buf, sizeof(_audiod_fct[func_id].ep_int_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, _audiod_fct[func_id].ep_int_buf, sizeof(_audiod_fct[func_id].ep_int_buf)), 0); + } else + { + // Release endpoint since we don't make any transfer + usbd_edpt_release(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int); + } return true; } - #endif // This function is called once a transmit of an audio packet was successfully completed. Here, we encode samples and place it in IN EP's buffer for next transmission. @@ -1091,48 +1094,6 @@ static inline bool audiod_fb_send(uint8_t rhport, audiod_function_t *audio) } #endif -#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -static bool set_int_number(audiod_function_t *audio) -{ - - uint8_t const *p_desc = audio->p_desc; - // Get pointer at end - uint8_t const *p_desc_end = audio->p_desc + audio->desc_length - TUD_AUDIO_DESC_IAD_LEN; - - - bool found = false; - while (!found && p_desc < p_desc_end) - { - // For each interface/alternate - if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) - { - uint8_t foundEPs = 0, nEps = ((tusb_desc_interface_t const * )p_desc)->bNumEndpoints; - while (!found && foundEPs < nEps && p_desc < p_desc_end) - { - // For each endpoint - if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) - { - tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc; - uint8_t const ep_addr = desc_ep->bEndpointAddress; - // If endpoint is input-direction and interrupt-type - if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.xfer == 0x03) // Check if usage is interrupt EP - { - // Store endpoint number and open endpoint - audio->ep_int = ep_addr; - TU_ASSERT(usbd_edpt_open(audio->rhport, desc_ep)); - found = true; - } - foundEPs += 1; - } - p_desc = tu_desc_next(p_desc); - } - } - p_desc = tu_desc_next(p_desc); - } - return found; -} -#endif - //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ @@ -1492,10 +1453,11 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin // Verify version is correct - this check can be omitted TU_VERIFY(itf_desc->bInterfaceProtocol == AUDIO_INT_PROTOCOL_CODE_V2); - // Verify interrupt control EP is enabled if demanded by descriptor - this should be best some static check however - this check can be omitted - if (itf_desc->bNumEndpoints == 1) // 0 or 1 EPs are allowed + // Verify interrupt control EP is enabled if demanded by descriptor + TU_ASSERT(itf_desc->bNumEndpoints <= 1); // 0 or 1 EPs are allowed + if (itf_desc->bNumEndpoints == 1) { - TU_VERIFY(CFG_TUD_AUDIO_INT_EPSIZE_IN > 0); + TU_ASSERT(CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP); } // Alternate setting MUST be zero - this check can be omitted @@ -1639,6 +1601,31 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin } #endif // CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP + { + uint8_t const *p_desc = _audiod_fct[i].p_desc; + uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) + { + // For each endpoint + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) + { + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc; + uint8_t const ep_addr = desc_ep->bEndpointAddress; + // If endpoint is input-direction and interrupt-type + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.xfer == TUSB_XFER_INTERRUPT) + { + // Store endpoint number and open endpoint + _audiod_fct[i].ep_int = ep_addr; + TU_ASSERT(usbd_edpt_open(_audiod_fct[i].rhport, desc_ep)); + } + } + p_desc = tu_desc_next(p_desc); + } + } +#endif + break; } } @@ -1649,10 +1636,6 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin // This is all we need so far - the EPs are setup by a later set_interface request (as per UAC2 specification) uint16_t drv_len = _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; // - TUD_AUDIO_DESC_IAD_LEN since tinyUSB already handles the IAD descriptor -#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP - TU_ASSERT(set_int_number(&_audiod_fct[i])); -#endif - return drv_len; } @@ -2169,7 +2152,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 { audiod_function_t* audio = &_audiod_fct[func_id]; -#if CFG_TUD_AUDIO_INT_EPSIZE_IN +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP // Data transmission of control interrupt finished if (audio->ep_int == ep_addr) @@ -2181,7 +2164,8 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 // I assume here, that things above are handled by PHY // All transmission is done - what remains to do is to inform job was completed - if (tud_audio_int_done_cb) TU_VERIFY(tud_audio_int_done_cb(rhport, (uint16_t) xferred_bytes)); + if (tud_audio_int_done_cb) tud_audio_int_done_cb(rhport); + return true; } #endif diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 70bbd7ff6..040a760d6 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -198,21 +198,7 @@ // Enable/disable interrupt EP (required for notifying host of control changes) #ifndef CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -#define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 0 // Feedback - 0 or 1 -#endif - -// Audio interrupt control EP size - disabled if 0 -#ifndef CFG_TUD_AUDIO_INT_EPSIZE_IN -// Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) -#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -#define CFG_TUD_AUDIO_INT_EPSIZE_IN 6 -#else -#define CFG_TUD_AUDIO_INT_EPSIZE_IN 0 -#endif -#endif - -#ifndef CFG_TUD_AUDIO_INT_EP_IN_SW_BUFFER_SIZE -#define CFG_TUD_AUDIO_INT_EP_IN_SW_BUFFER_SIZE 6 // Buffer size of audio control interrupt EP - 6 Bytes according to UAC 2 specification (p. 74) +#define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 0 // Feedback - 0 or 1 #endif // Use software encoding/decoding @@ -404,7 +390,7 @@ tu_fifo_t* tud_audio_n_get_tx_support_ff (uint8_t func_id, uint8_t ff_i #endif #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -uint16_t tud_audio_int_n_write (uint8_t func_id, uint8_t const* buffer, uint16_t len); +bool tud_audio_int_n_write (uint8_t func_id, const audio_interrupt_data_t * data); #endif @@ -448,7 +434,7 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff (uint8_t ff_idx); // INT CTR API #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -static inline uint16_t tud_audio_int_write (uint8_t const* buffer, uint16_t len); +static inline bool tud_audio_int_write (const audio_interrupt_data_t * data); #endif // Buffer control EP data and schedule a transmit @@ -548,32 +534,7 @@ TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -// UAC2 §6.1 "interrupt data message" -typedef struct TU_ATTR_PACKED -{ - uint8_t bInfo; - uint8_t bAttribute; - union TU_ATTR_PACKED - { - uint16_t wValue; - struct TU_ATTR_PACKED - { - uint8_t wValue_cn_or_mcn; - uint8_t wValue_cs; - }; - }; - union TU_ATTR_PACKED - { - uint16_t wIndex; - struct TU_ATTR_PACKED - { - uint8_t wIndex_ep_or_int; - uint8_t wIndex_entity_id; - }; - }; -} audio_status_update_t; - -TU_ATTR_WEAK bool tud_audio_int_done_cb(uint8_t rhport, uint16_t n_bytes_copied); +TU_ATTR_WEAK void tud_audio_int_done_cb(uint8_t rhport); #endif // Invoked when audio set interface request received @@ -705,9 +666,9 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff(uint8_t ff_idx) #endif #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -static inline uint16_t tud_audio_int_write(uint8_t const* buffer, uint16_t len) +static inline bool tud_audio_int_write(const audio_interrupt_data_t * data) { - return tud_audio_int_n_write(0, buffer, len); + return tud_audio_int_n_write(0, data); } #endif diff --git a/src/device/usbd.h b/src/device/usbd.h index cf500143a..2e3987b99 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -393,6 +393,11 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb // For more channels, add definitions here +/* Standard AC Interrupt Endpoint Descriptor(4.8.2.1) */ +#define TUD_AUDIO_DESC_STD_AC_INT_EP_LEN 7 +#define TUD_AUDIO_DESC_STD_AC_INT_EP(_ep, _interval) \ + TUD_AUDIO_DESC_STD_AC_INT_EP_LEN, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(6), _interval + /* Standard AS Interface Descriptor(4.9.1) */ #define TUD_AUDIO_DESC_STD_AS_INT_LEN 9 #define TUD_AUDIO_DESC_STD_AS_INT(_itfnum, _altset, _nEPs, _stridx) \ @@ -468,7 +473,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) @@ -517,7 +522,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) @@ -565,7 +570,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ -- cgit v1.3.1 From 47c12a07f2edf927eaa685ee8c32b222271d770f Mon Sep 17 00:00:00 2001 From: "Felix \"xq\" Queißner" Date: Mon, 2 Jan 2023 17:09:45 +0100 Subject: Implements tuh_deinit() and tud_deinit() to uninitialize host/device mode. --- src/device/dcd.h | 3 +++ src/device/usbd.h | 5 ++++- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 12 ++++++++++++ src/portable/raspberrypi/rp2040/hcd_rp2040.c | 8 ++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) (limited to 'src/device/usbd.h') diff --git a/src/device/dcd.h b/src/device/dcd.h index 69c26bcf4..21f404e4f 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -122,6 +122,9 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W // Initialize controller to device mode void dcd_init(uint8_t rhport); +// Deinitialize controller, unset device mode. +void dcd_deinit(uint8_t rhport); + // Interrupt Handler void dcd_int_handler(uint8_t rhport); diff --git a/src/device/usbd.h b/src/device/usbd.h index 2e3987b99..a9350192b 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -37,9 +37,12 @@ extern "C" { // Application API //--------------------------------------------------------------------+ -// Init device stack +// Init device stack on roothub port bool tud_init (uint8_t rhport); +// Deinit device stack on roothub port +void tud_deinit(uint8_t rhport); + // Check if device stack is already initialized bool tud_inited(void); diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 5c564cb1c..ccc7ee102 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -407,6 +407,18 @@ void dcd_init(uint8_t rhport) { dcd_connect(rhport); } +void dcd_deinit(uint8_t rhport) { + assert(rhport == 0); + + dcd_disconnect(rhport); + reset_non_control_endpoints(); + irq_remove_handler(USBCTRL_IRQ, dcd_rp2040_irq); + + // reset usb hardware into initial state + reset_block(RESETS_RESET_USBCTRL_BITS); + unreset_block_wait(RESETS_RESET_USBCTRL_BITS); +} + void dcd_int_enable(__unused uint8_t rhport) { assert(rhport == 0); irq_set_enabled(USBCTRL_IRQ, true); diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index b351a9a07..762753a25 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -409,6 +409,14 @@ bool hcd_init(uint8_t rhport) return true; } +void hcd_deinit(uint8_t rhport) { + (void) rhport; + + irq_remove_handler(USBCTRL_IRQ, hcd_rp2040_irq); + reset_block(RESETS_RESET_USBCTRL_BITS); + unreset_block_wait(RESETS_RESET_USBCTRL_BITS); +} + void hcd_port_reset(uint8_t rhport) { (void) rhport; -- cgit v1.3.1 From c3c06484560d0102366a3a1b1101c35301009f97 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Apr 2024 22:07:56 +0700 Subject: add class driver deinit --- src/class/audio/audio_device.c | 4 + src/class/audio/audio_device.h | 1 + src/class/bth/bth_device.c | 7 +- src/class/bth/bth_device.h | 1 + src/class/cdc/cdc_device.c | 32 ++++- src/class/cdc/cdc_device.h | 1 + src/class/dfu/dfu_device.c | 7 +- src/class/dfu/dfu_device.h | 1 + src/class/dfu/dfu_rt_device.c | 7 +- src/class/dfu/dfu_rt_device.h | 1 + src/class/hid/hid_device.c | 7 +- src/class/hid/hid_device.h | 1 + src/class/midi/midi_device.c | 36 ++++- src/class/midi/midi_device.h | 1 + src/class/msc/msc_device.c | 8 +- src/class/msc/msc_device.h | 1 + src/class/net/ecm_rndis_device.c | 7 +- src/class/net/ncm_device.c | 4 + src/class/net/net_device.h | 1 + src/class/usbtmc/usbtmc_device.c | 5 + src/class/usbtmc/usbtmc_device.h | 3 +- src/class/vendor/vendor_device.c | 38 ++++- src/class/vendor/vendor_device.h | 1 + src/class/video/video_device.c | 4 + src/class/video/video_device.h | 1 + src/device/dcd.h | 2 +- src/device/usbd.c | 204 +++++++++++++++++---------- src/device/usbd.h | 2 +- src/device/usbd_pvt.h | 4 +- src/host/usbh.c | 2 +- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 5 +- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 4 +- src/tusb_option.h | 2 +- 33 files changed, 292 insertions(+), 113 deletions(-) (limited to 'src/device/usbd.h') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 9a361419b..7077d66f8 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1396,6 +1396,10 @@ void audiod_init(void) } } +bool audiod_deinit(void) { + return false; // TODO not implemented yet +} + void audiod_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 040a760d6..b16514fd4 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -685,6 +685,7 @@ static inline bool tud_audio_fb_set(uint32_t feedback) // Internal Class Driver API //--------------------------------------------------------------------+ void audiod_init (void); +bool audiod_deinit (void); void audiod_reset (uint8_t rhport); uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index f145e2ead..cbf6e1332 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -91,11 +91,14 @@ bool tud_bt_acl_data_send(void *event, uint16_t event_len) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void btd_init(void) -{ +void btd_init(void) { tu_memclr(&_btd_itf, sizeof(_btd_itf)); } +bool btd_deinit(void) { + return true; +} + void btd_reset(uint8_t rhport) { (void)rhport; diff --git a/src/class/bth/bth_device.h b/src/class/bth/bth_device.h index e782c532b..4f6350839 100755 --- a/src/class/bth/bth_device.h +++ b/src/class/bth/bth_device.h @@ -104,6 +104,7 @@ bool tud_bt_acl_data_send(void *acl_data, uint16_t data_len); // Internal Class Driver API //--------------------------------------------------------------------+ void btd_init (void); +bool btd_deinit (void); void btd_reset (uint8_t rhport); uint16_t btd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool btd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const *request); diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index c26264e60..7ef0530ec 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -253,11 +253,39 @@ void cdcd_init(void) // In this way, the most current data is prioritized. tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true); - tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, osal_mutex_create(&p_cdc->rx_ff_mutex)); - tu_fifo_config_mutex(&p_cdc->tx_ff, osal_mutex_create(&p_cdc->tx_ff_mutex), NULL); + #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 } } +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; + + if (mutex_rd) { + osal_mutex_delete(mutex_rd); + tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, NULL); + } + + if (mutex_wr) { + osal_mutex_delete(mutex_wr); + tu_fifo_config_mutex(&p_cdc->tx_ff, NULL, NULL); + } + } + #endif + + return true; +} + void cdcd_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index a6e07aa5c..20e908451 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -247,6 +247,7 @@ static inline bool tud_cdc_write_clear(void) // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ void cdcd_init (void); +bool cdcd_deinit (void); void cdcd_reset (uint8_t rhport); uint16_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool cdcd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 3e7c13dea..71e7ac2b3 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -160,11 +160,14 @@ void dfu_moded_reset(uint8_t rhport) reset_state(); } -void dfu_moded_init(void) -{ +void dfu_moded_init(void) { dfu_moded_reset(0); } +bool dfu_moded_deinit(void) { + return true; +} + uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { (void) rhport; diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index fecf8596f..00c22ea8b 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -86,6 +86,7 @@ TU_ATTR_WEAK void tud_dfu_abort_cb(uint8_t alt); // Internal Class Driver API //--------------------------------------------------------------------+ void dfu_moded_init(void); +bool dfu_moded_deinit(void); void dfu_moded_reset(uint8_t rhport); uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/dfu/dfu_rt_device.c b/src/class/dfu/dfu_rt_device.c index a940d8d62..3b801b787 100644 --- a/src/class/dfu/dfu_rt_device.c +++ b/src/class/dfu/dfu_rt_device.c @@ -51,8 +51,11 @@ //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void dfu_rtd_init(void) -{ +void dfu_rtd_init(void) { +} + +bool dfu_rtd_deinit(void) { + return true; } void dfu_rtd_reset(uint8_t rhport) diff --git a/src/class/dfu/dfu_rt_device.h b/src/class/dfu/dfu_rt_device.h index babaa8214..67eb26d95 100644 --- a/src/class/dfu/dfu_rt_device.h +++ b/src/class/dfu/dfu_rt_device.h @@ -43,6 +43,7 @@ void tud_dfu_runtime_reboot_to_dfu_cb(void); // Internal Class Driver API //--------------------------------------------------------------------+ void dfu_rtd_init(void); +bool dfu_rtd_deinit(void); void dfu_rtd_reset(uint8_t rhport); uint16_t dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 5637ea6b4..e8eda1400 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -166,11 +166,14 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, //--------------------------------------------------------------------+ // USBD-CLASS API //--------------------------------------------------------------------+ -void hidd_init(void) -{ +void hidd_init(void) { hidd_reset(0); } +bool hidd_deinit(void) { + return true; +} + void hidd_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 17b24def1..53ecf9c06 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -406,6 +406,7 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y // Internal Class Driver API //--------------------------------------------------------------------+ void hidd_init (void); +bool hidd_deinit (void); void hidd_reset (uint8_t rhport); uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 052372a93..42905ab0d 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -373,12 +373,10 @@ bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4]) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void midid_init(void) -{ +void midid_init(void) { tu_memclr(_midid_itf, sizeof(_midid_itf)); - for(uint8_t i=0; itx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, false); // OBVS. #if CFG_FIFO_MUTEX - tu_fifo_config_mutex(&midi->rx_ff, NULL, osal_mutex_create(&midi->rx_ff_mutex)); - tu_fifo_config_mutex(&midi->tx_ff, osal_mutex_create(&midi->tx_ff_mutex), NULL); + osal_mutex_t mutex_rd = osal_mutex_create(&midi->rx_ff_mutex); + osal_mutex_t mutex_wr = osal_mutex_create(&midi->tx_ff_mutex); + TU_ASSERT(mutex_wr != NULL && mutex_wr != NULL, ); + + tu_fifo_config_mutex(&midi->rx_ff, NULL, mutex_rd); + tu_fifo_config_mutex(&midi->tx_ff, mutex_wr, NULL); #endif } } +bool midid_deinit(void) { + #if CFG_FIFO_MUTEX + for(uint8_t i=0; irx_ff.mutex_rd; + osal_mutex_t mutex_wr = midi->tx_ff.mutex_wr; + + if (mutex_rd) { + osal_mutex_delete(mutex_rd); + tu_fifo_config_mutex(&midi->rx_ff, NULL, NULL); + } + + if (mutex_wr) { + osal_mutex_delete(mutex_wr); + tu_fifo_config_mutex(&midi->tx_ff, NULL, NULL); + } + } + #endif + + return true; +} + void midid_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index 1c6f996be..3e89cc0a3 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -158,6 +158,7 @@ static inline bool tud_midi_packet_write (uint8_t const packet[4]) // Internal Class Driver API //--------------------------------------------------------------------+ void midid_init (void); +bool midid_deinit (void); void midid_reset (uint8_t rhport); uint16_t midid_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool midid_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index c145d86a6..588fcaaca 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -251,11 +251,15 @@ static inline void set_sense_medium_not_present(uint8_t lun) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void mscd_init(void) -{ +void mscd_init(void) { tu_memclr(&_mscd_itf, sizeof(mscd_interface_t)); } +bool mscd_deinit(void) { + // nothing to do + return true; +} + void mscd_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h index 72f95be06..4247a40bd 100644 --- a/src/class/msc/msc_device.h +++ b/src/class/msc/msc_device.h @@ -150,6 +150,7 @@ TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun); // Internal Class Driver API //--------------------------------------------------------------------+ void mscd_init (void); +bool mscd_deinit (void); void mscd_reset (uint8_t rhport); uint16_t mscd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool mscd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * p_request); diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c index 762425732..f7a5fd225 100644 --- a/src/class/net/ecm_rndis_device.c +++ b/src/class/net/ecm_rndis_device.c @@ -132,11 +132,14 @@ void netd_report(uint8_t *buf, uint16_t len) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void netd_init(void) -{ +void netd_init(void) { tu_memclr(&_netd_itf, sizeof(_netd_itf)); } +bool netd_deinit(void) { + return true; +} + void netd_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 226c42c4e..f84bd9f73 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -260,6 +260,10 @@ void netd_init(void) ncm_prepare_for_tx(); } +bool netd_deinit(void) { + return true; +} + void netd_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 399916355..da1a7b1e8 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -105,6 +105,7 @@ void tud_network_link_state_cb(bool state); // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ void netd_init (void); +bool netd_deinit (void); void netd_reset (uint8_t rhport); uint16_t netd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 573654d58..972a450e6 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -260,6 +260,11 @@ void usbtmcd_init_cb(void) usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); } +bool usbtmcd_deinit(void) { + osal_mutex_delete(usbtmcLock); + return true; +} + uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { (void)rhport; diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index c1298ddb8..3299a36eb 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -98,11 +98,12 @@ bool tud_usbtmc_start_bus_read(void); /* "callbacks" from USB device core */ +void usbtmcd_init_cb(void); +bool usbtmcd_deinit(void); uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); void usbtmcd_reset_cb(uint8_t rhport); bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); -void usbtmcd_init_cb(void); /************************************************************ * USBTMC Descriptor Templates diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index a68cb2156..e87ce3997 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -169,21 +169,47 @@ uint32_t tud_vendor_n_write_available (uint8_t itf) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void vendord_init(void) -{ +void vendord_init(void) { tu_memclr(_vendord_itf, sizeof(_vendord_itf)); - for(uint8_t i=0; irx_ff, p_itf->rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, 1, false); tu_fifo_config(&p_itf->tx_ff, p_itf->tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, 1, false); - tu_fifo_config_mutex(&p_itf->rx_ff, NULL, osal_mutex_create(&p_itf->rx_ff_mutex)); - tu_fifo_config_mutex(&p_itf->tx_ff, osal_mutex_create(&p_itf->tx_ff_mutex), NULL); + #if OSAL_MUTEX_REQUIRED + osal_mutex_t mutex_rd = osal_mutex_create(&p_itf->rx_ff_mutex); + osal_mutex_t mutex_wr = osal_mutex_create(&p_itf->tx_ff_mutex); + TU_ASSERT(mutex_rd && mutex_wr,); + + tu_fifo_config_mutex(&p_itf->rx_ff, NULL, mutex_rd); + tu_fifo_config_mutex(&p_itf->tx_ff, mutex_wr, NULL); + #endif + } +} + +bool vendord_deinit(void) { + #if OSAL_MUTEX_REQUIRED + for(uint8_t i=0; irx_ff.mutex_rd; + osal_mutex_t mutex_wr = p_itf->tx_ff.mutex_wr; + + if (mutex_rd) { + osal_mutex_delete(mutex_rd); + tu_fifo_config_mutex(&p_itf->rx_ff, NULL, NULL); + } + + if (mutex_wr) { + osal_mutex_delete(mutex_wr); + tu_fifo_config_mutex(&p_itf->tx_ff, NULL, NULL); + } } + #endif + + return true; } void vendord_reset(uint8_t rhport) diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index d239406b4..cd69ec7c6 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -139,6 +139,7 @@ static inline uint32_t tud_vendor_write_available (void) // Internal Class Driver API //--------------------------------------------------------------------+ void vendord_init(void); +bool vendord_deinit(void); void vendord_reset(uint8_t rhport); uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 5306356ba..c30690232 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -1229,6 +1229,10 @@ void videod_init(void) { } } +bool videod_deinit(void) { + return true; +} + void videod_reset(uint8_t rhport) { (void) rhport; for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO; ++i) { diff --git a/src/class/video/video_device.h b/src/class/video/video_device.h index ee2fcb9d5..92930c013 100644 --- a/src/class/video/video_device.h +++ b/src/class/video/video_device.h @@ -85,6 +85,7 @@ TU_ATTR_WEAK int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ void videod_init (void); +bool videod_deinit (void); void videod_reset (uint8_t rhport); uint16_t videod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/device/dcd.h b/src/device/dcd.h index 21f404e4f..d4f105aa3 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -123,7 +123,7 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W void dcd_init(uint8_t rhport); // Deinitialize controller, unset device mode. -void dcd_deinit(uint8_t rhport); +bool dcd_deinit(uint8_t rhport); // Interrupt Handler void dcd_int_handler(uint8_t rhport); diff --git a/src/device/usbd.c b/src/device/usbd.c index 8f98862c6..439e071ff 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -43,8 +43,13 @@ #endif //--------------------------------------------------------------------+ -// Callback weak stubs (called if application does not provide) +// Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ +TU_ATTR_WEAK bool dcd_deinit(uint8_t rhport) { + (void) rhport; + return false; +} + TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { (void)rhport; (void)eventid; @@ -85,17 +90,18 @@ tu_static usbd_device_t _usbd_dev; // Class Driver //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL - #define DRIVER_NAME(_name) .name = _name, + #define DRIVER_NAME(_name) _name #else - #define DRIVER_NAME(_name) + #define DRIVER_NAME(_name) NULL #endif // Built-in class drivers tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_CDC { - DRIVER_NAME("CDC") + .name = DRIVER_NAME("CDC"), .init = cdcd_init, + .deinit = cdcd_deinit, .reset = cdcd_reset, .open = cdcd_open, .control_xfer_cb = cdcd_control_xfer_cb, @@ -106,8 +112,9 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_MSC { - DRIVER_NAME("MSC") + .name = DRIVER_NAME("MSC"), .init = mscd_init, + .deinit = NULL, .reset = mscd_reset, .open = mscd_open, .control_xfer_cb = mscd_control_xfer_cb, @@ -118,121 +125,131 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_HID { - DRIVER_NAME("HID") - .init = hidd_init, - .reset = hidd_reset, - .open = hidd_open, - .control_xfer_cb = hidd_control_xfer_cb, - .xfer_cb = hidd_xfer_cb, - .sof = NULL + .name = DRIVER_NAME("HID"), + .init = hidd_init, + .deinit = hidd_deinit, + .reset = hidd_reset, + .open = hidd_open, + .control_xfer_cb = hidd_control_xfer_cb, + .xfer_cb = hidd_xfer_cb, + .sof = NULL }, #endif #if CFG_TUD_AUDIO { - DRIVER_NAME("AUDIO") - .init = audiod_init, - .reset = audiod_reset, - .open = audiod_open, - .control_xfer_cb = audiod_control_xfer_cb, - .xfer_cb = audiod_xfer_cb, - .sof = audiod_sof_isr + .name = DRIVER_NAME("AUDIO"), + .init = audiod_init, + .deinit = audiod_deinit, + .reset = audiod_reset, + .open = audiod_open, + .control_xfer_cb = audiod_control_xfer_cb, + .xfer_cb = audiod_xfer_cb, + .sof = audiod_sof_isr }, #endif #if CFG_TUD_VIDEO { - DRIVER_NAME("VIDEO") - .init = videod_init, - .reset = videod_reset, - .open = videod_open, - .control_xfer_cb = videod_control_xfer_cb, - .xfer_cb = videod_xfer_cb, - .sof = NULL + .name = DRIVER_NAME("VIDEO"), + .init = videod_init, + .deinit = videod_deinit, + .reset = videod_reset, + .open = videod_open, + .control_xfer_cb = videod_control_xfer_cb, + .xfer_cb = videod_xfer_cb, + .sof = NULL }, #endif #if CFG_TUD_MIDI { - DRIVER_NAME("MIDI") - .init = midid_init, - .open = midid_open, - .reset = midid_reset, - .control_xfer_cb = midid_control_xfer_cb, - .xfer_cb = midid_xfer_cb, - .sof = NULL + .name = DRIVER_NAME("MIDI"), + .init = midid_init, + .deinit = midid_deinit, + .open = midid_open, + .reset = midid_reset, + .control_xfer_cb = midid_control_xfer_cb, + .xfer_cb = midid_xfer_cb, + .sof = NULL }, #endif #if CFG_TUD_VENDOR { - DRIVER_NAME("VENDOR") - .init = vendord_init, - .reset = vendord_reset, - .open = vendord_open, - .control_xfer_cb = tud_vendor_control_xfer_cb, - .xfer_cb = vendord_xfer_cb, - .sof = NULL + .name = DRIVER_NAME("VENDOR"), + .init = vendord_init, + .deinit = vendord_deinit, + .reset = vendord_reset, + .open = vendord_open, + .control_xfer_cb = tud_vendor_control_xfer_cb, + .xfer_cb = vendord_xfer_cb, + .sof = NULL }, #endif #if CFG_TUD_USBTMC { - DRIVER_NAME("TMC") - .init = usbtmcd_init_cb, - .reset = usbtmcd_reset_cb, - .open = usbtmcd_open_cb, - .control_xfer_cb = usbtmcd_control_xfer_cb, - .xfer_cb = usbtmcd_xfer_cb, - .sof = NULL + .name = DRIVER_NAME("TMC"), + .init = usbtmcd_init_cb, + .deinit = usbtmcd_deinit, + .reset = usbtmcd_reset_cb, + .open = usbtmcd_open_cb, + .control_xfer_cb = usbtmcd_control_xfer_cb, + .xfer_cb = usbtmcd_xfer_cb, + .sof = NULL }, #endif #if CFG_TUD_DFU_RUNTIME { - DRIVER_NAME("DFU-RUNTIME") - .init = dfu_rtd_init, - .reset = dfu_rtd_reset, - .open = dfu_rtd_open, - .control_xfer_cb = dfu_rtd_control_xfer_cb, - .xfer_cb = NULL, - .sof = NULL + .name = DRIVER_NAME("DFU-RUNTIME"), + .init = dfu_rtd_init, + .deinit = dfu_rtd_deinit, + .reset = dfu_rtd_reset, + .open = dfu_rtd_open, + .control_xfer_cb = dfu_rtd_control_xfer_cb, + .xfer_cb = NULL, + .sof = NULL }, #endif #if CFG_TUD_DFU { - DRIVER_NAME("DFU") - .init = dfu_moded_init, - .reset = dfu_moded_reset, - .open = dfu_moded_open, - .control_xfer_cb = dfu_moded_control_xfer_cb, - .xfer_cb = NULL, - .sof = NULL + .name = DRIVER_NAME("DFU"), + .init = dfu_moded_init, + .deinit = dfu_moded_deinit, + .reset = dfu_moded_reset, + .open = dfu_moded_open, + .control_xfer_cb = dfu_moded_control_xfer_cb, + .xfer_cb = NULL, + .sof = NULL }, #endif #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM { - DRIVER_NAME("NET") - .init = netd_init, - .reset = netd_reset, - .open = netd_open, - .control_xfer_cb = netd_control_xfer_cb, - .xfer_cb = netd_xfer_cb, - .sof = NULL, + .name = DRIVER_NAME("NET"), + .init = netd_init, + .deinit = netd_deinit, + .reset = netd_reset, + .open = netd_open, + .control_xfer_cb = netd_control_xfer_cb, + .xfer_cb = netd_xfer_cb, + .sof = NULL, }, #endif #if CFG_TUD_BTH { - DRIVER_NAME("BTH") - .init = btd_init, - .reset = btd_reset, - .open = btd_open, - .control_xfer_cb = btd_control_xfer_cb, - .xfer_cb = btd_xfer_cb, - .sof = NULL + .name = DRIVER_NAME("BTH"), + .init = btd_init, + .deinit = btd_deinit, + .reset = btd_reset, + .open = btd_open, + .control_xfer_cb = btd_control_xfer_cb, + .xfer_cb = btd_xfer_cb, + .sof = NULL }, #endif }; @@ -402,7 +419,7 @@ bool tud_init(uint8_t rhport) { // Init class drivers for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); - TU_ASSERT(driver); + TU_ASSERT(driver && driver->init); TU_LOG_USBD("%s init\r\n", driver->name); driver->init(); } @@ -416,6 +433,41 @@ bool tud_init(uint8_t rhport) { return true; } +bool tud_deinit(uint8_t rhport) { + // skip if not initialized + if (!tud_inited()) return true; + + TU_LOG_USBD("USBD deinit on controller %u\r\n", rhport); + + // Deinit device controller driver + dcd_int_disable(rhport); + dcd_disconnect(rhport); + dcd_deinit(rhport); + + // Deinit class drivers + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); + if(driver && driver->deinit) { + TU_LOG_USBD("%s deinit\r\n", driver->name); + driver->deinit(); + } + } + + // Deinit device queue & task + osal_queue_delete(_usbd_q); + _usbd_q = NULL; + +#if OSAL_MUTEX_REQUIRED + // TODO make sure there is no task waiting on this mutex + osal_mutex_delete(_usbd_mutex); + _usbd_mutex = NULL; +#endif + + _usbd_rhport = RHPORT_INVALID; + + return true; +} + static void configuration_reset(uint8_t rhport) { for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); diff --git a/src/device/usbd.h b/src/device/usbd.h index a9350192b..0197628e2 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -41,7 +41,7 @@ extern "C" { bool tud_init (uint8_t rhport); // Deinit device stack on roothub port -void tud_deinit(uint8_t rhport); +bool tud_deinit(uint8_t rhport); // Check if device stack is already initialized bool tud_inited(void); diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 9039bc9d6..5ae96e589 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -40,11 +40,9 @@ //--------------------------------------------------------------------+ typedef struct { - #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL char const* name; - #endif - void (* init ) (void); + bool (* deinit ) (void); void (* reset ) (uint8_t rhport); uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len); bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/host/usbh.c b/src/host/usbh.c index aa0603d47..6a5491998 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -425,7 +425,7 @@ bool tuh_deinit(uint8_t rhport) { // Class drivers for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { usbh_class_driver_t const* driver = get_driver(drv_id); - if (driver) { + if (driver && driver->deinit) { TU_LOG_USBH("%s deinit\r\n", driver->name); driver->deinit(); } diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index ccc7ee102..a2b3375a3 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -407,16 +407,17 @@ void dcd_init(uint8_t rhport) { dcd_connect(rhport); } -void dcd_deinit(uint8_t rhport) { +bool dcd_deinit(uint8_t rhport) { assert(rhport == 0); - dcd_disconnect(rhport); reset_non_control_endpoints(); irq_remove_handler(USBCTRL_IRQ, dcd_rp2040_irq); // reset usb hardware into initial state reset_block(RESETS_RESET_USBCTRL_BITS); unreset_block_wait(RESETS_RESET_USBCTRL_BITS); + + return true; } void dcd_int_enable(__unused uint8_t rhport) { diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 762753a25..222dbbbf0 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -409,12 +409,14 @@ bool hcd_init(uint8_t rhport) return true; } -void hcd_deinit(uint8_t rhport) { +bool hcd_deinit(uint8_t rhport) { (void) rhport; irq_remove_handler(USBCTRL_IRQ, hcd_rp2040_irq); reset_block(RESETS_RESET_USBCTRL_BITS); unreset_block_wait(RESETS_RESET_USBCTRL_BITS); + + return true; } void hcd_port_reset(uint8_t rhport) diff --git a/src/tusb_option.h b/src/tusb_option.h index 2921d3ae0..cbcb69edd 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -34,7 +34,7 @@ #define TUSB_VERSION_MAJOR 0 #define TUSB_VERSION_MINOR 16 #define TUSB_VERSION_REVISION 0 -#define TUSB_VERSION_BUILD 2 +#define TUSB_VERSION_BUILD 3 #define TUSB_VERSION_NUMBER (TUSB_VERSION_MAJOR << 24 | TUSB_VERSION_MINOR << 16 | TUSB_VERSION_REVISION << 8 | TUSB_VERSION_BUILD) #define TUSB_VERSION_STRING TU_STRING(TUSB_VERSION_MAJOR) "." TU_STRING(TUSB_VERSION_MINOR) "." TU_STRING(TUSB_VERSION_REVISION) -- cgit v1.3.1 From 35e7fddc733c9abb7a6d6aae21994ca8bf053581 Mon Sep 17 00:00:00 2001 From: Trevor <4226647+trejan@users.noreply.github.com> Date: Tue, 30 Apr 2024 16:53:25 +0100 Subject: Add missing capability bit for CDC ACM serial break support The send break capability bit is needed for serial break support with Linux and possibly MacOS hosts. [A recent Linux kernel patch made it check the ACM capability bits before sending a serial break](https://github.com/raspberrypi/linux/commit/19e321c3eedd4c681a49f532a196bead5d57205e). --- src/device/usbd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/device/usbd.h') diff --git a/src/device/usbd.h b/src/device/usbd.h index 0197628e2..f36734040 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -221,8 +221,8 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\ /* CDC Call */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (uint8_t)((_itfnum) + 1),\ - /* CDC ACM: support line request */\ - 4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 2,\ + /* CDC ACM: support line request + send break */\ + 4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 6,\ /* CDC Union */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ /* Endpoint Notification */\ -- cgit v1.3.1