/** * @brief USBH_ParseCfgDesc * This function Parses the configuration descriptor * @param cfg_desc: Configuration Descriptor address * @param buf: Buffer where the source descriptor is available * @param length: Length of the descriptor * @retval None */ static void USBH_ParseCfgDesc (USBH_CfgDescTypeDef* cfg_desc, uint8_t *buf, uint16_t length) { USBH_InterfaceDescTypeDef *pif ; USBH_EpDescTypeDef *pep; USBH_DescHeader_t *pdesc = (USBH_DescHeader_t *)buf; uint16_t ptr; int8_t if_ix = 0; int8_t ep_ix = 0; pdesc = (USBH_DescHeader_t *)buf; /* Parse configuration descriptor */ cfg_desc->bLength = *(uint8_t *) (buf + 0); cfg_desc->bDescriptorType = *(uint8_t *) (buf + 1); cfg_desc->wTotalLength = LE16 (buf + 2); cfg_desc->bNumInterfaces = *(uint8_t *) (buf + 4); cfg_desc->bConfigurationValue = *(uint8_t *) (buf + 5); cfg_desc->iConfiguration = *(uint8_t *) (buf + 6); cfg_desc->bmAttributes = *(uint8_t *) (buf + 7); cfg_desc->bMaxPower = *(uint8_t *) (buf + 8); if (length > USB_CONFIGURATION_DESC_SIZE) { ptr = USB_LEN_CFG_DESC; pif = (USBH_InterfaceDescTypeDef *)0; while ((if_ix < USBH_MAX_NUM_INTERFACES ) && (ptr < cfg_desc->wTotalLength)) { pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr); if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE) { pif = &cfg_desc->Itf_Desc[if_ix]; USBH_ParseInterfaceDesc (pif, (uint8_t *)pdesc); ep_ix = 0; pep = (USBH_EpDescTypeDef *)0; while ((ep_ix < pif->bNumEndpoints) && (ptr < cfg_desc->wTotalLength)) { pdesc = USBH_GetNextDesc((void* )pdesc, &ptr); if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) { pep = &cfg_desc->Itf_Desc[if_ix].Ep_Desc[ep_ix]; USBH_ParseEPDesc (pep, (uint8_t *)pdesc); ep_ix++; } } if_ix++; } } } }
//-------------------------------------------------------------- static void USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc, USBH_InterfaceDesc_TypeDef* itf_desc, USBH_EpDesc_TypeDef ep_desc[][USBH_MAX_NUM_ENDPOINTS], uint8_t *buf, uint16_t length) { USBH_InterfaceDesc_TypeDef *pif ; USBH_InterfaceDesc_TypeDef temp_pif ; USBH_EpDesc_TypeDef *pep; USBH_DescHeader_t *pdesc = (USBH_DescHeader_t *)buf; uint16_t ptr; int8_t if_ix = 0; int8_t ep_ix = 0; static uint16_t prev_ep_size = 0; static uint8_t prev_itf = 0; pdesc = (USBH_DescHeader_t *)buf; /* Parse configuration descriptor */ cfg_desc->bLength = *(uint8_t *) (buf + 0); cfg_desc->bDescriptorType = *(uint8_t *) (buf + 1); cfg_desc->wTotalLength = LE16 (buf + 2); cfg_desc->bNumInterfaces = *(uint8_t *) (buf + 4); cfg_desc->bConfigurationValue = *(uint8_t *) (buf + 5); cfg_desc->iConfiguration = *(uint8_t *) (buf + 6); cfg_desc->bmAttributes = *(uint8_t *) (buf + 7); cfg_desc->bMaxPower = *(uint8_t *) (buf + 8); if (length > USB_CONFIGURATION_DESC_SIZE) { ptr = USB_LEN_CFG_DESC; if ( cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES) { pif = (USBH_InterfaceDesc_TypeDef *)0; while (ptr < cfg_desc->wTotalLength ) { pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr); if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE) { if_ix = *(((uint8_t *)pdesc ) + 2); pif = &itf_desc[if_ix]; if((*((uint8_t *)pdesc + 3)) < 3) { USBH_ParseInterfaceDesc (&temp_pif, (uint8_t *)pdesc); ep_ix = 0; /* Parse Ep descriptors relative to the current interface */ if(temp_pif.bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) { while (ep_ix < temp_pif.bNumEndpoints) { pdesc = USBH_GetNextDesc((void* )pdesc, &ptr); if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) { pep = &ep_desc[if_ix][ep_ix]; if(prev_itf != if_ix) { prev_itf = if_ix; USBH_ParseInterfaceDesc (pif, (uint8_t *)&temp_pif); } else { if(prev_ep_size > LE16((uint8_t *)pdesc + 4)) { break; } else { USBH_ParseInterfaceDesc (pif, (uint8_t *)&temp_pif); } } USBH_ParseEPDesc (pep, (uint8_t *)pdesc); prev_ep_size = LE16((uint8_t *)pdesc + 4); ep_ix++; } } } } } } } prev_ep_size = 0; prev_itf = 0; } }
//-------------------------------------------------------------- static void USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc, USBH_InterfaceDesc_TypeDef* itf_desc, USBH_EpDesc_TypeDef* ep_desc, uint8_t *buf, uint16_t length) { USBH_InterfaceDesc_TypeDef *pif ; USBH_EpDesc_TypeDef *pep; USBH_DescHeader_t *pdesc = (USBH_DescHeader_t *)buf; uint16_t ptr; int8_t if_ix; int8_t ep_ix; pdesc = (USBH_DescHeader_t *)buf; /* Parse configuration descriptor */ cfg_desc->bLength = *(uint8_t *) (buf + 0); cfg_desc->bDescriptorType = *(uint8_t *) (buf + 1); cfg_desc->wTotalLength = LE16 (buf + 2); cfg_desc->bNumInterfaces = *(uint8_t *) (buf + 4); cfg_desc->bConfigurationValue = *(uint8_t *) (buf + 5); cfg_desc->iConfiguration = *(uint8_t *) (buf + 6); cfg_desc->bmAttributes = *(uint8_t *) (buf + 7); cfg_desc->bMaxPower = *(uint8_t *) (buf + 8); if (length > USB_CONFIGURATION_DESC_SIZE) { ptr = USB_LEN_CFG_DESC; if ( cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES) { if_ix = 0; pif = (USBH_InterfaceDesc_TypeDef *)0; /* Parse Interface descriptor relative to the current configuration */ if(cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES) { while (if_ix < cfg_desc->bNumInterfaces) { pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr); if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE) { pif = &itf_desc[if_ix]; USBH_ParseInterfaceDesc (pif, (uint8_t *)pdesc); ep_ix = 0; /* Parse Ep descriptors relative to the current interface */ if(pif->bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) { while (ep_ix < pif->bNumEndpoints) { pdesc = USBH_GetNextDesc((void* )pdesc, &ptr); if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) { pep = &ep_desc[ep_ix]; USBH_ParseEPDesc (pep, (uint8_t *)pdesc); ep_ix++; } else { ptr += pdesc->bLength; } } } if_ix++; } else { ptr += pdesc->bLength; } } } } } }