diff options
| author | hathach <[email protected]> | 2025-07-09 13:07:13 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2025-07-09 13:07:13 +0700 |
| commit | 386f5518992166dec0830659b21663aeddae4fc8 (patch) | |
| tree | c143f921067c6fbe0bbc9d68c8864b9b1fc71d11 /src/device | |
| parent | 965e26de1dcbd87c3b0e371857bc4ad0b9b3e840 (diff) | |
| parent | 04fb5873effebb3dff770e3257ed789ee36f3846 (diff) | |
Merge branch 'refs/heads/master' into fork/ChrisDeadman/hcd-samd-support
Diffstat (limited to 'src/device')
| -rw-r--r-- | src/device/dcd.h | 6 | ||||
| -rw-r--r-- | src/device/usbd.c | 137 | ||||
| -rw-r--r-- | src/device/usbd.h | 2 | ||||
| -rw-r--r-- | src/device/usbd_control.c | 55 | ||||
| -rw-r--r-- | src/device/usbd_pvt.h | 8 |
5 files changed, 143 insertions, 65 deletions
diff --git a/src/device/dcd.h b/src/device/dcd.h index d01f82e01..789552d47 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -93,15 +93,15 @@ typedef struct TU_ATTR_ALIGNED(4) { // clean/flush data cache: write cache -> memory. // Required before an DMA TX transfer to make sure data is in memory -void dcd_dcache_clean(void const* addr, uint32_t data_size) TU_ATTR_WEAK; +bool dcd_dcache_clean(const void* addr, uint32_t data_size); // invalidate data cache: mark cache as invalid, next read will read from memory // Required BOTH before and after an DMA RX transfer -void dcd_dcache_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK; +bool dcd_dcache_invalidate(const void* addr, uint32_t data_size); // clean and invalidate data cache // Required before an DMA transfer where memory is both read/write by DMA -void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK; +bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size); //--------------------------------------------------------------------+ // Controller API diff --git a/src/device/usbd.c b/src/device/usbd.c index a730b745b..1e16034a8 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -46,9 +46,7 @@ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { - (void) rhport; - (void) eventid; - (void) in_isr; + (void) rhport; (void) eventid; (void) in_isr; } TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count) { @@ -82,9 +80,7 @@ TU_ATTR_WEAK void tud_resume_cb(void) { } TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { - (void) rhport; - (void) stage; - (void) request; + (void) rhport; (void) stage; (void) request; return false; } @@ -101,6 +97,21 @@ TU_ATTR_WEAK void dcd_disconnect(uint8_t rhport) { (void) rhport; } +TU_ATTR_WEAK bool dcd_dcache_clean(const void* addr, uint32_t data_size) { + (void) addr; (void) data_size; + return true; +} + +TU_ATTR_WEAK bool dcd_dcache_invalidate(const void* addr, uint32_t data_size) { + (void) addr; (void) data_size; + return true; +} + +TU_ATTR_WEAK bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) { + (void) addr; (void) data_size; + return true; +} + //--------------------------------------------------------------------+ // Device Data //--------------------------------------------------------------------+ @@ -152,6 +163,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { .open = cdcd_open, .control_xfer_cb = cdcd_control_xfer_cb, .xfer_cb = cdcd_xfer_cb, + .xfer_isr = NULL, .sof = NULL }, #endif @@ -165,6 +177,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { .open = mscd_open, .control_xfer_cb = mscd_control_xfer_cb, .xfer_cb = mscd_xfer_cb, + .xfer_isr = NULL, .sof = NULL }, #endif @@ -178,6 +191,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { .open = hidd_open, .control_xfer_cb = hidd_control_xfer_cb, .xfer_cb = hidd_xfer_cb, + .xfer_isr = NULL, .sof = NULL }, #endif @@ -191,6 +205,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { .open = audiod_open, .control_xfer_cb = audiod_control_xfer_cb, .xfer_cb = audiod_xfer_cb, + .xfer_isr = audiod_xfer_isr, .sof = audiod_sof_isr }, #endif @@ -204,6 +219,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { .open = videod_open, .control_xfer_cb = videod_control_xfer_cb, .xfer_cb = videod_xfer_cb, + .xfer_isr = NULL, .sof = NULL }, #endif @@ -217,6 +233,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { .reset = midid_reset, .control_xfer_cb = midid_control_xfer_cb, .xfer_cb = midid_xfer_cb, + .xfer_isr = NULL, .sof = NULL }, #endif @@ -230,6 +247,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { .open = vendord_open, .control_xfer_cb = tud_vendor_control_xfer_cb, .xfer_cb = vendord_xfer_cb, + .xfer_isr = NULL, .sof = NULL }, #endif @@ -243,6 +261,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { .open = usbtmcd_open_cb, .control_xfer_cb = usbtmcd_control_xfer_cb, .xfer_cb = usbtmcd_xfer_cb, + .xfer_isr = NULL, .sof = NULL }, #endif @@ -256,6 +275,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { .open = dfu_rtd_open, .control_xfer_cb = dfu_rtd_control_xfer_cb, .xfer_cb = NULL, + .xfer_isr = NULL, .sof = NULL }, #endif @@ -269,6 +289,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { .open = dfu_moded_open, .control_xfer_cb = dfu_moded_control_xfer_cb, .xfer_cb = NULL, + .xfer_isr = NULL, .sof = NULL }, #endif @@ -282,7 +303,8 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { .open = netd_open, .control_xfer_cb = netd_control_xfer_cb, .xfer_cb = netd_xfer_cb, - .sof = NULL, + .xfer_isr = NULL, + .sof = NULL, }, #endif @@ -295,6 +317,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { .open = btd_open, .control_xfer_cb = btd_control_xfer_cb, .xfer_cb = btd_xfer_cb, + .xfer_isr = NULL, .sof = NULL }, #endif @@ -329,15 +352,16 @@ TU_ATTR_ALWAYS_INLINE static inline usbd_class_driver_t const * get_driver(uint8 enum { RHPORT_INVALID = 0xFFu }; tu_static uint8_t _usbd_rhport = RHPORT_INVALID; -// Event queue -// usbd_int_set() is used as mutex in OS NONE config +static OSAL_SPINLOCK_DEF(_usbd_spin, usbd_int_set); + +// Event queue: usbd_int_set() is used as mutex in OS NONE config OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); -tu_static osal_queue_t _usbd_q; +static osal_queue_t _usbd_q; // Mutex for claiming endpoint #if OSAL_MUTEX_REQUIRED - tu_static osal_mutex_def_t _ubsd_mutexdef; - tu_static osal_mutex_t _usbd_mutex; + static osal_mutex_def_t _ubsd_mutexdef; + static osal_mutex_t _usbd_mutex; #else #define _usbd_mutex NULL #endif @@ -453,17 +477,36 @@ bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { return true; // skip if already initialized } TU_ASSERT(rh_init); - - TU_LOG_USBD("USBD init on controller %u, speed = %s\r\n", rhport, - rh_init->speed == TUSB_SPEED_HIGH ? "High" : "Full"); +#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL + char const* speed_str = 0; + switch (rh_init->speed) { + case TUSB_SPEED_HIGH: + speed_str = "High"; + break; + case TUSB_SPEED_FULL: + speed_str = "Full"; + break; + case TUSB_SPEED_LOW: + speed_str = "Low"; + break; + case TUSB_SPEED_AUTO: + speed_str = "Auto"; + break; + default: + break; + } + TU_LOG_USBD("USBD init on controller %u, speed = %s\r\n", rhport, speed_str); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(dcd_event_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_fifo_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_edpt_stream_t)); +#endif tu_varclr(&_usbd_dev); _usbd_queued_setup = 0; + osal_spin_init(&_usbd_spin); + #if OSAL_MUTEX_REQUIRED // Init device mutex _usbd_mutex = osal_mutex_create(&_ubsd_mutexdef); @@ -550,8 +593,7 @@ static void usbd_reset(uint8_t rhport) { } bool tud_task_event_ready(void) { - // Skip if stack is not initialized - if (!tud_inited()) return false; + TU_VERIFY(tud_inited()); // Skip if stack is not initialized return !osal_queue_empty(_usbd_q); } @@ -673,7 +715,9 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { case USBD_EVENT_FUNC_CALL: TU_LOG_USBD("\r\n"); - if (event.func_call.func) event.func_call.func(event.func_call.param); + if (event.func_call.func) { + event.func_call.func(event.func_call.param); + } break; case DCD_EVENT_SOF: @@ -690,7 +734,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { #if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO // return if there is no more events, for application to run other background - if (osal_queue_empty(_usbd_q)) return; + if (osal_queue_empty(_usbd_q)) { return; } #endif } } @@ -1021,7 +1065,14 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) #endif #if CFG_TUD_MIDI - if ( driver->open == midid_open ) assoc_itf_count = 2; + if (driver->open == midid_open) { + // If there is a class-compliant Audio Control Class, then 2 interfaces. Otherwise, only one + if (TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && + AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass && + AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) { + assoc_itf_count = 2; + } + } #endif #if CFG_TUD_BTH && CFG_TUD_BTH_ISO_ALT_COUNT @@ -1209,6 +1260,32 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) send = true; break; + case DCD_EVENT_XFER_COMPLETE: { + // Invoke the class callback associated with the endpoint address + uint8_t const ep_addr = event->xfer_complete.ep_addr; + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const ep_dir = tu_edpt_dir(ep_addr); + + send = true; + if(epnum > 0) { + usbd_class_driver_t const* driver = get_driver(_usbd_dev.ep2drv[epnum][ep_dir]); + + if (driver && driver->xfer_isr) { + _usbd_dev.ep_status[epnum][ep_dir].busy = 0; + _usbd_dev.ep_status[epnum][ep_dir].claimed = 0; + + send = !driver->xfer_isr(event->rhport, ep_addr, (xfer_result_t) event->xfer_complete.result, event->xfer_complete.len); + + // xfer_isr() is deferred to xfer_cb(), revert busy/claimed status + if (send) { + _usbd_dev.ep_status[epnum][ep_dir].busy = 1; + _usbd_dev.ep_status[epnum][ep_dir].claimed = 1; + } + } + } + break; + } + default: send = true; break; @@ -1223,17 +1300,21 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) // USBD API For Class Driver //--------------------------------------------------------------------+ -void usbd_int_set(bool enabled) -{ - if (enabled) - { +void usbd_int_set(bool enabled) { + if (enabled) { dcd_int_enable(_usbd_rhport); - }else - { + } else { dcd_int_disable(_usbd_rhport); } } +void usbd_spin_lock(bool in_isr) { + osal_spin_lock(&_usbd_spin, in_isr); +} +void usbd_spin_unlock(bool in_isr) { + osal_spin_unlock(&_usbd_spin, in_isr); +} + // Parse consecutive endpoint descriptors (IN & OUT) bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in) { @@ -1278,7 +1359,7 @@ bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { rhport = _usbd_rhport; TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < CFG_TUD_ENDPPOINT_MAX); - TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed)); + TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed, false)); return dcd_edpt_open(rhport, desc_ep); } @@ -1479,7 +1560,7 @@ bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) uint8_t const dir = tu_edpt_dir(desc_ep->bEndpointAddress); TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX); - TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed)); + TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed, false)); _usbd_dev.ep_status[epnum][dir].stalled = 0; _usbd_dev.ep_status[epnum][dir].busy = 0; diff --git a/src/device/usbd.h b/src/device/usbd.h index de6007fb3..e5a848809 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -244,7 +244,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ /* CDC Union */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ /* Endpoint Notification */\ - 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 16,\ + 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 1,\ /* CDC Data Interface */\ 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\ /* Endpoint Out */\ diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index b1fd357aa..c9700fd9d 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -35,7 +35,7 @@ //--------------------------------------------------------------------+ // 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) { +TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, const tusb_control_request_t* request) { (void) rhport; (void) request; } @@ -44,10 +44,6 @@ TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_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 { EDPT_CTRL_OUT = 0x00, EDPT_CTRL_IN = 0x80 @@ -61,54 +57,53 @@ typedef struct { usbd_control_xfer_cb_t complete_cb; } usbd_control_xfer_t; -tu_static usbd_control_xfer_t _ctrl_xfer; +static usbd_control_xfer_t _ctrl_xfer; -CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN -tu_static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE]; +CFG_TUD_MEM_SECTION static struct { + TUD_EPBUF_DEF(buf, CFG_TUD_ENDPOINT0_SIZE); +} _ctrl_epbuf; //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ // Queue ZLP status transaction -static inline bool _status_stage_xact(uint8_t rhport, tusb_control_request_t const* request) { +static inline bool status_stage_xact(uint8_t rhport, const tusb_control_request_t* request) { // Opposite to endpoint in Data Phase - uint8_t const ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN; + const uint8_t ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN; return usbd_edpt_xfer(rhport, ep_addr, NULL, 0); } // Status phase -bool tud_control_status(uint8_t rhport, tusb_control_request_t const* request) { +bool tud_control_status(uint8_t rhport, const tusb_control_request_t* request) { _ctrl_xfer.request = (*request); _ctrl_xfer.buffer = NULL; _ctrl_xfer.total_xferred = 0; _ctrl_xfer.data_len = 0; - return _status_stage_xact(rhport, request); + return status_stage_xact(rhport, request); } // Queue a transaction in Data Stage // Each transaction has up to Endpoint0's max packet size. // This function can also transfer an zero-length packet -static bool _data_stage_xact(uint8_t rhport) { - uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred, - CFG_TUD_ENDPOINT0_SIZE); - +static bool data_stage_xact(uint8_t rhport) { + const uint16_t xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred, CFG_TUD_ENDPOINT0_SIZE); uint8_t ep_addr = EDPT_CTRL_OUT; if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN) { ep_addr = EDPT_CTRL_IN; if (xact_len) { - TU_VERIFY(0 == tu_memcpy_s(_usbd_ctrl_buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len)); + TU_VERIFY(0 == tu_memcpy_s(_ctrl_epbuf.buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len)); } } - return usbd_edpt_xfer(rhport, ep_addr, xact_len ? _usbd_ctrl_buf : NULL, xact_len); + return usbd_edpt_xfer(rhport, ep_addr, xact_len ? _ctrl_epbuf.buf : NULL, xact_len); } // Transmit data to/from the control endpoint. // If the request's wLength is zero, a status packet is sent instead. -bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const* request, void* buffer, uint16_t len) { +bool tud_control_xfer(uint8_t rhport, const tusb_control_request_t* request, void* buffer, uint16_t len) { _ctrl_xfer.request = (*request); _ctrl_xfer.buffer = (uint8_t*) buffer; _ctrl_xfer.total_xferred = 0U; @@ -118,14 +113,9 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const* request, voi if (_ctrl_xfer.data_len > 0U) { TU_ASSERT(buffer); } - -// TU_LOG2(" Control total data length is %u bytes\r\n", _ctrl_xfer.data_len); - - // Data stage - TU_ASSERT(_data_stage_xact(rhport)); + TU_ASSERT(data_stage_xact(rhport)); } else { - // Status stage - TU_ASSERT(_status_stage_xact(rhport, request)); + TU_ASSERT(status_stage_xact(rhport, request)); } return true; @@ -135,7 +125,7 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const* request, voi // USBD API //--------------------------------------------------------------------+ void usbd_control_reset(void); -void usbd_control_set_request(tusb_control_request_t const* request); +void usbd_control_set_request(const tusb_control_request_t* 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 result, uint32_t xferred_bytes); @@ -149,7 +139,7 @@ void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp) { } // for dcd_set_address where DCD is responsible for status response -void usbd_control_set_request(tusb_control_request_t const* request) { +void usbd_control_set_request(const tusb_control_request_t* request) { _ctrl_xfer.request = (*request); _ctrl_xfer.buffer = NULL; _ctrl_xfer.total_xferred = 0; @@ -179,8 +169,8 @@ bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT) { TU_VERIFY(_ctrl_xfer.buffer); - memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes); - TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _usbd_ctrl_buf, xferred_bytes, 2); + memcpy(_ctrl_xfer.buffer, _ctrl_epbuf.buf, xferred_bytes); + TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _ctrl_xfer.buffer, xferred_bytes, 2); } _ctrl_xfer.total_xferred += (uint16_t) xferred_bytes; @@ -204,8 +194,7 @@ bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, } if (is_ok) { - // Send status - TU_ASSERT(_status_stage_xact(rhport, &_ctrl_xfer.request)); + TU_ASSERT(status_stage_xact(rhport, &_ctrl_xfer.request)); } else { // Stall both IN and OUT control endpoint dcd_edpt_stall(rhport, EDPT_CTRL_OUT); @@ -213,7 +202,7 @@ bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, } } else { // More data to transfer - TU_ASSERT(_data_stage_xact(rhport)); + TU_ASSERT(data_stage_xact(rhport)); } return true; diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 90f37db3e..f1797bf0d 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -57,6 +57,7 @@ typedef struct { 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); bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + bool (* xfer_isr ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); // optional, return false to defer to xfer_cb() void (* sof ) (uint8_t rhport, uint32_t frame_count); // optional } usbd_class_driver_t; @@ -68,6 +69,8 @@ usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) TU_ATTR typedef bool (*usbd_control_xfer_cb_t)(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); void usbd_int_set(bool enabled); +void usbd_spin_lock(bool in_isr); +void usbd_spin_unlock(bool in_isr); //--------------------------------------------------------------------+ // USBD Endpoint API @@ -127,6 +130,11 @@ void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en); bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in); void usbd_defer_func(osal_task_func_t func, void *param, bool in_isr); + +#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL +void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback); +#endif + #ifdef __cplusplus } #endif |
