diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 643706269..76526d40b 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -192,31 +192,31 @@ tusb_error_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface (*p_length) = sizeof(tusb_desc_interface_t); // Communication Functional Descriptors - while( TUSB_DESC_CLASS_SPECIFIC == p_desc[DESCRIPTOR_OFFSET_TYPE] ) + while( TUSB_DESC_CLASS_SPECIFIC == p_desc[DESC_OFFSET_TYPE] ) { - (*p_length) += p_desc[DESCRIPTOR_OFFSET_LENGTH]; + (*p_length) += p_desc[DESC_OFFSET_LEN]; p_desc = descriptor_next(p_desc); } - if ( TUSB_DESC_ENDPOINT == p_desc[DESCRIPTOR_OFFSET_TYPE]) + if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE]) { // notification endpoint if any TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), TUSB_ERROR_DCD_OPEN_PIPE_FAILED); p_cdc->ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; - (*p_length) += p_desc[DESCRIPTOR_OFFSET_LENGTH]; + (*p_length) += p_desc[DESC_OFFSET_LEN]; p_desc = descriptor_next(p_desc); } //------------- Data Interface (if any) -------------// - if ( (TUSB_DESC_INTERFACE == p_desc[DESCRIPTOR_OFFSET_TYPE]) && + if ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) && (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) ) { // p_cdc->itf_num = p_cdc->ep_count += ((tusb_desc_interface_t const *) p_desc)->bNumEndpoints; // next to endpoint descritpor - (*p_length) += p_desc[DESCRIPTOR_OFFSET_LENGTH]; + (*p_length) += p_desc[DESC_OFFSET_LEN]; p_desc = descriptor_next(p_desc); // Open endpoint pair with usbd helper diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index bd5b5e32c..6950759d1 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -167,32 +167,32 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_ //------------- Communication Interface -------------// (*p_length) = sizeof(tusb_desc_interface_t); - while( TUSB_DESC_CLASS_SPECIFIC == p_desc[DESCRIPTOR_OFFSET_TYPE] ) + while( TUSB_DESC_CLASS_SPECIFIC == p_desc[DESC_OFFSET_TYPE] ) { // Communication Functional Descriptors if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) ) { // save ACM bmCapabilities p_cdc->acm_capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities; } - (*p_length) += p_desc[DESCRIPTOR_OFFSET_LENGTH]; + (*p_length) += p_desc[DESC_OFFSET_LEN]; p_desc = descriptor_next(p_desc); } - if ( TUSB_DESC_ENDPOINT == p_desc[DESCRIPTOR_OFFSET_TYPE]) + if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE]) { // notification endpoint if any p_cdc->pipe_notification = hcd_pipe_open(dev_addr, (tusb_desc_endpoint_t const *) p_desc, TUSB_CLASS_CDC); - (*p_length) += p_desc[DESCRIPTOR_OFFSET_LENGTH]; + (*p_length) += p_desc[DESC_OFFSET_LEN]; p_desc = descriptor_next(p_desc); TU_ASSERT(pipehandle_is_valid(p_cdc->pipe_notification), TUSB_ERROR_HCD_OPEN_PIPE_FAILED); } //------------- Data Interface (if any) -------------// - if ( (TUSB_DESC_INTERFACE == p_desc[DESCRIPTOR_OFFSET_TYPE]) && + if ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) && (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) ) { - (*p_length) += p_desc[DESCRIPTOR_OFFSET_LENGTH]; + (*p_length) += p_desc[DESC_OFFSET_LEN]; p_desc = descriptor_next(p_desc); // data endpoints expected to be in pairs @@ -208,7 +208,7 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_ (*p_pipe_hdl) = hcd_pipe_open(dev_addr, p_endpoint, TUSB_CLASS_CDC); TU_ASSERT ( pipehandle_is_valid(*p_pipe_hdl), TUSB_ERROR_HCD_OPEN_PIPE_FAILED ); - (*p_length) += p_desc[DESCRIPTOR_OFFSET_LENGTH]; + (*p_length) += p_desc[DESC_OFFSET_LEN]; p_desc = descriptor_next( p_desc ); } } diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index bc2ee8c64..9f22697a6 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -259,12 +259,12 @@ tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface uint8_t const *p_desc = (uint8_t const *) p_interface_desc; //------------- HID descriptor -------------// - p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; + p_desc += p_desc[DESC_OFFSET_LEN]; tusb_hid_descriptor_hid_t const *p_desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; TU_ASSERT(HID_DESC_TYPE_HID == p_desc_hid->bDescriptorType, TUSB_ERROR_HIDD_DESCRIPTOR_INTERFACE); //------------- Endpoint Descriptor -------------// - p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; + p_desc += p_desc[DESC_OFFSET_LEN]; tusb_desc_endpoint_t const *p_desc_endpoint = (tusb_desc_endpoint_t const *) p_desc; TU_ASSERT(TUSB_DESC_ENDPOINT == p_desc_endpoint->bDescriptorType, TUSB_ERROR_HIDD_DESCRIPTOR_INTERFACE); diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 69f86ee0b..fe0b7748b 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -186,12 +186,12 @@ tusb_error_t hidh_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_ uint8_t const *p_desc = (uint8_t const *) p_interface_desc; //------------- HID descriptor -------------// - p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; + p_desc += p_desc[DESC_OFFSET_LEN]; tusb_hid_descriptor_hid_t const *p_desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; TU_ASSERT(HID_DESC_TYPE_HID == p_desc_hid->bDescriptorType, TUSB_ERROR_INVALID_PARA); //------------- Endpoint Descriptor -------------// - p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; + p_desc += p_desc[DESC_OFFSET_LEN]; tusb_desc_endpoint_t const * p_endpoint_desc = (tusb_desc_endpoint_t const *) p_desc; TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint_desc->bDescriptorType, TUSB_ERROR_INVALID_PARA); diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 2b45a50c9..ddfceabdb 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -144,12 +144,17 @@ static inline uint8_t const * descriptor_next(uint8_t const p_desc[]) { - return p_desc + p_desc[DESCRIPTOR_OFFSET_LENGTH]; + return p_desc + p_desc[DESC_OFFSET_LEN]; } -static inline uint8_t descriptor_typeof(uint8_t const p_desc[]) +static inline uint8_t descriptor_type(uint8_t const p_desc[]) { - return p_desc[DESCRIPTOR_OFFSET_TYPE]; + return p_desc[DESC_OFFSET_TYPE]; +} + +static inline uint8_t descriptor_len(uint8_t const p_desc[]) +{ + return p_desc[DESC_OFFSET_LEN]; } //------------- Conversion -------------// diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 4b8ef899c..65e7cd999 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -203,8 +203,8 @@ typedef enum }tusb_event_t; enum { - DESCRIPTOR_OFFSET_LENGTH = 0, - DESCRIPTOR_OFFSET_TYPE = 1 + DESC_OFFSET_LEN = 0, + DESC_OFFSET_TYPE = 1 }; enum { diff --git a/src/device/usbd.c b/src/device/usbd.c index 504cdf77b..d795e4f9a 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -66,7 +66,10 @@ typedef struct { uint8_t config_num; // map interface number to driver (0xff is invalid) - uint8_t itf2drv[16]; + uint8_t itf2drv[16]; + + // map endpoint to driver ( 0xff is invalid ) + uint8_t ep2drv[2][8]; }usbd_device_t; CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN uint8_t _usbd_ctrl_buf[CFG_TUD_CTRL_BUFSIZE]; @@ -100,18 +103,6 @@ static usbd_class_driver_t const usbd_class_drivers[] = }, #endif - #if DEVICE_CLASS_HID - { - .class_code = TUSB_CLASS_HID, - .init = hidd_init, - .open = hidd_open, - .control_req_st = hidd_control_request_st, - .xfer_cb = hidd_xfer_cb, - .sof = NULL, - .reset = hidd_reset - }, - #endif - #if CFG_TUD_MSC { .class_code = TUSB_CLASS_MSC, @@ -124,6 +115,19 @@ static usbd_class_driver_t const usbd_class_drivers[] = }, #endif + + #if DEVICE_CLASS_HID + { + .class_code = TUSB_CLASS_HID, + .init = hidd_init, + .open = hidd_open, + .control_req_st = hidd_control_request_st, + .xfer_cb = hidd_xfer_cb, + .sof = NULL, + .reset = hidd_reset + }, + #endif + #if CFG_TUD_CUSTOM_CLASS { .class_code = TUSB_CLASS_VENDOR_SPECIFIC, @@ -191,6 +195,7 @@ static osal_semaphore_def_t _usbd_sem_def; //--------------------------------------------------------------------+ // INTERNAL FUNCTION //--------------------------------------------------------------------+ +static void mark_interface_endpoint(uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id); static tusb_error_t proc_set_config_req(uint8_t rhport, uint8_t config_number); static uint16_t get_descriptor(uint8_t rhport, tusb_control_request_t const * const p_request, uint8_t const ** pp_buffer); @@ -300,6 +305,7 @@ static void usbd_reset(uint8_t rhport) { varclr_(&_usbd_dev); memset(_usbd_dev.itf2drv, 0xff, sizeof(_usbd_dev.itf2drv)); // invalid mapping + memset(_usbd_dev.ep2drv , 0xff, sizeof(_usbd_dev.ep2drv )); // invalid mapping for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++) { @@ -395,6 +401,7 @@ static tusb_error_t proc_control_request_st(uint8_t rhport, tusb_control_request OSAL_SUBTASK_END } +// Process Set Configure Request // TODO Host (windows) can get HID report descriptor before set configured // may need to open interface before set configured static tusb_error_t proc_set_config_req(uint8_t rhport, uint8_t config_number) @@ -418,33 +425,35 @@ static tusb_error_t proc_set_config_req(uint8_t rhport, uint8_t config_number) while( p_desc < desc_cfg + cfg_len ) { - if ( TUSB_DESC_INTERFACE_ASSOCIATION == p_desc[DESCRIPTOR_OFFSET_TYPE]) + if ( TUSB_DESC_INTERFACE_ASSOCIATION == descriptor_type(p_desc) ) { - p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // ignore Interface Association + p_desc = descriptor_next(p_desc); // ignore Interface Association }else { - TU_ASSERT( TUSB_DESC_INTERFACE == p_desc[DESCRIPTOR_OFFSET_TYPE], TUSB_ERROR_NOT_SUPPORTED_YET ); + TU_ASSERT( TUSB_DESC_INTERFACE == descriptor_type(p_desc), TUSB_ERROR_NOT_SUPPORTED_YET ); tusb_desc_interface_t* p_desc_itf = (tusb_desc_interface_t*) p_desc; uint8_t const class_code = p_desc_itf->bInterfaceClass; // Check if class is supported - uint8_t drid; - for (drid = 0; drid < USBD_CLASS_DRIVER_COUNT; drid++) + uint8_t drv_id; + for (drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++) { - if ( usbd_class_drivers[drid].class_code == class_code ) break; + if ( usbd_class_drivers[drv_id].class_code == class_code ) break; } - TU_ASSERT( drid < USBD_CLASS_DRIVER_COUNT, TUSB_ERROR_NOT_SUPPORTED_YET ); + TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT, TUSB_ERROR_NOT_SUPPORTED_YET ); // Interface number must not be used TU_ASSERT( 0xff == _usbd_dev.itf2drv[p_desc_itf->bInterfaceNumber], TUSB_ERROR_FAILED); - _usbd_dev.itf2drv[p_desc_itf->bInterfaceNumber] = drid; + _usbd_dev.itf2drv[p_desc_itf->bInterfaceNumber] = drv_id; - uint16_t length=0; - TU_ASSERT_ERR( usbd_class_drivers[drid].open( rhport, p_desc_itf, &length ) ); + uint16_t len=0; + TU_ASSERT_ERR( usbd_class_drivers[drv_id].open( rhport, p_desc_itf, &len ) ); + TU_ASSERT( len >= sizeof(tusb_desc_interface_t), TUSB_ERROR_FAILED ); - TU_ASSERT( length >= sizeof(tusb_desc_interface_t), TUSB_ERROR_FAILED ); - p_desc += length; + mark_interface_endpoint(p_desc, len, drv_id); + + p_desc += len; // next interface } } @@ -454,6 +463,7 @@ static tusb_error_t proc_set_config_req(uint8_t rhport, uint8_t config_number) return TUSB_ERROR_NONE; } +// return len of descriptor and change pointer to descriptor's buffer static uint16_t get_descriptor(uint8_t rhport, tusb_control_request_t const * const p_request, uint8_t const ** pp_buffer) { (void) rhport; @@ -514,6 +524,25 @@ static uint16_t get_descriptor(uint8_t rhport, tusb_control_request_t const * co return len; } +// Helper marking endpoint of interface belongs to class driver +static void mark_interface_endpoint(uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id) +{ + uint16_t len = 0; + + while( len < desc_len ) + { + if ( TUSB_DESC_ENDPOINT == descriptor_type(p_desc) ) + { + uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress; + + _usbd_dev.ep2drv[ edpt_dir(ep_addr) ][ edpt_number(ep_addr) ] = driver_id; + } + + len += descriptor_len(p_desc); + p_desc = descriptor_next(p_desc); + } +} + //--------------------------------------------------------------------+ // USBD-DCD Callback API //--------------------------------------------------------------------+ diff --git a/src/host/usbh.c b/src/host/usbh.c index a67bd8d8c..6d1cd37ad 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -572,9 +572,9 @@ tusb_error_t enumeration_body_subtask(void) while( p_desc < enum_data_buffer + ((tusb_desc_configuration_t*)enum_data_buffer)->wTotalLength ) { // skip until we see interface descriptor - if ( TUSB_DESC_INTERFACE != p_desc[DESCRIPTOR_OFFSET_TYPE] ) + if ( TUSB_DESC_INTERFACE != p_desc[DESC_OFFSET_TYPE] ) { - p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip the descriptor, increase by the descriptor's length + p_desc += p_desc[DESC_OFFSET_LEN]; // skip the descriptor, increase by the descriptor's length }else { static uint8_t class_index; // has to be static as it is used to call class's open_subtask @@ -600,11 +600,11 @@ tusb_error_t enumeration_body_subtask(void) p_desc += length; }else // Interface open failed, for example a subclass is not supported { - p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop + p_desc += p_desc[DESC_OFFSET_LEN]; // skip this interface, the rest will be skipped by the above loop } } else // unsupported class (not enable or yet implemented) { - p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop + p_desc += p_desc[DESC_OFFSET_LEN]; // skip this interface, the rest will be skipped by the above loop } } }