add ep2drv, rename descriptor offset

This commit is contained in:
hathach 2018-07-13 17:48:26 +07:00
parent cd5b5d3a53
commit 1efb552bfd
8 changed files with 85 additions and 51 deletions

View File

@ -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); (*p_length) = sizeof(tusb_desc_interface_t);
// Communication Functional Descriptors // 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); 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 { // notification endpoint if any
TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), TUSB_ERROR_DCD_OPEN_PIPE_FAILED); 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_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); p_desc = descriptor_next(p_desc);
} }
//------------- Data Interface (if any) -------------// //------------- 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) ) (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
{ {
// p_cdc->itf_num = // p_cdc->itf_num =
p_cdc->ep_count += ((tusb_desc_interface_t const *) p_desc)->bNumEndpoints; p_cdc->ep_count += ((tusb_desc_interface_t const *) p_desc)->bNumEndpoints;
// next to endpoint descritpor // next to endpoint descritpor
(*p_length) += p_desc[DESCRIPTOR_OFFSET_LENGTH]; (*p_length) += p_desc[DESC_OFFSET_LEN];
p_desc = descriptor_next(p_desc); p_desc = descriptor_next(p_desc);
// Open endpoint pair with usbd helper // Open endpoint pair with usbd helper

View File

@ -167,32 +167,32 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_
//------------- Communication Interface -------------// //------------- Communication Interface -------------//
(*p_length) = sizeof(tusb_desc_interface_t); (*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 { // Communication Functional Descriptors
if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) ) if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) )
{ // save ACM bmCapabilities { // save ACM bmCapabilities
p_cdc->acm_capability = ((cdc_desc_func_acm_t const *) p_desc)->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); 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 { // notification endpoint if any
p_cdc->pipe_notification = hcd_pipe_open(dev_addr, (tusb_desc_endpoint_t const *) p_desc, TUSB_CLASS_CDC); 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); p_desc = descriptor_next(p_desc);
TU_ASSERT(pipehandle_is_valid(p_cdc->pipe_notification), TUSB_ERROR_HCD_OPEN_PIPE_FAILED); TU_ASSERT(pipehandle_is_valid(p_cdc->pipe_notification), TUSB_ERROR_HCD_OPEN_PIPE_FAILED);
} }
//------------- Data Interface (if any) -------------// //------------- 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) ) (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); p_desc = descriptor_next(p_desc);
// data endpoints expected to be in pairs // 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); (*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 ); 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 ); p_desc = descriptor_next( p_desc );
} }
} }

View File

@ -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; uint8_t const *p_desc = (uint8_t const *) p_interface_desc;
//------------- HID descriptor -------------// //------------- 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; 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); TU_ASSERT(HID_DESC_TYPE_HID == p_desc_hid->bDescriptorType, TUSB_ERROR_HIDD_DESCRIPTOR_INTERFACE);
//------------- Endpoint Descriptor -------------// //------------- 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; 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); TU_ASSERT(TUSB_DESC_ENDPOINT == p_desc_endpoint->bDescriptorType, TUSB_ERROR_HIDD_DESCRIPTOR_INTERFACE);

View File

@ -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; uint8_t const *p_desc = (uint8_t const *) p_interface_desc;
//------------- HID descriptor -------------// //------------- 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; 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); TU_ASSERT(HID_DESC_TYPE_HID == p_desc_hid->bDescriptorType, TUSB_ERROR_INVALID_PARA);
//------------- Endpoint Descriptor -------------// //------------- 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; 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); TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint_desc->bDescriptorType, TUSB_ERROR_INVALID_PARA);

View File

@ -144,12 +144,17 @@
static inline uint8_t const * descriptor_next(uint8_t const p_desc[]) 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 -------------// //------------- Conversion -------------//

View File

@ -203,8 +203,8 @@ typedef enum
}tusb_event_t; }tusb_event_t;
enum { enum {
DESCRIPTOR_OFFSET_LENGTH = 0, DESC_OFFSET_LEN = 0,
DESCRIPTOR_OFFSET_TYPE = 1 DESC_OFFSET_TYPE = 1
}; };
enum { enum {

View File

@ -67,6 +67,9 @@ typedef struct {
// map interface number to driver (0xff is invalid) // 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; }usbd_device_t;
CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN uint8_t _usbd_ctrl_buf[CFG_TUD_CTRL_BUFSIZE]; 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 #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 #if CFG_TUD_MSC
{ {
.class_code = TUSB_CLASS_MSC, .class_code = TUSB_CLASS_MSC,
@ -124,6 +115,19 @@ static usbd_class_driver_t const usbd_class_drivers[] =
}, },
#endif #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 #if CFG_TUD_CUSTOM_CLASS
{ {
.class_code = TUSB_CLASS_VENDOR_SPECIFIC, .class_code = TUSB_CLASS_VENDOR_SPECIFIC,
@ -191,6 +195,7 @@ static osal_semaphore_def_t _usbd_sem_def;
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// INTERNAL FUNCTION // 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 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); 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); varclr_(&_usbd_dev);
memset(_usbd_dev.itf2drv, 0xff, sizeof(_usbd_dev.itf2drv)); // invalid mapping 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++) 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 OSAL_SUBTASK_END
} }
// Process Set Configure Request
// TODO Host (windows) can get HID report descriptor before set configured // TODO Host (windows) can get HID report descriptor before set configured
// may need to open interface 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) 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 ) 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 }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; tusb_desc_interface_t* p_desc_itf = (tusb_desc_interface_t*) p_desc;
uint8_t const class_code = p_desc_itf->bInterfaceClass; uint8_t const class_code = p_desc_itf->bInterfaceClass;
// Check if class is supported // Check if class is supported
uint8_t drid; uint8_t drv_id;
for (drid = 0; drid < USBD_CLASS_DRIVER_COUNT; drid++) 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 // Interface number must not be used
TU_ASSERT( 0xff == _usbd_dev.itf2drv[p_desc_itf->bInterfaceNumber], TUSB_ERROR_FAILED); 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; uint16_t len=0;
TU_ASSERT_ERR( usbd_class_drivers[drid].open( rhport, p_desc_itf, &length ) ); 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 ); mark_interface_endpoint(p_desc, len, drv_id);
p_desc += length;
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 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) static uint16_t get_descriptor(uint8_t rhport, tusb_control_request_t const * const p_request, uint8_t const ** pp_buffer)
{ {
(void) rhport; (void) rhport;
@ -514,6 +524,25 @@ static uint16_t get_descriptor(uint8_t rhport, tusb_control_request_t const * co
return len; 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 // USBD-DCD Callback API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+

View File

@ -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 ) while( p_desc < enum_data_buffer + ((tusb_desc_configuration_t*)enum_data_buffer)->wTotalLength )
{ {
// skip until we see interface descriptor // 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 }else
{ {
static uint8_t class_index; // has to be static as it is used to call class's open_subtask 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; p_desc += length;
}else // Interface open failed, for example a subclass is not supported }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) } 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
} }
} }
} }