/** * Returns configuration descriptor list. * \param pDriver Pointer to a USBDDriver instance. * \param cfgNum Reserved. */ USBConfigurationDescriptor *USBDDriver_GetCfgDescriptors( USBDDriver *pDriver, uint8_t cfgNum) { USBDDriverDescriptors *pDescList = (USBDDriverDescriptors *)pDriver->pDescriptors; USBConfigurationDescriptor *pCfg; if (USBD_HAL_IsHighSpeed() && pDescList->pHsConfiguration) pCfg = (USBConfigurationDescriptor *)pDescList->pHsConfiguration; else pCfg = (USBConfigurationDescriptor *)pDescList->pFsConfiguration; return pCfg; }
/** * Configures the device by setting it into the Configured state and * initializing all endpoints. * \param pDriver Pointer to a USBDDriver instance. * \param cfgnum Configuration number to set. */ static void SetConfiguration(USBDDriver *pDriver, uint8_t cfgnum) { USBEndpointDescriptor *pEndpoints[17]; const USBConfigurationDescriptor *pConfiguration; /* Use different descriptor depending on device speed */ if ( USBD_HAL_IsHighSpeed() && pDriver->pDescriptors->pHsConfiguration) { pConfiguration = pDriver->pDescriptors->pHsConfiguration; } else { pConfiguration = pDriver->pDescriptors->pFsConfiguration; } /* Set & save the desired configuration */ USBD_SetConfiguration(cfgnum); pDriver->cfgnum = cfgnum; pDriver->isRemoteWakeUpEnabled = ((pConfiguration->bmAttributes & 0x20) > 0); /* If the configuration is not 0, configure endpoints */ if (cfgnum != 0) { /* Parse configuration to get endpoint descriptors */ USBConfigurationDescriptor_Parse(pConfiguration, 0, pEndpoints, 0); /* Configure endpoints */ int i = 0; while (pEndpoints[i] != 0) { USBD_ConfigureEndpoint(pEndpoints[i]); i++; } } /* Should be done before send the ZLP */ if (NULL != USBDDriverCallbacks_ConfigurationChanged) USBDDriverCallbacks_ConfigurationChanged(cfgnum); /* Acknowledge the request */ USBD_Write(0, /* Endpoint #0 */ 0, /* No data buffer */ 0, /* No data buffer */ (TransferCallback) 0, (void *) 0); }
/** * Invoked whenever the active configuration of device is changed by the * host. * \param cfgnum Configuration number. */ void AUDDSpeakerDriver_ConfigurationChangeHandler(uint8_t cfgnum) { AUDDSpeakerDriver *pAudd = &auddSpeakerDriver; AUDDSpeakerPhone *pAudf = &pAudd->fun; const USBDDriverDescriptors *pDescriptors = pAudf->pUsbd->pDescriptors; USBConfigurationDescriptor *pDesc; if (cfgnum > 0) { /* Parse endpoints for data & notification */ if (USBD_HAL_IsHighSpeed() && pDescriptors->pHsConfiguration) pDesc = (USBConfigurationDescriptor*)pDescriptors->pHsConfiguration; else pDesc = (USBConfigurationDescriptor*)pDescriptors->pFsConfiguration; AUDDSpeakerPhone_ParseInterfaces(pAudf, (USBGenericDescriptor*)pDesc, pDesc->wTotalLength); } }
/** * Handles configureation changed event. * \param cfgnum New configuration number */ void HIDDTransferDriver_ConfigurationChangedHandler(uint8_t cfgnum) { const USBDDriverDescriptors * pDescriptors = USBD_GetDriver()->pDescriptors; HIDDTransferDriver * pDrv = &hiddTransferDriver; HIDDFunction * pHidd = &pDrv->hidFunction; USBConfigurationDescriptor *pDesc; if (cfgnum > 0) { /* Parse endpoints for reports */ if (USBD_HAL_IsHighSpeed() && pDescriptors->pHsConfiguration) pDesc = (USBConfigurationDescriptor*)pDescriptors->pHsConfiguration; else pDesc = (USBConfigurationDescriptor*)pDescriptors->pFsConfiguration; HIDDFunction_ParseInterface(pHidd, (USBGenericDescriptor*)pDesc, pDesc->wTotalLength); /* Start polling for Output Reports */ HIDDFunction_StartPollingOutputs(pHidd); } }
/** * Indicates if the device is running in high or full-speed. Always returns 0 * since UDP does not support high-speed mode. */ uint8_t USBD_IsHighSpeed(void) { return USBD_HAL_IsHighSpeed(); }
/** * Sends the requested USB descriptor to the host if available, or STALLs the * request. * \param pDriver Pointer to a USBDDriver instance. * \param type Type of the requested descriptor * \param index Index of the requested descriptor. * \param length Maximum number of bytes to return. */ static void GetDescriptor( const USBDDriver *pDriver, uint8_t type, uint8_t indexRDesc, uint32_t length) { const USBDeviceDescriptor *pDevice; const USBConfigurationDescriptor *pConfiguration; const USBDeviceQualifierDescriptor *pQualifier; const USBConfigurationDescriptor *pOtherSpeed; const USBGenericDescriptor **pStrings = (const USBGenericDescriptor **) pDriver->pDescriptors->pStrings; const USBGenericDescriptor *pString; uint8_t numStrings = pDriver->pDescriptors->numStrings; uint8_t terminateWithNull = 0; /* Use different set of descriptors depending on device speed */ /* By default, we uses full speed values */ pDevice = pDriver->pDescriptors->pFsDevice; pConfiguration = pDriver->pDescriptors->pFsConfiguration; /* HS, we try HS values */ if (USBD_HAL_IsHighSpeed()) { TRACE_DEBUG_WP("HS "); if (pDriver->pDescriptors->pHsDevice) pDevice = pDriver->pDescriptors->pHsDevice; if (pDriver->pDescriptors->pHsConfiguration) pConfiguration = pDriver->pDescriptors->pHsConfiguration; pQualifier = pDriver->pDescriptors->pHsQualifier; pOtherSpeed = pDriver->pDescriptors->pHsOtherSpeed; } else { TRACE_DEBUG_WP("FS "); pQualifier = pDriver->pDescriptors->pFsQualifier; pOtherSpeed = pDriver->pDescriptors->pFsOtherSpeed; } /* Check the descriptor type */ switch (type) { case USBGenericDescriptor_DEVICE: TRACE_INFO_WP("Dev "); /* Adjust length and send descriptor */ if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice)) { length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice); } USBD_Write(0, pDevice, length, 0, 0); break; case USBGenericDescriptor_CONFIGURATION: TRACE_INFO_WP("Cfg "); /* Adjust length and send descriptor */ if (length > USBConfigurationDescriptor_GetTotalLength(pConfiguration)) { length = USBConfigurationDescriptor_GetTotalLength(pConfiguration); terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); } USBD_Write(0, pConfiguration, length, terminateWithNull ? TerminateCtrlInWithNull : 0, 0); break; case USBGenericDescriptor_DEVICEQUALIFIER: TRACE_INFO_WP("Qua "); /* Check if descriptor exists */ if (!pQualifier) { USBD_Stall(0); } else { /* Adjust length and send descriptor */ if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pQualifier)) { length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pQualifier); } USBD_Write(0, pQualifier, length, 0, 0); } break; case USBGenericDescriptor_OTHERSPEEDCONFIGURATION: TRACE_INFO_WP("OSC "); /* Check if descriptor exists */ if (!pOtherSpeed) { USBD_Stall(0); } else { /* Adjust length and send descriptor */ if (length > USBConfigurationDescriptor_GetTotalLength(pOtherSpeed)) { length = USBConfigurationDescriptor_GetTotalLength(pOtherSpeed); terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); } USBD_Write(0, pOtherSpeed, length, terminateWithNull ? TerminateCtrlInWithNull : 0, 0); } break; case USBGenericDescriptor_STRING: TRACE_INFO_WP("Str%d ", indexRDesc); /* Check if descriptor exists */ if (indexRDesc >= numStrings) { USBD_Stall(0); } else { pString = pStrings[indexRDesc]; /* Adjust length and send descriptor */ if (length > USBGenericDescriptor_GetLength(pString)) { length = USBGenericDescriptor_GetLength(pString); terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); } USBD_Write(0, pString, length, terminateWithNull ? TerminateCtrlInWithNull : 0, 0); } break; default: TRACE_WARNING( "USBDDriver_GetDescriptor: Unknown descriptor type (%d)\n\r", type); USBD_Stall(0); } }