diff --git a/Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c b/Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c index 40bc98e2dda7bf1a9ad9526d1fa3eca72d1b045d..2de7b722b2a8b4f869e2dd8b28ba53e9b023a17d 100644 --- a/Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c @@ -96,6 +96,9 @@ uint8_t ProcessConfigurationDescriptor(void) /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ diff --git a/Demos/Host/LowLevel/JoystickHostWithParser/ConfigDescriptor.c b/Demos/Host/LowLevel/JoystickHostWithParser/ConfigDescriptor.c index dfca7b40796f42787cdcd96caa98702adbae1e96..1d82650431515899a9efdf8e25ab983d7ef65fc9 100644 --- a/Demos/Host/LowLevel/JoystickHostWithParser/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/JoystickHostWithParser/ConfigDescriptor.c @@ -87,6 +87,9 @@ uint8_t ProcessConfigurationDescriptor(void) /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ diff --git a/Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c b/Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c index dbdfac9c6af9eb4edcc9ac163c31fc4c045ec8bc..988579ce7f769ad29147cd2f38164edd5c1c137a 100644 --- a/Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c @@ -87,6 +87,9 @@ uint8_t ProcessConfigurationDescriptor(void) /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ diff --git a/Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c b/Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c index d397ca7adeb6dba78d1a41f32d2b944421929e1b..bf2c4e051a166398d850f0029e718cd6f645f17e 100644 --- a/Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c @@ -83,7 +83,7 @@ uint8_t ProcessConfigurationDescriptor(void) } /* Save the HID report size for later use */ - HIDReportSize = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_HID_t).HIDReportLength; + HIDReportSize = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_HID_t)->HIDReportLength; while (!(DataINEndpoint)) { @@ -108,7 +108,10 @@ uint8_t ProcessConfigurationDescriptor(void) } /* Save the HID report size for later use */ - HIDReportSize = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_HID_t).HIDReportLength; + HIDReportSize = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_HID_t)->HIDReportLength; + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ diff --git a/Demos/Host/LowLevel/MIDIHost/ConfigDescriptor.c b/Demos/Host/LowLevel/MIDIHost/ConfigDescriptor.c index 3ede4577849a6d402ab0ccca5c21dbf410aacd2a..7dda634cc3be2085b0977417bbd59ebe67629405 100644 --- a/Demos/Host/LowLevel/MIDIHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/MIDIHost/ConfigDescriptor.c @@ -92,6 +92,9 @@ uint8_t ProcessConfigurationDescriptor(void) /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ diff --git a/Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c b/Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c index 64565ac6df9334e1120f4ab6619fba7afad49aff..a91d61ac04d91c277531d8c025a508a8b8e17ac8 100644 --- a/Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c @@ -92,6 +92,9 @@ uint8_t ProcessConfigurationDescriptor(void) /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ diff --git a/Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c b/Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c index 02c4cd46d675f1af54f234534f939c49d303a966..4ea8aefe9664ce0a73fc241b0de55538b0ecaa9c 100644 --- a/Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c @@ -87,6 +87,9 @@ uint8_t ProcessConfigurationDescriptor(void) /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ diff --git a/Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c b/Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c index f285f5a02ed91dc119fa4f6a6de159f390b0bd41..c5afbe4763f0f999c498cd1bfedc3429ca23b9bf 100644 --- a/Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c @@ -83,7 +83,7 @@ uint8_t ProcessConfigurationDescriptor(void) } /* Save the HID report size for later use */ - HIDReportSize = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_HID_t).HIDReportLength; + HIDReportSize = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_HID_t)->HIDReportLength; while (!(DataINEndpoint)) { @@ -108,7 +108,10 @@ uint8_t ProcessConfigurationDescriptor(void) } /* Save the HID report size for later use */ - HIDReportSize = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_HID_t).HIDReportLength; + HIDReportSize = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_HID_t)->HIDReportLength; + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ diff --git a/Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c b/Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c index 0591aaca24493e3b68b6f368ad9f5c8cdf15fc23..b16ac668c9580a878b99928a4a12cdebd2077678 100644 --- a/Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c @@ -75,8 +75,8 @@ uint8_t ProcessConfigurationDescriptor(void) } /* Save Printer interface details for later use */ - PrinterInterfaceNumber = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_Interface_t).InterfaceNumber; - PrinterAltSetting = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_Interface_t).AlternateSetting; + PrinterInterfaceNumber = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t)->InterfaceNumber; + PrinterAltSetting = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t)->AlternateSetting; while (!(DataINEndpoint) || !(DataOUTEndpoint)) { @@ -97,8 +97,11 @@ uint8_t ProcessConfigurationDescriptor(void) } /* Save Printer interface details for later use */ - PrinterInterfaceNumber = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_Interface_t).InterfaceNumber; - PrinterAltSetting = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_Interface_t).AlternateSetting; + PrinterInterfaceNumber = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t)->InterfaceNumber; + PrinterAltSetting = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t)->AlternateSetting; + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ @@ -106,7 +109,7 @@ uint8_t ProcessConfigurationDescriptor(void) /* If the endpoint is a IN type endpoint */ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) - DataINEndpoint = EndpointData; + DataINEndpoint = EndpointData; else DataOUTEndpoint = EndpointData; } diff --git a/Demos/Host/LowLevel/RNDISEthernetHost/ConfigDescriptor.c b/Demos/Host/LowLevel/RNDISEthernetHost/ConfigDescriptor.c index 0db576f72e607b7aca0ac5ac41aaac9f73d94147..aa75dd1743c04807cc547899e5c1269b358e8696 100644 --- a/Demos/Host/LowLevel/RNDISEthernetHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/RNDISEthernetHost/ConfigDescriptor.c @@ -110,6 +110,9 @@ uint8_t ProcessConfigurationDescriptor(void) /* Clear any found endpoints */ NotificationEndpoint = NULL; } + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ diff --git a/Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c b/Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c index 583df3bcc37c8d700b99c57738d5e5acfc075e80..78bca7f949f3233078110554de5fcec19d569eaf 100644 --- a/Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c @@ -94,6 +94,9 @@ uint8_t ProcessConfigurationDescriptor(void) /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ diff --git a/Demos/Host/LowLevel/VirtualSerialHost/ConfigDescriptor.c b/Demos/Host/LowLevel/VirtualSerialHost/ConfigDescriptor.c index c35a606ccca7357ab69a99750df93ab575f98a38..a26fa5cceada36da445a809a3a239ef72459d9fd 100644 --- a/Demos/Host/LowLevel/VirtualSerialHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/VirtualSerialHost/ConfigDescriptor.c @@ -110,6 +110,9 @@ uint8_t ProcessConfigurationDescriptor(void) /* Clear any found endpoints */ NotificationEndpoint = NULL; } + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ diff --git a/LUFA/Drivers/USB/Class/Device/Audio.h b/LUFA/Drivers/USB/Class/Device/Audio.h index caf1fdc68b2021bcdc34e9e1c4827ea23131fed0..414f4526be7db5be8ba237c931bd80fa348f9417 100644 --- a/LUFA/Drivers/USB/Class/Device/Audio.h +++ b/LUFA/Drivers/USB/Class/Device/Audio.h @@ -116,6 +116,10 @@ * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the * given Audio interface is selected. * + * \note The endpoint index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or endpoint bank corruption will occur. Gaps in the allocated endpoint numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved endpoint indexes. + * * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. * * \return Boolean true if the endpoints were successfully configured, false otherwise. diff --git a/LUFA/Drivers/USB/Class/Device/CDC.h b/LUFA/Drivers/USB/Class/Device/CDC.h index 1b0b86810a17234167b2e24e56b33ed1787b954b..0e27d9d59aa292ce3bed2d9f6d158dfa21869ab3 100644 --- a/LUFA/Drivers/USB/Class/Device/CDC.h +++ b/LUFA/Drivers/USB/Class/Device/CDC.h @@ -151,6 +151,10 @@ * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing * the given CDC interface is selected. * + * \note The endpoint index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or endpoint bank corruption will occur. Gaps in the allocated endpoint numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved endpoint indexes. + * * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. * * \return Boolean true if the endpoints were successfully configured, false otherwise. diff --git a/LUFA/Drivers/USB/Class/Device/HID.h b/LUFA/Drivers/USB/Class/Device/HID.h index e90f15d1f7332d576f167fd36de80787a51e429d..097b12f294c8ce463da989de9d334f3b93b51e0e 100644 --- a/LUFA/Drivers/USB/Class/Device/HID.h +++ b/LUFA/Drivers/USB/Class/Device/HID.h @@ -128,6 +128,10 @@ * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration * containing the given HID interface is selected. * + * \note The endpoint index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or endpoint bank corruption will occur. Gaps in the allocated endpoint numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved endpoint indexes. + * * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. * * \return Boolean true if the endpoints were successfully configured, false otherwise. diff --git a/LUFA/Drivers/USB/Class/Device/MIDI.h b/LUFA/Drivers/USB/Class/Device/MIDI.h index e733bfecdc839cf646d2ff8b422159c2160e6114..cb8e2dee363361906e7287416dca1350b07198dd 100644 --- a/LUFA/Drivers/USB/Class/Device/MIDI.h +++ b/LUFA/Drivers/USB/Class/Device/MIDI.h @@ -106,6 +106,10 @@ * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration * containing the given MIDI interface is selected. * + * \note The endpoint index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or endpoint bank corruption will occur. Gaps in the allocated endpoint numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved endpoint indexes. + * * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. * * \return Boolean true if the endpoints were successfully configured, false otherwise. diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.h b/LUFA/Drivers/USB/Class/Device/MassStorage.h index 9e8cccb6f6ef5870bc37dc5743947c336feff383..39a806eee7e1463973341585ee1fa9ac821ca6a5 100644 --- a/LUFA/Drivers/USB/Class/Device/MassStorage.h +++ b/LUFA/Drivers/USB/Class/Device/MassStorage.h @@ -116,6 +116,10 @@ * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration * containing the given Mass Storage interface is selected. * + * \note The endpoint index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or endpoint bank corruption will occur. Gaps in the allocated endpoint numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved endpoint indexes. + * * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state. * * \return Boolean true if the endpoints were successfully configured, false otherwise. diff --git a/LUFA/Drivers/USB/Class/Device/RNDIS.h b/LUFA/Drivers/USB/Class/Device/RNDIS.h index 8af656322df0b6ff12295a47fb4d3331d101b715..64f967953b58faf495f84dfdc4b55b5f4f294700 100644 --- a/LUFA/Drivers/USB/Class/Device/RNDIS.h +++ b/LUFA/Drivers/USB/Class/Device/RNDIS.h @@ -124,6 +124,10 @@ * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration * containing the given HID interface is selected. * + * \note The endpoint index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or endpoint bank corruption will occur. Gaps in the allocated endpoint numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved endpoint indexes. + * * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state. * * \return Boolean true if the endpoints were successfully configured, false otherwise. diff --git a/LUFA/Drivers/USB/Class/Host/CDC.c b/LUFA/Drivers/USB/Class/Host/CDC.c index 5a87c77eed1698eb3e7de7a1d12fcd868ad97549..79c207ea85431ad15790f9e7f5605fe56b2ee638 100644 --- a/LUFA/Drivers/USB/Class/Host/CDC.c +++ b/LUFA/Drivers/USB/Class/Host/CDC.c @@ -40,103 +40,105 @@ uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo uint16_t ConfigDescriptorSize, void* ConfigDescriptorData) { - uint8_t FoundEndpoints = 0; + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + USB_Descriptor_Endpoint_t* NotificationEndpoint = NULL; memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State)); if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) return CDC_ENUMERROR_InvalidConfigDescriptor; - + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DCOMP_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) { - return CDC_ENUMERROR_NoCDCInterfaceFound; + return CDC_ENUMERROR_NoCompatibleInterfaceFound; } - CDCInterfaceInfo->State.ControlInterfaceNumber = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).InterfaceNumber; + CDCInterfaceInfo->State.ControlInterfaceNumber = DESCRIPTOR_PCAST(ConfigDescriptorData, + USB_Descriptor_Interface_t)->InterfaceNumber; - while (FoundEndpoints != (CDC_FOUND_NOTIFICATION_IN | CDC_FOUND_DATAPIPE_IN | CDC_FOUND_DATAPIPE_OUT)) + while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint)) { if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DCOMP_CDC_Host_NextCDCInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { - if (FoundEndpoints & CDC_FOUND_NOTIFICATION_IN) + if (NotificationEndpoint) { - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, - DCOMP_CDC_Host_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found) + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_CDC_Host_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found) { - return CDC_ENUMERROR_NoCDCInterfaceFound; - } + return CDC_ENUMERROR_NoCompatibleInterfaceFound; + } + + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; } else { - FoundEndpoints = 0; - - Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber); - Pipe_DisablePipe(); - Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber); - Pipe_DisablePipe(); - Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipeNumber); - Pipe_DisablePipe(); - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, - DCOMP_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) + DCOMP_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) { - return CDC_ENUMERROR_NoCDCInterfaceFound; + return CDC_ENUMERROR_NoCompatibleInterfaceFound; } - } - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, - DCOMP_CDC_Host_NextCDCInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) - { - return CDC_ENUMERROR_EndpointsNotFound; + CDCInterfaceInfo->State.ControlInterfaceNumber = DESCRIPTOR_PCAST(ConfigDescriptorData, + USB_Descriptor_Interface_t)->InterfaceNumber; + + NotificationEndpoint = NULL; } + + continue; } USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); - if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT) + if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) { - if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) - { - Pipe_ConfigurePipe(CDCInterfaceInfo->Config.NotificationPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN, - EndpointData->EndpointAddress, EndpointData->EndpointSize, - CDCInterfaceInfo->Config.NotificationPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - CDCInterfaceInfo->State.NotificationPipeSize = EndpointData->EndpointSize; - - Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS); - - FoundEndpoints |= CDC_FOUND_NOTIFICATION_IN; - } + if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT) + NotificationEndpoint = EndpointData; + else + DataINEndpoint = EndpointData; } else { - if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) - { - Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN, - EndpointData->EndpointAddress, EndpointData->EndpointSize, - CDCInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); + DataOUTEndpoint = EndpointData; + } + } + + for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++) + { + if (PipeNum == CDCInterfaceInfo->Config.DataINPipeNumber) + { + Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN, + DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, + CDCInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - CDCInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize; + CDCInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize; + } + else if (PipeNum == CDCInterfaceInfo->Config.DataOUTPipeNumber) + { + Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT, + DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, + CDCInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - FoundEndpoints |= CDC_FOUND_DATAPIPE_IN; - } - else - { - Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT, - EndpointData->EndpointAddress, EndpointData->EndpointSize, - CDCInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - - CDCInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize; - - FoundEndpoints |= CDC_FOUND_DATAPIPE_OUT; - } + CDCInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize; + } + else if (PipeNum == CDCInterfaceInfo->Config.NotificationPipeNumber) + { + Pipe_ConfigurePipe(PipeNum, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN, + NotificationEndpoint->EndpointAddress, NotificationEndpoint->EndpointSize, + CDCInterfaceInfo->Config.NotificationPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); + Pipe_SetInterruptPeriod(NotificationEndpoint->PollingIntervalMS); + + CDCInterfaceInfo->State.NotificationPipeSize = NotificationEndpoint->EndpointSize; } } CDCInterfaceInfo->State.ControlLineStates.HostToDevice = (CDC_CONTROL_LINE_OUT_RTS | CDC_CONTROL_LINE_OUT_DTR); CDCInterfaceInfo->State.ControlLineStates.DeviceToHost = (CDC_CONTROL_LINE_IN_DCD | CDC_CONTROL_LINE_IN_DSR); CDCInterfaceInfo->State.IsActive = true; + return CDC_ENUMERROR_NoError; } diff --git a/LUFA/Drivers/USB/Class/Host/CDC.h b/LUFA/Drivers/USB/Class/Host/CDC.h index 848dd361a82befa51aaa2b97b1bd5e408d562be8..d7de77b89f719603c622e8d7f617e15cdcfbd651 100644 --- a/LUFA/Drivers/USB/Class/Host/CDC.h +++ b/LUFA/Drivers/USB/Class/Host/CDC.h @@ -143,8 +143,7 @@ { CDC_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ CDC_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ - CDC_ENUMERROR_NoCDCInterfaceFound = 2, /**< A compatible CDC interface was not found in the device's Configuration Descriptor. */ - CDC_ENUMERROR_EndpointsNotFound = 3, /**< Compatible CDC endpoints were not found in the device's CDC interface. */ + CDC_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible CDC interface was not found in the device's Configuration Descriptor. */ }; /* Function Prototypes: */ @@ -161,6 +160,10 @@ * This should be called once after the stack has enumerated the attached device, while the host state machine is in * the Addressed state. * + * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes. + * * \param[in,out] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state. * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor. @@ -315,10 +318,6 @@ #define CDC_DATA_CLASS 0x0A #define CDC_DATA_SUBCLASS 0x00 #define CDC_DATA_PROTOCOL 0x00 - - #define CDC_FOUND_DATAPIPE_IN (1 << 0) - #define CDC_FOUND_DATAPIPE_OUT (1 << 1) - #define CDC_FOUND_NOTIFICATION_IN (1 << 2) /* Function Prototypes: */ #if defined(__INCLUDE_FROM_CDC_CLASS_HOST_C) diff --git a/LUFA/Drivers/USB/Class/Host/HID.c b/LUFA/Drivers/USB/Class/Host/HID.c index bbb32cb552cd8c8f5d3365864193e209489bc7d1..cd22e65fcce183ada026e86e172975d25d11e85b 100644 --- a/LUFA/Drivers/USB/Class/Host/HID.c +++ b/LUFA/Drivers/USB/Class/Host/HID.c @@ -40,21 +40,22 @@ uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo uint16_t ConfigDescriptorSize, void* ConfigDescriptorData) { - uint8_t FoundEndpoints = 0; + USB_Descriptor_Interface_t* CurrentHIDInterface; + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State)); - + if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) return HID_ENUMERROR_InvalidConfigDescriptor; - USB_Descriptor_Interface_t* CurrentHIDInterface; - do { if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DCOMP_HID_Host_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found) { - return HID_ENUMERROR_NoHIDInterfaceFound; + return HID_ENUMERROR_NoCompatibleInterfaceFound; } CurrentHIDInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); @@ -65,47 +66,80 @@ uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo HIDInterfaceInfo->State.SupportsBootProtocol = (CurrentHIDInterface->SubClass != HID_BOOTP_NonBootProtocol); if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DCOMP_HID_NextHID) != DESCRIPTOR_SEARCH_COMP_Found) - return HID_ENUMERROR_NoHIDDescriptorFound; + return HID_ENUMERROR_NoCompatibleInterfaceFound; - HIDInterfaceInfo->State.HIDReportSize = DESCRIPTOR_CAST(ConfigDescriptorData, USB_HID_Descriptor_HID_t).HIDReportLength; + HIDInterfaceInfo->State.HIDReportSize = DESCRIPTOR_PCAST(ConfigDescriptorData, + USB_HID_Descriptor_HID_t)->HIDReportLength; - while (FoundEndpoints != (HID_FOUND_DATAPIPE_IN | HID_FOUND_DATAPIPE_OUT)) + while (!(DataINEndpoint) || !(DataOUTEndpoint)) { if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DCOMP_HID_Host_NextHIDInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { - if (FoundEndpoints & HID_FOUND_DATAPIPE_IN) + if (DataINEndpoint || DataOUTEndpoint) break; + + do + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_HID_Host_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return HID_ENUMERROR_NoCompatibleInterfaceFound; + } - return HID_ENUMERROR_EndpointsNotFound; + CurrentHIDInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + } while (HIDInterfaceInfo->Config.HIDInterfaceProtocol && + (CurrentHIDInterface->Protocol != HIDInterfaceInfo->Config.HIDInterfaceProtocol)); + + HIDInterfaceInfo->State.InterfaceNumber = CurrentHIDInterface->InterfaceNumber; + HIDInterfaceInfo->State.SupportsBootProtocol = (CurrentHIDInterface->SubClass != HID_BOOTP_NonBootProtocol); + + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DCOMP_HID_NextHID) != DESCRIPTOR_SEARCH_COMP_Found) + return HID_ENUMERROR_NoCompatibleInterfaceFound; + + HIDInterfaceInfo->State.HIDReportSize = DESCRIPTOR_PCAST(ConfigDescriptorData, + USB_HID_Descriptor_HID_t)->HIDReportLength; + + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; + + continue; } USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) + DataINEndpoint = EndpointData; + else + DataOUTEndpoint = EndpointData; + } + + for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++) + { + if (PipeNum == HIDInterfaceInfo->Config.DataINPipeNumber) { - Pipe_ConfigurePipe(HIDInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN, - EndpointData->EndpointAddress, EndpointData->EndpointSize, + Pipe_ConfigurePipe(PipeNum, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN, + DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, HIDInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - HIDInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize; + Pipe_SetInterruptPeriod(DataINEndpoint->PollingIntervalMS); - FoundEndpoints |= HID_FOUND_DATAPIPE_IN; + HIDInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize; } - else + else if (PipeNum == HIDInterfaceInfo->Config.DataOUTPipeNumber) { - Pipe_ConfigurePipe(HIDInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_OUT, - EndpointData->EndpointAddress, EndpointData->EndpointSize, + Pipe_ConfigurePipe(PipeNum, EP_TYPE_INTERRUPT, PIPE_TOKEN_OUT, + DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, HIDInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - HIDInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize; - + Pipe_SetInterruptPeriod(DataOUTEndpoint->PollingIntervalMS); + + HIDInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize; HIDInterfaceInfo->State.DeviceUsesOUTPipe = true; - - FoundEndpoints |= HID_FOUND_DATAPIPE_OUT; } } - + HIDInterfaceInfo->State.LargestReportSize = 8; HIDInterfaceInfo->State.IsActive = true; + return HID_ENUMERROR_NoError; } diff --git a/LUFA/Drivers/USB/Class/Host/HID.h b/LUFA/Drivers/USB/Class/Host/HID.h index bbc8f5d124cbdef94a8bdff94c36559c0531212b..fc9249c21397ab4817bcde79fcc0ec7630534a24 100644 --- a/LUFA/Drivers/USB/Class/Host/HID.h +++ b/LUFA/Drivers/USB/Class/Host/HID.h @@ -139,9 +139,7 @@ { HID_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ HID_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ - HID_ENUMERROR_NoHIDInterfaceFound = 2, /**< A compatible HID interface was not found in the device's Configuration Descriptor. */ - HID_ENUMERROR_NoHIDDescriptorFound = 3, /**< The HID descriptor was not found in the device's HID interface. */ - HID_ENUMERROR_EndpointsNotFound = 4, /**< Compatible HID endpoints were not found in the device's HID interface. */ + HID_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible HID interface was not found in the device's Configuration Descriptor. */ }; /* Function Prototypes: */ @@ -151,6 +149,11 @@ * device. This should be called once after the stack has enumerated the attached device, while the host state * machine is in the Addressed state. * + * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes. + * \n\n + * * \note Once the device pipes are configured, the HID device's reporting protocol <b>must</b> be set via a call * to either the \ref HID_Host_SetBootProtocol() or \ref HID_Host_SetReportProtocol() function. * @@ -291,9 +294,6 @@ #if !defined(__DOXYGEN__) /* Macros: */ #define HID_INTERFACE_CLASS 0x03 - - #define HID_FOUND_DATAPIPE_IN (1 << 0) - #define HID_FOUND_DATAPIPE_OUT (1 << 1) /* Function Prototypes: */ #if defined(__INCLUDE_FROM_HID_CLASS_HOST_C) diff --git a/LUFA/Drivers/USB/Class/Host/MIDI.c b/LUFA/Drivers/USB/Class/Host/MIDI.c index fd7f13ccdfbeabf79d72326ee2c236ffdc90e7c6..6f34933fb4f70563bac9aa7707442dae8d79b42c 100644 --- a/LUFA/Drivers/USB/Class/Host/MIDI.c +++ b/LUFA/Drivers/USB/Class/Host/MIDI.c @@ -40,50 +40,72 @@ uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceI uint16_t ConfigDescriptorSize, void* ConfigDescriptorData) { - uint8_t FoundEndpoints = 0; + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State)); if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) return MIDI_ENUMERROR_InvalidConfigDescriptor; - + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DCOMP_MIDI_Host_NextMIDIStreamingInterface) != DESCRIPTOR_SEARCH_COMP_Found) { - return MIDI_ENUMERROR_NoStreamingInterfaceFound; + return MIDI_ENUMERROR_NoCompatibleInterfaceFound; } - while (FoundEndpoints != (MIDI_FOUND_DATAPIPE_IN | MIDI_FOUND_DATAPIPE_OUT)) + MIDIInterfaceInfo->State.InterfaceNumber = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t)->InterfaceNumber; + + while (!(DataINEndpoint) || !(DataOUTEndpoint)) { if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { - return MIDI_ENUMERROR_EndpointsNotFound; + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; + + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_MIDI_Host_NextMIDIStreamingInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return MIDI_ENUMERROR_NoCompatibleInterfaceFound; + } + + MIDIInterfaceInfo->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) + DataINEndpoint = EndpointData; + else + DataOUTEndpoint = EndpointData; + } + + for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++) + { + if (PipeNum == MIDIInterfaceInfo->Config.DataINPipeNumber) { - Pipe_ConfigurePipe(MIDIInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN, - EndpointData->EndpointAddress, EndpointData->EndpointSize, + Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN, + DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, MIDIInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - MIDIInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize; - FoundEndpoints |= MIDI_FOUND_DATAPIPE_IN; + MIDIInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize; } - else + else if (PipeNum == MIDIInterfaceInfo->Config.DataOUTPipeNumber) { - Pipe_ConfigurePipe(MIDIInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT, - EndpointData->EndpointAddress, EndpointData->EndpointSize, + Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT, + DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, MIDIInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - MIDIInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize; - - FoundEndpoints |= MIDI_FOUND_DATAPIPE_OUT; + + MIDIInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize; } } - + MIDIInterfaceInfo->State.IsActive = true; + return MIDI_ENUMERROR_NoError; } diff --git a/LUFA/Drivers/USB/Class/Host/MIDI.h b/LUFA/Drivers/USB/Class/Host/MIDI.h index d5cf5829ec5a38e3cadce0b2a1bfaf1c930dae94..f71f000f6797335065fc88f55dd8a28fa0e6da43 100644 --- a/LUFA/Drivers/USB/Class/Host/MIDI.h +++ b/LUFA/Drivers/USB/Class/Host/MIDI.h @@ -89,10 +89,11 @@ */ struct { - bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid - * after \ref MIDI_Host_ConfigurePipes() is called and the Host state machine is in the - * Configured state. - */ + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref MIDI_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t InterfaceNumber; /**< Interface index of the MIDI interface within the attached device. */ uint16_t DataINPipeSize; /**< Size in bytes of the MIDI Streaming Data interface's IN data pipe. */ uint16_t DataOUTPipeSize; /**< Size in bytes of the MIDI Streaming Data interface's OUT data pipe. */ @@ -108,8 +109,7 @@ { MIDI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ MIDI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ - MIDI_ENUMERROR_NoStreamingInterfaceFound = 2, /**< A compatible MIDI interface was not found in the device's Configuration Descriptor. */ - MIDI_ENUMERROR_EndpointsNotFound = 3, /**< Compatible MIDI data endpoints were not found in the device's MIDI interface. */ + MIDI_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible MIDI interface was not found in the device's Configuration Descriptor. */ }; /* Function Prototypes: */ @@ -119,6 +119,10 @@ * This should be called once after the stack has enumerated the attached device, while the host state machine is in * the Addressed state. * + * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes. + * * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state. * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor. @@ -184,9 +188,6 @@ #define MIDI_STREAMING_CLASS 0x01 #define MIDI_STREAMING_SUBCLASS 0x03 #define MIDI_STREAMING_PROTOCOL 0x00 - - #define MIDI_FOUND_DATAPIPE_IN (1 << 0) - #define MIDI_FOUND_DATAPIPE_OUT (1 << 1) /* Function Prototypes: */ #if defined(__INCLUDE_FROM_MIDI_CLASS_HOST_C) diff --git a/LUFA/Drivers/USB/Class/Host/MassStorage.c b/LUFA/Drivers/USB/Class/Host/MassStorage.c index 0366703bb87f44b6527554bc2d27d56ab0a0dc62..104a358ce5cee315ffe2601f231188c93c8ee8d6 100644 --- a/LUFA/Drivers/USB/Class/Host/MassStorage.c +++ b/LUFA/Drivers/USB/Class/Host/MassStorage.c @@ -38,58 +38,78 @@ uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, uint16_t ConfigDescriptorSize, - void* DeviceConfigDescriptor) + void* ConfigDescriptorData) { - uint8_t FoundEndpoints = 0; - + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State)); - if (DESCRIPTOR_TYPE(DeviceConfigDescriptor) != DTYPE_Configuration) + if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) return MS_ENUMERROR_InvalidConfigDescriptor; - - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor, - DCOMP_MS_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found) + + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_MS_Host_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found) { - return MS_ENUMERROR_NoMSInterfaceFound; + return MS_ENUMERROR_NoCompatibleInterfaceFound; } - - MSInterfaceInfo->State.InterfaceNumber = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Interface_t)->InterfaceNumber; - while (FoundEndpoints != (MS_FOUND_DATAPIPE_IN | MS_FOUND_DATAPIPE_OUT)) + MSInterfaceInfo->State.InterfaceNumber = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t)->InterfaceNumber; + + while (!(DataINEndpoint) || !(DataOUTEndpoint)) { - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor, - DCOMP_MS_NextMSInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_MS_Host_NextMSInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { - return MS_ENUMERROR_EndpointsNotFound; + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; + + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_MS_Host_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return MS_ENUMERROR_NoCompatibleInterfaceFound; + } + + MSInterfaceInfo->State.InterfaceNumber = DESCRIPTOR_PCAST(ConfigDescriptorData, + USB_Descriptor_Interface_t)->InterfaceNumber; + + continue; } - USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Endpoint_t); + USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) + DataINEndpoint = EndpointData; + else + DataOUTEndpoint = EndpointData; + } + + for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++) + { + if (PipeNum == MSInterfaceInfo->Config.DataINPipeNumber) { - Pipe_ConfigurePipe(MSInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN, - EndpointData->EndpointAddress, EndpointData->EndpointSize, - MSInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - MSInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize; - - FoundEndpoints |= MS_FOUND_DATAPIPE_IN; + Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN, + DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, + MSInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); + + MSInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize; } - else + else if (PipeNum == MSInterfaceInfo->Config.DataOUTPipeNumber) { - Pipe_ConfigurePipe(MSInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT, - EndpointData->EndpointAddress, EndpointData->EndpointSize, - MSInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - MSInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize; - - FoundEndpoints |= MS_FOUND_DATAPIPE_OUT; - } + Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT, + DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, + MSInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); + + MSInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize; + } } MSInterfaceInfo->State.IsActive = true; + return MS_ENUMERROR_NoError; } -static uint8_t DCOMP_MS_NextMSInterface(void* const CurrentDescriptor) +static uint8_t DCOMP_MS_Host_NextMSInterface(void* const CurrentDescriptor) { if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface) { @@ -107,7 +127,7 @@ static uint8_t DCOMP_MS_NextMSInterface(void* const CurrentDescriptor) return DESCRIPTOR_SEARCH_NotFound; } -static uint8_t DCOMP_MS_NextMSInterfaceEndpoint(void* const CurrentDescriptor) +static uint8_t DCOMP_MS_Host_NextMSInterfaceEndpoint(void* const CurrentDescriptor) { if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint) { diff --git a/LUFA/Drivers/USB/Class/Host/MassStorage.h b/LUFA/Drivers/USB/Class/Host/MassStorage.h index bfbe6cdb763408e60ab5a8e3555095f883fe9072..606aa79f87bf2b73c8abc2796a234ab23bd4837c 100644 --- a/LUFA/Drivers/USB/Class/Host/MassStorage.h +++ b/LUFA/Drivers/USB/Class/Host/MassStorage.h @@ -93,11 +93,11 @@ */ struct { - bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid - * after \ref MS_Host_ConfigurePipes() is called and the Host state machine is in the - * Configured state. - */ - uint8_t InterfaceNumber; /**< Interface index of the Mass Storage interface within the attached device. */ + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref MS_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t InterfaceNumber; /**< Interface index of the Mass Storage interface within the attached device. */ uint16_t DataINPipeSize; /**< Size in bytes of the Mass Storage interface's IN data pipe. */ uint16_t DataOUTPipeSize; /**< Size in bytes of the Mass Storage interface's OUT data pipe. */ @@ -126,8 +126,7 @@ { MS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ MS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ - MS_ENUMERROR_NoMSInterfaceFound = 2, /**< A compatible Mass Storage interface was not found in the device's Configuration Descriptor. */ - MS_ENUMERROR_EndpointsNotFound = 3, /**< Compatible Mass Storage endpoints were not found in the device's interfaces. */ + MS_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Mass Storage interface was not found in the device's Configuration Descriptor. */ }; /* Function Prototypes: */ @@ -137,15 +136,19 @@ * is found within the device. This should be called once after the stack has enumerated the attached device, while * the host state machine is in the Addressed state. * - * \param[in,out] MSInterfaceInfo Pointer to a structure containing an MS Class host configuration and state. - * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. - * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor. + * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing an MS Class host configuration and state. + * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. + * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. * * \return A value from the \ref MS_Host_EnumerationFailure_ErrorCodes_t enum. */ uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, uint16_t ConfigDescriptorSize, - void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); /** Sends a MASS STORAGE RESET control request to the attached device, resetting the Mass Storage Interface * and readying it for the next Mass Storage command. @@ -320,14 +323,11 @@ #define COMMAND_DIRECTION_DATA_IN (1 << 7) #define COMMAND_DATA_TIMEOUT_MS 10000 - - #define MS_FOUND_DATAPIPE_IN (1 << 0) - #define MS_FOUND_DATAPIPE_OUT (1 << 1) /* Function Prototypes: */ #if defined(__INCLUDE_FROM_MS_CLASS_HOST_C) - static uint8_t DCOMP_MS_NextMSInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1); - static uint8_t DCOMP_MS_NextMSInterfaceEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_MS_Host_NextMSInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_MS_Host_NextMSInterfaceEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1); static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, MS_CommandBlockWrapper_t* const SCSICommandBlock, diff --git a/LUFA/Drivers/USB/Class/Host/Printer.c b/LUFA/Drivers/USB/Class/Host/Printer.c index 99977e5a7e190f697a0d16d105a0393f693a1870..e1c3e15505fbca73bd53e5cd9545744035d5e514 100644 --- a/LUFA/Drivers/USB/Class/Host/Printer.c +++ b/LUFA/Drivers/USB/Class/Host/Printer.c @@ -40,8 +40,9 @@ uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceI uint16_t ConfigDescriptorSize, void* DeviceConfigDescriptor) { - uint8_t FoundEndpoints = 0; - + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + memset(&PRNTInterfaceInfo->State, 0x00, sizeof(PRNTInterfaceInfo->State)); if (DESCRIPTOR_TYPE(DeviceConfigDescriptor) != DTYPE_Configuration) @@ -50,45 +51,66 @@ uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceI if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor, DCOMP_PRNT_NextPRNTInterface) != DESCRIPTOR_SEARCH_COMP_Found) { - return PRNT_ENUMERROR_NoPrinterInterfaceFound; + return PRNT_ENUMERROR_NoCompatibleInterfaceFound; } - USB_Descriptor_Interface_t* PrinterInterface = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Interface_t); - - PRNTInterfaceInfo->State.InterfaceNumber = PrinterInterface->InterfaceNumber; - PRNTInterfaceInfo->State.AlternateSetting = PrinterInterface->AlternateSetting; + PRNTInterfaceInfo->State.InterfaceNumber = DESCRIPTOR_PCAST(DeviceConfigDescriptor, + USB_Descriptor_Interface_t)->InterfaceNumber; + PRNTInterfaceInfo->State.AlternateSetting = DESCRIPTOR_PCAST(DeviceConfigDescriptor, + USB_Descriptor_Interface_t)->AlternateSetting; - while (FoundEndpoints != (PRNT_FOUND_DATAPIPE_IN | PRNT_FOUND_DATAPIPE_OUT)) + while (!(DataINEndpoint) || !(DataOUTEndpoint)) { if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor, DCOMP_PRNT_NextPRNTInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { - return PRNT_ENUMERROR_EndpointsNotFound; + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; + + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor, + DCOMP_PRNT_NextPRNTInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return PRNT_ENUMERROR_NoCompatibleInterfaceFound; + } + + PRNTInterfaceInfo->State.InterfaceNumber = DESCRIPTOR_PCAST(DeviceConfigDescriptor, + USB_Descriptor_Interface_t)->InterfaceNumber; + PRNTInterfaceInfo->State.AlternateSetting = DESCRIPTOR_PCAST(DeviceConfigDescriptor, + USB_Descriptor_Interface_t)->AlternateSetting; + + continue; } USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Endpoint_t); if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) + DataINEndpoint = EndpointData; + else + DataOUTEndpoint = EndpointData; + } + + for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++) + { + if (PipeNum == PRNTInterfaceInfo->Config.DataINPipeNumber) { - Pipe_ConfigurePipe(PRNTInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN, - EndpointData->EndpointAddress, EndpointData->EndpointSize, - PRNTInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - PRNTInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize; - - FoundEndpoints |= PRNT_FOUND_DATAPIPE_IN; + Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN, + DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, + PRNTInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); + + PRNTInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize; } - else + else if (PipeNum == PRNTInterfaceInfo->Config.DataOUTPipeNumber) { - Pipe_ConfigurePipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT, - EndpointData->EndpointAddress, EndpointData->EndpointSize, - PRNTInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - PRNTInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize; - - FoundEndpoints |= PRNT_FOUND_DATAPIPE_OUT; - } + Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT, + DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, + PRNTInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); + + PRNTInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize; + } } PRNTInterfaceInfo->State.IsActive = true; + return PRNT_ENUMERROR_NoError; } diff --git a/LUFA/Drivers/USB/Class/Host/Printer.h b/LUFA/Drivers/USB/Class/Host/Printer.h index 37216081be4a54071098af9297146593a4eaadf0..9848287f4ca88871258112a3b493e05558387dcc 100644 --- a/LUFA/Drivers/USB/Class/Host/Printer.h +++ b/LUFA/Drivers/USB/Class/Host/Printer.h @@ -109,8 +109,7 @@ { PRNT_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ PRNT_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ - PRNT_ENUMERROR_NoPrinterInterfaceFound = 2, /**< A compatible Printer interface was not found in the device's Configuration Descriptor. */ - PRNT_ENUMERROR_EndpointsNotFound = 3, /**< Compatible Printer endpoints were not found in the device's interfaces. */ + PRNT_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Printer interface was not found in the device's Configuration Descriptor. */ }; /* Function Prototypes: */ @@ -128,6 +127,10 @@ * the device. This should be called once after the stack has enumerated the attached device, while the host state * machine is in the Addressed state. * + * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes. + * * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor. @@ -265,9 +268,6 @@ #define REQ_GetDeviceID 0 #define REQ_GetPortStatus 1 #define REQ_SoftReset 2 - - #define PRNT_FOUND_DATAPIPE_IN (1 << 0) - #define PRNT_FOUND_DATAPIPE_OUT (1 << 1) /* Function Prototypes: */ #if defined(__INCLUDE_FROM_PRINTER_CLASS_HOST_C) diff --git a/LUFA/Drivers/USB/Class/Host/RNDIS.c b/LUFA/Drivers/USB/Class/Host/RNDIS.c index b3d0f3070a13a72cf3fcec5d7c4a1f59bc155779..f6dcba12bd2f0504422bf5e07e6b34e0683e06f0 100644 --- a/LUFA/Drivers/USB/Class/Host/RNDIS.c +++ b/LUFA/Drivers/USB/Class/Host/RNDIS.c @@ -40,99 +40,103 @@ uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfa uint16_t ConfigDescriptorSize, void* ConfigDescriptorData) { - uint8_t FoundEndpoints = 0; + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + USB_Descriptor_Endpoint_t* NotificationEndpoint = NULL; memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State)); if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) return RNDIS_ENUMERROR_InvalidConfigDescriptor; - + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DCOMP_RNDIS_Host_NextRNDISControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) { - return RNDIS_ENUMERROR_NoRNDISInterfaceFound; + return RNDIS_ENUMERROR_NoCompatibleInterfaceFound; } - RNDISInterfaceInfo->State.ControlInterfaceNumber = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).InterfaceNumber; + RNDISInterfaceInfo->State.ControlInterfaceNumber = DESCRIPTOR_PCAST(ConfigDescriptorData, + USB_Descriptor_Interface_t)->InterfaceNumber; - while (FoundEndpoints != (RNDIS_FOUND_NOTIFICATION_IN | RNDIS_FOUND_DATAPIPE_IN | RNDIS_FOUND_DATAPIPE_OUT)) + while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint)) { if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { - if (FoundEndpoints & RNDIS_FOUND_NOTIFICATION_IN) + if (NotificationEndpoint) { - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, - DCOMP_RNDIS_Host_NextRNDISDataInterface) != DESCRIPTOR_SEARCH_COMP_Found) + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_RNDIS_Host_NextRNDISDataInterface) != DESCRIPTOR_SEARCH_COMP_Found) { - return RNDIS_ENUMERROR_NoRNDISInterfaceFound; - } + return RNDIS_ENUMERROR_NoCompatibleInterfaceFound; + } + + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; } else { - FoundEndpoints = 0; - - Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipeNumber); - Pipe_DisablePipe(); - Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber); - Pipe_DisablePipe(); - Pipe_SelectPipe(RNDISInterfaceInfo->Config.NotificationPipeNumber); - Pipe_DisablePipe(); - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, - DCOMP_RNDIS_Host_NextRNDISControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) + DCOMP_RNDIS_Host_NextRNDISControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) { - return RNDIS_ENUMERROR_NoRNDISInterfaceFound; + return RNDIS_ENUMERROR_NoCompatibleInterfaceFound; } - } - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, - DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) - { - return RNDIS_ENUMERROR_EndpointsNotFound; + RNDISInterfaceInfo->State.ControlInterfaceNumber = DESCRIPTOR_PCAST(ConfigDescriptorData, + USB_Descriptor_Interface_t)->InterfaceNumber; + + NotificationEndpoint = NULL; } + + continue; } USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); - if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT) + if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) { - if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) - { - Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.NotificationPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN, - EndpointData->EndpointAddress, EndpointData->EndpointSize, - RNDISInterfaceInfo->Config.NotificationPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - RNDISInterfaceInfo->State.NotificationPipeSize = EndpointData->EndpointSize; - - Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS); - - FoundEndpoints |= RNDIS_FOUND_NOTIFICATION_IN; - } + if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT) + NotificationEndpoint = EndpointData; + else + DataINEndpoint = EndpointData; } else { - if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) - { - Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN, - EndpointData->EndpointAddress, EndpointData->EndpointSize, - RNDISInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - RNDISInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize; + DataOUTEndpoint = EndpointData; + } + } + + for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++) + { + if (PipeNum == RNDISInterfaceInfo->Config.DataINPipeNumber) + { + Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN, + DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, + RNDISInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - FoundEndpoints |= RNDIS_FOUND_DATAPIPE_IN; - } - else - { - Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT, - EndpointData->EndpointAddress, EndpointData->EndpointSize, - RNDISInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); - RNDISInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize; - - FoundEndpoints |= RNDIS_FOUND_DATAPIPE_OUT; - } + RNDISInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize; + } + else if (PipeNum == RNDISInterfaceInfo->Config.DataOUTPipeNumber) + { + Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT, + DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, + RNDISInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); + + RNDISInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize; + } + else if (PipeNum == RNDISInterfaceInfo->Config.NotificationPipeNumber) + { + Pipe_ConfigurePipe(PipeNum, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN, + NotificationEndpoint->EndpointAddress, NotificationEndpoint->EndpointSize, + RNDISInterfaceInfo->Config.NotificationPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); + Pipe_SetInterruptPeriod(NotificationEndpoint->PollingIntervalMS); + + RNDISInterfaceInfo->State.NotificationPipeSize = NotificationEndpoint->EndpointSize; } } RNDISInterfaceInfo->State.IsActive = true; + return RNDIS_ENUMERROR_NoError; } diff --git a/LUFA/Drivers/USB/Class/Host/RNDIS.h b/LUFA/Drivers/USB/Class/Host/RNDIS.h index df99824bdd402e08f4c349a861aa6c9af4cedf7b..0cb5f46ceb86f04264a40d48bdcdf199490c6888 100644 --- a/LUFA/Drivers/USB/Class/Host/RNDIS.h +++ b/LUFA/Drivers/USB/Class/Host/RNDIS.h @@ -123,8 +123,7 @@ { RNDIS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ RNDIS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ - RNDIS_ENUMERROR_NoRNDISInterfaceFound = 2, /**< A compatible RNDIS interface was not found in the device's Configuration Descriptor. */ - RNDIS_ENUMERROR_EndpointsNotFound = 3, /**< Compatible RNDIS endpoints were not found in the device's RNDIS interface. */ + RNDIS_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible RNDIS interface was not found in the device's Configuration Descriptor. */ }; /* Macros: */ @@ -138,6 +137,10 @@ * This should be called once after the stack has enumerated the attached device, while the host state machine is in * the Addressed state. * + * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes. + * * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor. @@ -262,10 +265,6 @@ #define RNDIS_DATA_CLASS 0x0A #define RNDIS_DATA_SUBCLASS 0x00 #define RNDIS_DATA_PROTOCOL 0x00 - - #define RNDIS_FOUND_DATAPIPE_IN (1 << 0) - #define RNDIS_FOUND_DATAPIPE_OUT (1 << 1) - #define RNDIS_FOUND_NOTIFICATION_IN (1 << 2) /* Function Prototypes: */ #if defined(__INCLUDE_FROM_RNDIS_CLASS_HOST_C) diff --git a/LUFA/Drivers/USB/Class/Host/StillImage.c b/LUFA/Drivers/USB/Class/Host/StillImage.c index 3883d3bad5fa0c90c8cacd9b11a397a34e5bc776..744444d593e61927ba7ab666715653d1e0b2fc98 100644 --- a/LUFA/Drivers/USB/Class/Host/StillImage.c +++ b/LUFA/Drivers/USB/Class/Host/StillImage.c @@ -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; + 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); - 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; + 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); - FoundEndpoints |= SI_FOUND_DATAPIPE_OUT; - } + 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; } diff --git a/LUFA/Drivers/USB/Class/Host/StillImage.h b/LUFA/Drivers/USB/Class/Host/StillImage.h index 020f03003ed104fa30973d1e7abb3da9fa64b8a2..319b72a1ba437b5cc0f22bc5d5dc71bcfa452483 100644 --- a/LUFA/Drivers/USB/Class/Host/StillImage.h +++ b/LUFA/Drivers/USB/Class/Host/StillImage.h @@ -96,10 +96,11 @@ */ struct { - bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid - * after \ref SI_Host_ConfigurePipes() is called and the Host state machine is in the - * Configured state. - */ + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref SI_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t InterfaceNumber; /**< Interface index of the Mass Storage interface within the attached device. */ uint16_t DataINPipeSize; /**< Size in bytes of the Still Image interface's IN data pipe. */ uint16_t DataOUTPipeSize; /**< Size in bytes of the Still Image interface's OUT data pipe. */ @@ -119,12 +120,9 @@ { SI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ SI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ - SI_ENUMERROR_NoSIInterfaceFound = 2, /**< A compatible Still Image interface was not found in the device's + SI_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Still Image interface was not found in the device's * Configuration Descriptor. */ - SI_ENUMERROR_EndpointsNotFound = 3, /**< Compatible Still Image data endpoints were not found in the - * device's Still Image interface. - */ }; /* Function Prototypes: */ @@ -134,15 +132,19 @@ * found within the device. This should be called once after the stack has enumerated the attached device, while * the host state machine is in the Addressed state. * - * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. - * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. - * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor. + * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other + * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes + * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. + * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. * * \return A value from the \ref SI_Host_EnumerationFailure_ErrorCodes_t enum. */ uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, uint16_t ConfigDescriptorSize, - void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); /** Opens a new PIMA session with the attached device. This should be used before any session-orientated PIMA commands * are issued to the device. Only one session can be open at the one time. @@ -309,10 +311,6 @@ #define STILL_IMAGE_SUBCLASS 0x01 #define STILL_IMAGE_PROTOCOL 0x01 - #define SI_FOUND_EVENTS_IN (1 << 0) - #define SI_FOUND_DATAPIPE_IN (1 << 1) - #define SI_FOUND_DATAPIPE_OUT (1 << 2) - #define COMMAND_DATA_TIMEOUT_MS 10000 /* Function Prototypes: */ diff --git a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c index 78290d73c173b54f6bb3a9fe14d0afc7e319d9b2..b5d98c04d9e33a2be163a77cea94fe0d8c03132d 100644 --- a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c +++ b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c @@ -52,7 +52,7 @@ uint8_t USB_Host_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const if ((ErrorCode = USB_Host_SendControlRequest(ConfigHeader)) != HOST_SENDCONTROL_Successful) return ErrorCode; - *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).TotalConfigurationSize; + *ConfigSizePtr = DESCRIPTOR_PCAST(ConfigHeader, USB_Descriptor_Configuration_Header_t)->TotalConfigurationSize; if (*ConfigSizePtr > BufferSize) return HOST_GETCONFIG_BuffOverflow; diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 97ed9e5068905defbf384960d24ccf2e9ae13866..957005441353df4b6ded940183a588751aef5822 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -45,7 +45,7 @@ * - Removed the EVENT_USB_InitFailure() event, not specifying a USB mode now defaults to UID selection mode * - Renamed and moved class driver common constant definitions to make the naming scheme more uniform * - Changed default value for the reset polarity parameter in the AVRISP-MKII project so that it defaults to active low drive - * - Rewritten configuration descriptor parser for all host mode projects and class drivers to ensure better compatibility + * - Changed configuration descriptor parser for all host mode projects and class drivers to ensure better compatibility with devices * * <b>Fixed:</b> * - Fixed USB_GetHIDReportItemInfo() function modifying the given report item's data when the report item does not exist diff --git a/Projects/MissileLauncher/ConfigDescriptor.c b/Projects/MissileLauncher/ConfigDescriptor.c index 7214c7e6a2efb48711c5f540e51af630a278927b..78b4d2fad50b2aab6a280378eb8719218bd4648f 100644 --- a/Projects/MissileLauncher/ConfigDescriptor.c +++ b/Projects/MissileLauncher/ConfigDescriptor.c @@ -50,7 +50,9 @@ uint8_t ProcessConfigurationDescriptor(void) 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; /* Retrieve the entire configuration descriptor into the allocated buffer */ switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) @@ -65,50 +67,62 @@ uint8_t ProcessConfigurationDescriptor(void) return ControlError; } - /* Get the HID interface from the configuration descriptor */ + /* Get the first HID interface from the configuration descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ - return NoHIDInterfaceFound; + return NoCompatibleInterfaceFound; } - while (FoundEndpoints != ((1 << HID_DATA_IN_PIPE) | (1 << HID_DATA_OUT_PIPE))) + while (!(DataINEndpoint) || !(DataOUTEndpoint)) { /* Get the next HID interface's data endpoint descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, - DComp_NextInterfaceHIDDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) + DComp_NextHIDInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Not all HID devices have an OUT endpoint - if we've reached the end of the HID descriptor * but only found the mandatory IN endpoint, it's safe to continue with the device enumeration */ - if (FoundEndpoints == (1 << HID_DATA_IN_PIPE)) + if (DataINEndpoint) break; - - /* Descriptor not found, error out */ - return NoEndpointFound; + + /* Clear any found endpoints */ + DataOUTEndpoint = NULL; + + /* Get the next HID interface from the configuration descriptor */ + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, + DComp_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + /* Descriptor not found, error out */ + return NoCompatibleInterfaceFound; + } + + /* Skip the remainder of the loop as we have not found an endpoint yet */ + continue; } /* Retrieve the endpoint address from the endpoint descriptor */ - USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); + USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t); /* If the endpoint is a IN type endpoint */ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) - { - /* Configure the HID data IN pipe */ - Pipe_ConfigurePipe(HID_DATA_IN_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN, - EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE); - - FoundEndpoints |= (1 << HID_DATA_IN_PIPE); - } + DataINEndpoint = EndpointData; else - { - /* Configure the HID data OUT pipe */ - Pipe_ConfigurePipe(HID_DATA_OUT_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_OUT, - EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE); - - FoundEndpoints |= (1 << HID_DATA_OUT_PIPE); - } + DataOUTEndpoint = EndpointData; } + + /* Configure the HID data IN pipe */ + Pipe_ConfigurePipe(HID_DATA_IN_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN, + DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE); + Pipe_SetInterruptPeriod(DataINEndpoint->PollingIntervalMS); + + /* Check if the HID interface contained an optional OUT data endpoint */ + if (DataOUTEndpoint) + { + /* Configure the HID data OUT pipe */ + Pipe_ConfigurePipe(HID_DATA_OUT_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_OUT, + DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, PIPE_BANK_SINGLE); + } /* Valid data found, return success */ return SuccessfulConfigRead; @@ -148,7 +162,7 @@ uint8_t DComp_NextHIDInterface(void* CurrentDescriptor) * * \return A value from the DSEARCH_Return_ErrorCodes_t enum */ -uint8_t DComp_NextInterfaceHIDDataEndpoint(void* CurrentDescriptor) +uint8_t DComp_NextHIDInterfaceDataEndpoint(void* CurrentDescriptor) { /* Determine the type of the current descriptor */ if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint) diff --git a/Projects/MissileLauncher/ConfigDescriptor.h b/Projects/MissileLauncher/ConfigDescriptor.h index 4df31f1f9dbd8cda66d4fd4e313b19b95a7d9197..5cddada1d15813a4b29a9c5be7446a1a2cfc397a 100644 --- a/Projects/MissileLauncher/ConfigDescriptor.h +++ b/Projects/MissileLauncher/ConfigDescriptor.h @@ -45,6 +45,12 @@ /** Interface Class value for the Human Interface Device class. */ #define HID_CLASS 0x03 + /** Pipe number for the HID data IN pipe. */ + #define HID_DATA_IN_PIPE 1 + + /** Pipe number for the HID data OUT pipe. */ + #define HID_DATA_OUT_PIPE 2 + /* Enums: */ /** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */ enum GenericHIDHost_GetConfigDescriptorDataCodes_t @@ -53,14 +59,13 @@ ControlError = 1, /**< A control request to the device failed to complete successfully */ DescriptorTooLarge = 2, /**< The device's Configuration Descriptor is too large to process */ InvalidConfigDataReturned = 3, /**< The device returned an invalid Configuration Descriptor */ - NoHIDInterfaceFound = 4, /**< A compatible HID interface was not found in the device's Configuration Descriptor */ - NoEndpointFound = 5, /**< A compatible HID IN endpoint was not found in the device's HID interface */ + NoCompatibleInterfaceFound = 4, /**< A compatible interface with the required endpoints was not found */ }; /* Function Prototypes: */ uint8_t ProcessConfigurationDescriptor(void); uint8_t DComp_NextHIDInterface(void* CurrentDescriptor); - uint8_t DComp_NextInterfaceHIDDataEndpoint(void* CurrentDescriptor); + uint8_t DComp_NextHIDInterfaceDataEndpoint(void* CurrentDescriptor); #endif diff --git a/Projects/MissileLauncher/MissileLauncher.h b/Projects/MissileLauncher/MissileLauncher.h index 57aae09922b048b4bc45f8ff156b20391bd53990..6bff6af8b569f0897609bc688506f664e57d7db9 100644 --- a/Projects/MissileLauncher/MissileLauncher.h +++ b/Projects/MissileLauncher/MissileLauncher.h @@ -54,12 +54,6 @@ #include "ConfigDescriptor.h" /* Macros: */ - /** Pipe number for the HID data IN pipe. */ - #define HID_DATA_IN_PIPE 1 - - /** Pipe number for the HID data OUT pipe. */ - #define HID_DATA_OUT_PIPE 2 - /** HID Class specific request to send a HID report to the device. */ #define REQ_SetReport 0x09