uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
- uint8_t FoundEndpoints = 0;
+
+ USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
+ USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
+ USB_Descriptor_Endpoint_t* NotificationEndpoint = NULL;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
return ControlError;
}
- /* Get the CDC control interface from the configuration descriptor */
+ /* Get the first CDC control interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
- return NoCDCInterfaceFound;
+ return NoCompatibleInterfaceFound;
}
- /* Get the IN and OUT data and IN notification endpoints for the CDC interface */
- while (FoundEndpoints != ((1 << CDC_NOTIFICATIONPIPE) | (1 << CDC_DATAPIPE_IN) | (1 << CDC_DATAPIPE_OUT)))
+ while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint))
{
- /* Fetch the next bulk or interrupt endpoint from the current CDC interface */
+ /* Get the next CDC interface's endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextCDCDataInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
- /* Check to see if the control interface's notification pipe has been found, if so search for the data interface */
- if (FoundEndpoints & (1 << CDC_NOTIFICATIONPIPE))
+ /* Check if we have already found the control interface's notification endpoint or not */
+ if (NotificationEndpoint)
{
- /* Get the next CDC data interface from the configuration descriptor (CDC class has two CDC interfaces) */
- if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
- DComp_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
+ /* Get the next CDC data interface from the configuration descriptor */
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
+ DComp_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
- return NoCDCInterfaceFound;
- }
+ return NoCompatibleInterfaceFound;
+ }
+
+ /* Clear any found endpoints */
+ DataINEndpoint = NULL;
+ DataOUTEndpoint = NULL;
}
else
{
- /* Clear the found endpoints mask, since any already processed endpoints aren't in the CDC interface we need */
- FoundEndpoints = 0;
-
- /* Disable any already configured pipes from the invalid CDC interfaces */
- Pipe_SelectPipe(CDC_NOTIFICATIONPIPE);
- Pipe_DisablePipe();
- Pipe_SelectPipe(CDC_DATAPIPE_IN);
- Pipe_DisablePipe();
- Pipe_SelectPipe(CDC_DATAPIPE_OUT);
- Pipe_DisablePipe();
-
- /* Get the next CDC control interface from the configuration descriptor (CDC class has two CDC interfaces) */
+ /* Get the next CDC control interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
- DComp_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
+ DComp_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
- return NoCDCInterfaceFound;
+ return NoCompatibleInterfaceFound;
}
- }
- /* Fetch the next bulk or interrupt endpoint from the current CDC interface */
- if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
- DComp_NextCDCDataInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
- {
- /* Descriptor not found, error out */
- return NoEndpointFound;
+ /* Clear any found endpoints */
+ NotificationEndpoint = NULL;
}
}
+ /* Retrieve the endpoint address from the endpoint descriptor */
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
- /* Check if the found endpoint is a interrupt or bulk type descriptor */
- if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
+ /* If the endpoint is a IN type endpoint */
+ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
- /* If the endpoint is a IN type interrupt endpoint */
- if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
- {
- /* Configure the notification pipe */
- Pipe_ConfigurePipe(CDC_NOTIFICATIONPIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
- EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
-
- Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
-
- /* Set the flag indicating that the notification pipe has been found */
- FoundEndpoints |= (1 << CDC_NOTIFICATIONPIPE);
- }
+ /* Check if the found endpoint is a interrupt or bulk type descriptor */
+ if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
+ NotificationEndpoint = EndpointData;
+ else
+ DataINEndpoint = EndpointData;
}
else
{
- /* Check if the endpoint is a bulk IN or bulk OUT endpoint */
- if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
- {
- /* Configure the data IN pipe */
- Pipe_ConfigurePipe(CDC_DATAPIPE_IN, EP_TYPE_BULK, PIPE_TOKEN_IN,
- EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
-
- /* Set the flag indicating that the data IN pipe has been found */
- FoundEndpoints |= (1 << CDC_DATAPIPE_IN);
- }
- else
- {
- /* Configure the data OUT pipe */
- Pipe_ConfigurePipe(CDC_DATAPIPE_OUT, EP_TYPE_BULK, PIPE_TOKEN_OUT,
- EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
-
- /* Set the flag indicating that the data OUT pipe has been found */
- FoundEndpoints |= (1 << CDC_DATAPIPE_OUT);
- }
+ DataOUTEndpoint = EndpointData;
}
}
+
+ /* Configure the CDC data IN pipe */
+ Pipe_ConfigurePipe(CDC_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
+ DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE);
+
+ /* Configure the CDC data OUT pipe */
+ Pipe_ConfigurePipe(CDC_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
+ DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, PIPE_BANK_SINGLE);
+
+ /* Configure the CDC notification pipe */
+ Pipe_ConfigurePipe(CDC_NOTIFICATION_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
+ NotificationEndpoint->EndpointAddress, NotificationEndpoint->EndpointSize, PIPE_BANK_SINGLE);
+ Pipe_SetInterruptPeriod(NotificationEndpoint->PollingIntervalMS);
/* Valid data found, return success */
return SuccessfulConfigRead;