diff options
Diffstat (limited to 'LUFA/Drivers')
21 files changed, 457 insertions, 309 deletions
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.h b/LUFA/Drivers/USB/Class/Device/Audio.h index caf1fdc68..414f4526b 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 1b0b86810..0e27d9d59 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 e90f15d1f..097b12f29 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 e733bfecd..cb8e2dee3 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 9e8cccb6f..39a806eee 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 8af656322..64f967953 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 5a87c77ee..79c207ea8 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 848dd361a..d7de77b89 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 bbb32cb55..cd22e65fc 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 bbc8f5d12..fc9249c21 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 fd7f13ccd..6f34933fb 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 d5cf5829e..f71f000f6 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 0366703bb..104a358ce 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 bfbe6cdb7..606aa79f8 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 99977e5a7..e1c3e1550 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 37216081b..9848287f4 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 b3d0f3070..f6dcba12b 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 df99824bd..0cb5f46ce 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 3883d3bad..744444d59 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 020f03003..319b72a1b 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 78290d73c..b5d98c04d 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; |