diff options
Diffstat (limited to 'src/device')
| -rw-r--r-- | src/device/usbd.c | 195 | ||||
| -rw-r--r-- | src/device/usbd.h | 9 | ||||
| -rw-r--r-- | src/device/usbd_control.c | 25 | ||||
| -rw-r--r-- | src/device/usbd_pvt.h | 6 |
4 files changed, 134 insertions, 101 deletions
diff --git a/src/device/usbd.c b/src/device/usbd.c index 90edc3dde..f6b00563d 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -93,131 +93,121 @@ 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_request = cdcd_control_request, - .control_complete = cdcd_control_complete, - .xfer_cb = cdcd_xfer_cb, - .sof = NULL + 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_request = mscd_control_request, - .control_complete = mscd_control_complete, - .xfer_cb = mscd_xfer_cb, - .sof = NULL + 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_request = hidd_control_request, - .control_complete = hidd_control_complete, - .xfer_cb = hidd_xfer_cb, - .sof = NULL + 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") + #if CFG_TUD_AUDIO + { + DRIVER_NAME("AUDIO") .init = audiod_init, - .reset = audiod_reset, + .reset = audiod_reset, .open = audiod_open, - .control_request = audiod_control_request, - .control_complete = audiod_control_complete, + .control_xfer_cb = audiod_control_xfer_cb, .xfer_cb = audiod_xfer_cb, .sof = NULL -}, -#endif + }, + #endif #if CFG_TUD_MIDI { - DRIVER_NAME("MIDI") - .init = midid_init, - .open = midid_open, - .reset = midid_reset, - .control_request = midid_control_request, - .control_complete = midid_control_complete, - .xfer_cb = midid_xfer_cb, - .sof = NULL + 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_request = tud_vendor_control_request_cb, - .control_complete = tud_vendor_control_complete_cb, - .xfer_cb = vendord_xfer_cb, - .sof = NULL + 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_request = usbtmcd_control_request_cb, - .control_complete = usbtmcd_control_complete_cb, - .xfer_cb = usbtmcd_xfer_cb, - .sof = NULL + 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_RT { - DRIVER_NAME("DFU-RT") - .init = dfu_rtd_init, - .reset = dfu_rtd_reset, - .open = dfu_rtd_open, - .control_request = dfu_rtd_control_request, - .control_complete = dfu_rtd_control_complete, - .xfer_cb = dfu_rtd_xfer_cb, - .sof = NULL + DRIVER_NAME("DFU-RT") + .init = dfu_rtd_init, + .reset = dfu_rtd_reset, + .open = dfu_rtd_open, + .control_xfer_cb = dfu_rtd_control_xfer_cb, + .xfer_cb = dfu_rtd_xfer_cb, + .sof = NULL }, #endif #if CFG_TUD_NET { - DRIVER_NAME("NET") - .init = netd_init, - .reset = netd_reset, - .open = netd_open, - .control_request = netd_control_request, - .control_complete = netd_control_complete, - .xfer_cb = netd_xfer_cb, - .sof = NULL, + 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_request = btd_control_request, - .control_complete = btd_control_complete, - .xfer_cb = btd_xfer_cb, - .sof = NULL + 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 }; @@ -274,7 +264,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const // from usbd_control.c void usbd_control_reset(void); void usbd_control_set_request(tusb_control_request_t const *request); -void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_request_t const * ) ); +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); @@ -313,12 +303,12 @@ static char const* const _tusb_std_request_str[] = }; // for usbd_control to print the name of control complete driver -void usbd_driver_print_control_complete_name(bool (*control_complete) (uint8_t, tusb_control_request_t const * )) +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->control_complete == control_complete ) + if ( driver->control_xfer_cb == callback ) { TU_LOG2(" %s control complete\r\n", driver->name); return; @@ -336,9 +326,14 @@ tusb_speed_t tud_speed_get(void) return (tusb_speed_t) _usbd_dev.speed; } +bool tud_connected(void) +{ + return _usbd_dev.connected; +} + bool tud_mounted(void) { - return _usbd_dev.cfg_num ? 1 : 0; + return _usbd_dev.cfg_num ? true : false; } bool tud_suspended(void) @@ -522,7 +517,7 @@ void tud_task (void) TU_ASSERT(driver, ); TU_LOG2(" %s xfer callback\r\n", driver->name); - driver->xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len); + driver->xfer_cb(event.rhport, ep_addr, (xfer_result_t)event.xfer_complete.result, event.xfer_complete.len); } } break; @@ -565,9 +560,9 @@ void tud_task (void) // Helper to invoke class driver control request handler static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * driver, tusb_control_request_t const * request) { - usbd_control_set_complete_callback(driver->control_complete); + usbd_control_set_complete_callback(driver->control_xfer_cb); TU_LOG2(" %s control request\r\n", driver->name); - return driver->control_request(rhport, request); + return driver->control_xfer_cb(rhport, CONTROL_STAGE_SETUP, request); } // This handles the actual request and its response. @@ -581,10 +576,10 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Vendor request if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) { - TU_VERIFY(tud_vendor_control_request_cb); + TU_VERIFY(tud_vendor_control_xfer_cb); - if (tud_vendor_control_complete_cb) usbd_control_set_complete_callback(tud_vendor_control_complete_cb); - return tud_vendor_control_request_cb(rhport, p_request); + usbd_control_set_complete_callback(tud_vendor_control_xfer_cb); + return tud_vendor_control_xfer_cb(rhport, CONTROL_STAGE_SETUP, p_request); } #if CFG_TUSB_DEBUG >= 2 @@ -938,6 +933,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const break; case TUSB_DESC_STRING: + { TU_LOG2(" String[%u]\r\n", desc_index); // String Descriptor always uses the desc set from user @@ -946,6 +942,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const // first byte of descriptor is its size return tud_control_xfer(rhport, p_request, (void*) desc_str, desc_str[0]); + } break; case TUSB_DESC_DEVICE_QUALIFIER: @@ -1106,6 +1103,24 @@ bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, desc_ep->wMaxPacketSize.size); + if (TUSB_XFER_ISOCHRONOUS == desc_ep->bmAttributes.xfer) + { + TU_ASSERT(desc_ep->wMaxPacketSize.size <= (_usbd_dev.speed == TUSB_SPEED_HIGH ? 1024 : 1023)); + } + else + { + uint16_t const max_epsize = (_usbd_dev.speed == TUSB_SPEED_HIGH ? 512 : 64); + + if (TUSB_XFER_BULK == desc_ep->bmAttributes.xfer) + { + // Bulk must be EXACTLY 512/64 bytes + TU_ASSERT(desc_ep->wMaxPacketSize.size == max_epsize); + }else + { + TU_ASSERT(desc_ep->wMaxPacketSize.size <= max_epsize); + } + } + return dcd_edpt_open(rhport, desc_ep); } diff --git a/src/device/usbd.h b/src/device/usbd.h index e88f64ba8..360567743 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -56,6 +56,9 @@ extern void dcd_int_handler(uint8_t rhport); // Get current bus speed tusb_speed_t tud_speed_get(void); +// Check if device is connected (may not mounted/configured yet) +bool tud_connected(void); + // Check if device is connected and configured bool tud_mounted(void); @@ -125,11 +128,7 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en); TU_ATTR_WEAK void tud_resume_cb(void); // Invoked when received control request with VENDOR TYPE -TU_ATTR_WEAK bool tud_vendor_control_request_cb(uint8_t rhport, tusb_control_request_t const * request); - -// Invoked when vendor control request is complete -TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_request_t const * request); - +TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); //--------------------------------------------------------------------+ // Binary Device Object Store (BOS) Descriptor Templates diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index db0eb70a7..8ed0ad1c0 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -33,7 +33,7 @@ #include "dcd.h" #if CFG_TUSB_DEBUG >= 2 -extern void usbd_driver_print_control_complete_name(bool (*control_complete) (uint8_t, tusb_control_request_t const *)); +extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback); #endif enum @@ -50,7 +50,7 @@ typedef struct uint16_t data_len; uint16_t total_xferred; - bool (*complete_cb) (uint8_t, tusb_control_request_t const *); + usbd_control_xfer_cb_t complete_cb; } usbd_control_xfer_t; static usbd_control_xfer_t _ctrl_xfer; @@ -140,13 +140,21 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo // USBD API //--------------------------------------------------------------------+ +//--------------------------------------------------------------------+ +// Prototypes +//--------------------------------------------------------------------+ +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) { tu_varclr(&_ctrl_xfer); } // TODO may find a better way -void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_request_t const * ) ) +void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp ) { _ctrl_xfer.complete_cb = fp; } @@ -171,7 +179,16 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result if ( tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction ) { TU_ASSERT(0 == xferred_bytes); + + // invoke optional dcd hook if available if (dcd_edpt0_status_complete) dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request); + + if (_ctrl_xfer.complete_cb) + { + // TODO refactor with usbd_driver_print_control_complete_name + _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_ACK, &_ctrl_xfer.request); + } + return true; } @@ -199,7 +216,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result usbd_driver_print_control_complete_name(_ctrl_xfer.complete_cb); #endif - is_ok = _ctrl_xfer.complete_cb(rhport, &_ctrl_xfer.request); + is_ok = _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_DATA, &_ctrl_xfer.request); } if ( is_ok ) diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 09b285581..212c3a202 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -46,8 +46,7 @@ typedef struct void (* init ) (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_request ) (uint8_t rhport, tusb_control_request_t const * request); - bool (* control_complete ) (uint8_t rhport, tusb_control_request_t const * request); + 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 event, uint32_t xferred_bytes); void (* sof ) (uint8_t rhport); /* optional */ } usbd_class_driver_t; @@ -57,6 +56,9 @@ typedef struct // Note: The drivers array must be accessible at all time when stack is active usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) TU_ATTR_WEAK; + +typedef bool (*usbd_control_xfer_cb_t)(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); + //--------------------------------------------------------------------+ // USBD Endpoint API //--------------------------------------------------------------------+ |
