Fix low level host mode demos not correctly fetching the next endpoint when an invalid interface is discarded.
Update the pipe configuration routines in the host mode class drivers so that they use the same new code to enumerate compatible devices to increase reliability. Add support to the host mode class drivers for non-sequential (but non-overlapping with other interface) pipe numbers.
This commit is contained in:
parent
158afe9109
commit
7166c7ba3e
37 changed files with 563 additions and 366 deletions
|
@ -38,68 +38,91 @@
|
|||
|
||||
uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
|
||||
uint16_t ConfigDescriptorSize,
|
||||
void* DeviceConfigDescriptor)
|
||||
void* ConfigDescriptorData)
|
||||
{
|
||||
uint8_t FoundEndpoints = 0;
|
||||
|
||||
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
|
||||
USB_Descriptor_Endpoint_t* EventsEndpoint = NULL;
|
||||
|
||||
memset(&SIInterfaceInfo->State, 0x00, sizeof(SIInterfaceInfo->State));
|
||||
|
||||
if (DESCRIPTOR_TYPE(DeviceConfigDescriptor) != DTYPE_Configuration)
|
||||
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
|
||||
return SI_ENUMERROR_InvalidConfigDescriptor;
|
||||
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
|
||||
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_SI_Host_NextSIInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return SI_ENUMERROR_NoSIInterfaceFound;
|
||||
return SI_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
while (FoundEndpoints != (SI_FOUND_EVENTS_IN | SI_FOUND_DATAPIPE_IN | SI_FOUND_DATAPIPE_OUT))
|
||||
SIInterfaceInfo->State.InterfaceNumber = DESCRIPTOR_PCAST(ConfigDescriptorData,
|
||||
USB_Descriptor_Interface_t)->InterfaceNumber;
|
||||
|
||||
while (!(DataINEndpoint) || !(DataOUTEndpoint))
|
||||
{
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_SI_Host_NextSIInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
return SI_ENUMERROR_EndpointsNotFound;
|
||||
}
|
||||
|
||||
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Endpoint_t);
|
||||
DataINEndpoint = NULL;
|
||||
DataOUTEndpoint = NULL;
|
||||
EventsEndpoint = NULL;
|
||||
|
||||
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
|
||||
{
|
||||
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
|
||||
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
|
||||
DCOMP_SI_Host_NextSIInterface) != DESCRIPTOR_SEARCH_COMP_Found)
|
||||
{
|
||||
Pipe_ConfigurePipe(SIInterfaceInfo->Config.EventsPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize,
|
||||
SIInterfaceInfo->Config.EventsPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
|
||||
SIInterfaceInfo->State.EventsPipeSize = EndpointData->EndpointSize;
|
||||
|
||||
Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
|
||||
|
||||
FoundEndpoints |= SI_FOUND_EVENTS_IN;
|
||||
return SI_ENUMERROR_NoCompatibleInterfaceFound;
|
||||
}
|
||||
|
||||
SIInterfaceInfo->State.InterfaceNumber = DESCRIPTOR_PCAST(ConfigDescriptorData,
|
||||
USB_Descriptor_Interface_t)->InterfaceNumber;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
|
||||
|
||||
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
|
||||
{
|
||||
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
|
||||
EventsEndpoint = EndpointData;
|
||||
else
|
||||
DataINEndpoint = EndpointData;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
|
||||
{
|
||||
Pipe_ConfigurePipe(SIInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize,
|
||||
SIInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
|
||||
SIInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
|
||||
|
||||
FoundEndpoints |= SI_FOUND_DATAPIPE_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_ConfigurePipe(SIInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize,
|
||||
SIInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
|
||||
SIInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
|
||||
|
||||
FoundEndpoints |= SI_FOUND_DATAPIPE_OUT;
|
||||
}
|
||||
DataOUTEndpoint = EndpointData;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
|
||||
{
|
||||
if (PipeNum == SIInterfaceInfo->Config.DataINPipeNumber)
|
||||
{
|
||||
Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN,
|
||||
DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize,
|
||||
SIInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
|
||||
|
||||
SIInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
|
||||
}
|
||||
else if (PipeNum == SIInterfaceInfo->Config.DataOUTPipeNumber)
|
||||
{
|
||||
Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT,
|
||||
DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize,
|
||||
SIInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
|
||||
|
||||
SIInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
|
||||
}
|
||||
else if (PipeNum == SIInterfaceInfo->Config.EventsPipeNumber)
|
||||
{
|
||||
Pipe_ConfigurePipe(PipeNum, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
|
||||
EventsEndpoint->EndpointAddress, EventsEndpoint->EndpointSize,
|
||||
SIInterfaceInfo->Config.EventsPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
|
||||
Pipe_SetInterruptPeriod(EventsEndpoint->PollingIntervalMS);
|
||||
|
||||
SIInterfaceInfo->State.EventsPipeSize = EventsEndpoint->EndpointSize;
|
||||
}
|
||||
}
|
||||
|
||||
SIInterfaceInfo->State.IsActive = true;
|
||||
return SI_ENUMERROR_NoError;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue