Fix low level host mode demos not correctly fetching the next endpoint when an invali...
authorDean Camera <dean@fourwalledcubicle.com>
Thu, 30 Sep 2010 07:56:47 +0000 (07:56 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Thu, 30 Sep 2010 07:56:47 +0000 (07:56 +0000)
Update the pipe configuration routines in the host mode class drivers so that they use the same new code to enumerate compatible devices to increase reliability. Add support to the host mode class drivers for non-sequential (but non-overlapping with other interface) pipe numbers.

37 files changed:
Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c
Demos/Host/LowLevel/JoystickHostWithParser/ConfigDescriptor.c
Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c
Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c
Demos/Host/LowLevel/MIDIHost/ConfigDescriptor.c
Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c
Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c
Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c
Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c
Demos/Host/LowLevel/RNDISEthernetHost/ConfigDescriptor.c
Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c
Demos/Host/LowLevel/VirtualSerialHost/ConfigDescriptor.c
LUFA/Drivers/USB/Class/Device/Audio.h
LUFA/Drivers/USB/Class/Device/CDC.h
LUFA/Drivers/USB/Class/Device/HID.h
LUFA/Drivers/USB/Class/Device/MIDI.h
LUFA/Drivers/USB/Class/Device/MassStorage.h
LUFA/Drivers/USB/Class/Device/RNDIS.h
LUFA/Drivers/USB/Class/Host/CDC.c
LUFA/Drivers/USB/Class/Host/CDC.h
LUFA/Drivers/USB/Class/Host/HID.c
LUFA/Drivers/USB/Class/Host/HID.h
LUFA/Drivers/USB/Class/Host/MIDI.c
LUFA/Drivers/USB/Class/Host/MIDI.h
LUFA/Drivers/USB/Class/Host/MassStorage.c
LUFA/Drivers/USB/Class/Host/MassStorage.h
LUFA/Drivers/USB/Class/Host/Printer.c
LUFA/Drivers/USB/Class/Host/Printer.h
LUFA/Drivers/USB/Class/Host/RNDIS.c
LUFA/Drivers/USB/Class/Host/RNDIS.h
LUFA/Drivers/USB/Class/Host/StillImage.c
LUFA/Drivers/USB/Class/Host/StillImage.h
LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c
LUFA/ManPages/ChangeLog.txt
Projects/MissileLauncher/ConfigDescriptor.c
Projects/MissileLauncher/ConfigDescriptor.h
Projects/MissileLauncher/MissileLauncher.h

index 40bc98e..2de7b72 100644 (file)
@@ -96,6 +96,9 @@ uint8_t ProcessConfigurationDescriptor(void)
                                /* Descriptor not found, error out */
                                return NoCompatibleInterfaceFound;
                        }
                                /* 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 */
                }
                
                /* Retrieve the endpoint address from the endpoint descriptor */
index dfca7b4..1d82650 100644 (file)
@@ -87,6 +87,9 @@ uint8_t ProcessConfigurationDescriptor(void)
                                /* Descriptor not found, error out */
                                return NoCompatibleInterfaceFound;
                        }
                                /* 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 */
                }
                
                /* Retrieve the endpoint address from the endpoint descriptor */
index dbdfac9..988579c 100644 (file)
@@ -87,6 +87,9 @@ uint8_t ProcessConfigurationDescriptor(void)
                                /* Descriptor not found, error out */
                                return NoCompatibleInterfaceFound;
                        }
                                /* 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 */
                }
                
                /* Retrieve the endpoint address from the endpoint descriptor */
index d397ca7..bf2c4e0 100644 (file)
@@ -83,7 +83,7 @@ uint8_t ProcessConfigurationDescriptor(void)
        }
        
        /* Save the HID report size for later use */
        }
        
        /* 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))
        {
 
        while (!(DataINEndpoint))
        {
@@ -108,7 +108,10 @@ uint8_t ProcessConfigurationDescriptor(void)
                        }
                        
                        /* Save the HID report size for later use */
                        }
                        
                        /* 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 */
                }
                
                /* Retrieve the endpoint address from the endpoint descriptor */
index 3ede457..7dda634 100644 (file)
@@ -92,6 +92,9 @@ uint8_t ProcessConfigurationDescriptor(void)
                                /* Descriptor not found, error out */
                                return NoCompatibleInterfaceFound;
                        }
                                /* 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 */
                }
                
                /* Retrieve the endpoint address from the endpoint descriptor */
index 64565ac..a91d61a 100644 (file)
@@ -92,6 +92,9 @@ uint8_t ProcessConfigurationDescriptor(void)
                                /* Descriptor not found, error out */
                                return NoCompatibleInterfaceFound;
                        }
                                /* 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 */
                }
                
                /* Retrieve the endpoint address from the endpoint descriptor */
index 02c4cd4..4ea8aef 100644 (file)
@@ -87,6 +87,9 @@ uint8_t ProcessConfigurationDescriptor(void)
                                /* Descriptor not found, error out */
                                return NoCompatibleInterfaceFound;
                        }
                                /* 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 */
                }
                
                /* Retrieve the endpoint address from the endpoint descriptor */
index f285f5a..c5afbe4 100644 (file)
@@ -83,7 +83,7 @@ uint8_t ProcessConfigurationDescriptor(void)
        }
        
        /* Save the HID report size for later use */
        }
        
        /* 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))
        {
 
        while (!(DataINEndpoint))
        {
@@ -108,7 +108,10 @@ uint8_t ProcessConfigurationDescriptor(void)
                        }
                        
                        /* Save the HID report size for later use */
                        }
                        
                        /* 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 */
                }
                
                /* Retrieve the endpoint address from the endpoint descriptor */
index 0591aac..b16ac66 100644 (file)
@@ -75,8 +75,8 @@ uint8_t ProcessConfigurationDescriptor(void)
        }
 
        /* Save Printer interface details for later use */
        }
 
        /* 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))
        {
 
        while (!(DataINEndpoint) || !(DataOUTEndpoint))
        {
@@ -97,8 +97,11 @@ uint8_t ProcessConfigurationDescriptor(void)
                        }
                        
                        /* Save Printer interface details for later use */
                        }
                        
                        /* 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 */
                }
                
                /* 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)
 
                /* If the endpoint is a IN type endpoint */
                if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
-                 DataINEndpoint = EndpointData;
+                 DataINEndpoint  = EndpointData;
                else
                  DataOUTEndpoint = EndpointData;
        }
                else
                  DataOUTEndpoint = EndpointData;
        }
index 0db576f..aa75dd1 100644 (file)
@@ -110,6 +110,9 @@ uint8_t ProcessConfigurationDescriptor(void)
                                /* Clear any found endpoints */
                                NotificationEndpoint = NULL;
                        }
                                /* 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 */
                }
                
                /* Retrieve the endpoint address from the endpoint descriptor */
index 583df3b..78bca7f 100644 (file)
@@ -94,6 +94,9 @@ uint8_t ProcessConfigurationDescriptor(void)
                                /* Descriptor not found, error out */
                                return NoCompatibleInterfaceFound;
                        }
                                /* 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 */
                }
 
                /* Retrieve the endpoint address from the endpoint descriptor */
index c35a606..a26fa5c 100644 (file)
@@ -110,6 +110,9 @@ uint8_t ProcessConfigurationDescriptor(void)
                                /* Clear any found endpoints */
                                NotificationEndpoint = NULL;
                        }
                                /* 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 */
                }
                
                /* Retrieve the endpoint address from the endpoint descriptor */
index caf1fdc..414f452 100644 (file)
                         *  \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the
                         *  given Audio interface is selected.
                         *
                         *  \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.
                         *  \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.
index 1b0b868..0e27d9d 100644 (file)
                         *  \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing
                         *  the given CDC interface is selected.
                         *
                         *  \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.
                         *  \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.
index e90f15d..097b12f 100644 (file)
                         *  \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
                         *  containing the given HID interface is selected.
                         *
                         *  \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.
                         *  \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.
index e733bfe..cb8e2de 100644 (file)
                         *  \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
                         *  containing the given MIDI interface is selected.
                         *
                         *  \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.
                         *  \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.
index 9e8cccb..39a806e 100644 (file)
                         *  \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
                         *  containing the given Mass Storage interface is selected.
                         *
                         *  \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.
                         *  \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.
index 8af6563..64f9679 100644 (file)
                         *  \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
                         *  containing the given HID interface is selected.
                         *
                         *  \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.
                         *  \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.
index 5a87c77..79c207e 100644 (file)
@@ -40,103 +40,105 @@ uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo
                                 uint16_t ConfigDescriptorSize,
                                 void* ConfigDescriptorData)
 {
                                 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;
 
        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)
        {
        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 (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
                        {
                        }
                        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,
                                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);
 
                }
                
                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
                {
                }
                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;
                }
        }
 
        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;
 }
 
        return CDC_ENUMERROR_NoError;
 }
 
index 848dd36..d7de77b 100644 (file)
                        {
                                CDC_ENUMERROR_NoError                    = 0, /**< Configuration Descriptor was processed successfully. */
                                CDC_ENUMERROR_InvalidConfigDescriptor    = 1, /**< The device returned an invalid Configuration Descriptor. */
                        {
                                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: */
                        };
        
                /* Function Prototypes: */
                         *  This should be called once after the stack has enumerated the attached device, while the host state machine is in
                         *  the Addressed state.
                         *
                         *  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.
                         *  \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.
                        #define CDC_DATA_CLASS                  0x0A
                        #define CDC_DATA_SUBCLASS               0x00
                        #define CDC_DATA_PROTOCOL               0x00
                        #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)
 
                /* Function Prototypes: */
                        #if defined(__INCLUDE_FROM_CDC_CLASS_HOST_C)
index bbb32cb..cd22e65 100644 (file)
@@ -40,21 +40,22 @@ uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo
                                 uint16_t ConfigDescriptorSize,
                                 void* ConfigDescriptorData)
 {
                                 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));
        memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
-
+       
        if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
          return HID_ENUMERROR_InvalidConfigDescriptor;
        
        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)
                {
        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);
                }
                
                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)
        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 (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
                                              DCOMP_HID_Host_NextHIDInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
                {
-                       if (FoundEndpoints & HID_FOUND_DATAPIPE_IN)
+                       if (DataINEndpoint || DataOUTEndpoint)
                          break;
                          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)
                }
                
                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->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->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;
                        HIDInterfaceInfo->State.DeviceUsesOUTPipe = true;
-                       
-                       FoundEndpoints |= HID_FOUND_DATAPIPE_OUT;               
                }
        }
                }
        }
-
+       
        HIDInterfaceInfo->State.LargestReportSize = 8;
        HIDInterfaceInfo->State.IsActive = true;
        HIDInterfaceInfo->State.LargestReportSize = 8;
        HIDInterfaceInfo->State.IsActive = true;
+       
        return HID_ENUMERROR_NoError;
 }
 
        return HID_ENUMERROR_NoError;
 }
 
index bbc8f5d..fc9249c 100644 (file)
                        {
                                HID_ENUMERROR_NoError                    = 0, /**< Configuration Descriptor was processed successfully. */
                                HID_ENUMERROR_InvalidConfigDescriptor    = 1, /**< The device returned an invalid Configuration Descriptor. */
                        {
                                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: */
                        };
        
                /* Function Prototypes: */
                         *  device. This should be called once after the stack has enumerated the attached device, while the host state
                         *  machine is in the Addressed state.
                         *
                         *  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.
                         *
                         *  \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.
                         *
        #if !defined(__DOXYGEN__)
                /* Macros: */
                        #define HID_INTERFACE_CLASS             0x03
        #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)
 
                /* Function Prototypes: */
                        #if defined(__INCLUDE_FROM_HID_CLASS_HOST_C)
index fd7f13c..6f34933 100644 (file)
@@ -40,50 +40,72 @@ uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceI
                                  uint16_t ConfigDescriptorSize,
                                  void* ConfigDescriptorData)
 {
                                  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;
 
        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)
        {
        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)
                {
        {
                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)
                }
                
                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->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->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;
        MIDIInterfaceInfo->State.IsActive = true;
+
        return MIDI_ENUMERROR_NoError;
 }
 
        return MIDI_ENUMERROR_NoError;
 }
 
index d5cf582..f71f000 100644 (file)
                                           */
                                struct
                                {
                                           */
                                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. */
 
                                        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. */
                        {
                                MIDI_ENUMERROR_NoError                    = 0, /**< Configuration Descriptor was processed successfully. */
                                MIDI_ENUMERROR_InvalidConfigDescriptor    = 1, /**< The device returned an invalid Configuration Descriptor. */
                        {
                                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: */
                        };
        
                /* Function Prototypes: */
                         *  This should be called once after the stack has enumerated the attached device, while the host state machine is in
                         *  the Addressed state.
                         *
                         *  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.
                         *  \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.
                        #define MIDI_STREAMING_CLASS           0x01
                        #define MIDI_STREAMING_SUBCLASS        0x03
                        #define MIDI_STREAMING_PROTOCOL        0x00
                        #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)
 
                /* Function Prototypes: */
                        #if defined(__INCLUDE_FROM_MIDI_CLASS_HOST_C)
index 0366703..104a358 100644 (file)
 
 uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
                                uint16_t ConfigDescriptorSize,
 
 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));
 
        memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State));
 
-       if (DESCRIPTOR_TYPE(DeviceConfigDescriptor) != DTYPE_Configuration)
+       if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
          return MS_ENUMERROR_InvalidConfigDescriptor;
          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)
 
                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;
        }
 
        MSInterfaceInfo->State.IsActive = true;
+
        return MS_ENUMERROR_NoError;
 }
 
        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)
        {
 {
        if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
        {
@@ -107,7 +127,7 @@ static uint8_t DCOMP_MS_NextMSInterface(void* const CurrentDescriptor)
        return DESCRIPTOR_SEARCH_NotFound;
 }
 
        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)
        {
 {
        if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
        {
index bfbe6cd..606aa79 100644 (file)
                                           */
                                struct
                                {
                                           */
                                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. */
 
                                        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. */
                        {
                                MS_ENUMERROR_NoError                    = 0, /**< Configuration Descriptor was processed successfully. */
                                MS_ENUMERROR_InvalidConfigDescriptor    = 1, /**< The device returned an invalid Configuration Descriptor. */
                        {
                                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: */
                        };
        
                /* Function Prototypes: */
                         *  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.
                         *
                         *  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,
                         *
                         *  \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.
 
                        /** 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.
                        #define COMMAND_DIRECTION_DATA_IN      (1 << 7)
                        
                        #define COMMAND_DATA_TIMEOUT_MS        10000
                        #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)             
                        
                /* 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,
                                
                                static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
                                                                   MS_CommandBlockWrapper_t* const SCSICommandBlock,
index 99977e5..e1c3e15 100644 (file)
@@ -40,8 +40,9 @@ uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceI
                                  uint16_t ConfigDescriptorSize,
                                                             void* DeviceConfigDescriptor)
 {
                                  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)
        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)
        {
        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)
                {
        {
                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)
                }
                
                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;
        }
 
        PRNTInterfaceInfo->State.IsActive = true;
+
        return PRNT_ENUMERROR_NoError;
 }
 
        return PRNT_ENUMERROR_NoError;
 }
 
index 3721608..9848287 100644 (file)
                        {
                                PRNT_ENUMERROR_NoError                    = 0, /**< Configuration Descriptor was processed successfully. */
                                PRNT_ENUMERROR_InvalidConfigDescriptor    = 1, /**< The device returned an invalid Configuration Descriptor. */
                        {
                                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: */
                        };
        
                /* Function Prototypes: */
                         *  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.
                         *
                         *  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.
                         *  \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.
                        #define REQ_GetDeviceID                0
                        #define REQ_GetPortStatus              1
                        #define REQ_SoftReset                  2
                        #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)                
                        
                /* Function Prototypes: */
                        #if defined(__INCLUDE_FROM_PRINTER_CLASS_HOST_C)                
index b3d0f30..f6dcba1 100644 (file)
@@ -40,99 +40,103 @@ uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfa
                                   uint16_t ConfigDescriptorSize,
                                   void* ConfigDescriptorData)
 {
                                   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;
 
        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)
        {
        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 (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
                        {
                        }
                        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,
                                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);
 
                }
                
                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
                {
                }
                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;
                }
        }
 
        RNDISInterfaceInfo->State.IsActive = true;
+
        return RNDIS_ENUMERROR_NoError;
 }
 
        return RNDIS_ENUMERROR_NoError;
 }
 
index df99824..0cb5f46 100644 (file)
                        {
                                RNDIS_ENUMERROR_NoError                    = 0, /**< Configuration Descriptor was processed successfully. */
                                RNDIS_ENUMERROR_InvalidConfigDescriptor    = 1, /**< The device returned an invalid Configuration Descriptor. */
                        {
                                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: */
                        };
 
                /* Macros: */
                         *  This should be called once after the stack has enumerated the attached device, while the host state machine is in
                         *  the Addressed state.
                         *
                         *  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.
                         *  \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.
                        #define RNDIS_DATA_CLASS                  0x0A
                        #define RNDIS_DATA_SUBCLASS               0x00
                        #define RNDIS_DATA_PROTOCOL               0x00
                        #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)
 
                /* Function Prototypes: */
                        #if defined(__INCLUDE_FROM_RNDIS_CLASS_HOST_C)
index 3883d3b..744444d 100644 (file)
 
 uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
                                uint16_t ConfigDescriptorSize,
 
 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));
        
        memset(&SIInterfaceInfo->State, 0x00, sizeof(SIInterfaceInfo->State));
        
-       if (DESCRIPTOR_TYPE(DeviceConfigDescriptor) != DTYPE_Configuration)
+       if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
          return SI_ENUMERROR_InvalidConfigDescriptor;
          return SI_ENUMERROR_InvalidConfigDescriptor;
-       
-       if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
+
+       if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
                                      DCOMP_SI_Host_NextSIInterface) != DESCRIPTOR_SEARCH_COMP_Found)
        {
                                      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)
                {
                                              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
                {
                }
                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;
 }
        SIInterfaceInfo->State.IsActive = true;
        return SI_ENUMERROR_NoError;
 }
index 020f030..319b72a 100644 (file)
                                           */
                                struct
                                {
                                           */
                                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. */
 
                                        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. */
                        {
                                SI_ENUMERROR_NoError                    = 0, /**< Configuration Descriptor was processed successfully. */
                                SI_ENUMERROR_InvalidConfigDescriptor    = 1, /**< The device returned an invalid Configuration Descriptor. */
                        {
                                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.
                                                                              */
                                                                              *   Configuration Descriptor.
                                                                              */
-                               SI_ENUMERROR_EndpointsNotFound          = 3, /**< Compatible Still Image data endpoints were not found in the
-                                                                             *   device's Still Image interface.
-                                                                             */
                        };
 
                /* Function Prototypes: */
                        };
 
                /* Function Prototypes: */
                         *  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.
                         *
                         *  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,
                         *
                         *  \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.
 
                        /** 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.
                        #define STILL_IMAGE_SUBCLASS           0x01
                        #define STILL_IMAGE_PROTOCOL           0x01
 
                        #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: */
                        #define COMMAND_DATA_TIMEOUT_MS        10000
                
                /* Function Prototypes: */
index 78290d7..b5d98c0 100644 (file)
@@ -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;
 
        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;
 
        if (*ConfigSizePtr > BufferSize)
          return HOST_GETCONFIG_BuffOverflow;
index 97ed9e5..9570054 100644 (file)
@@ -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
   *  - 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
   *
   *  <b>Fixed:</b>
   *  - Fixed USB_GetHIDReportItemInfo() function modifying the given report item's data when the report item does not exist
index 7214c7e..78b4d2f 100644 (file)
@@ -50,7 +50,9 @@ uint8_t ProcessConfigurationDescriptor(void)
        uint8_t  ConfigDescriptorData[512];
        void*    CurrConfigLocation = ConfigDescriptorData;
        uint16_t CurrConfigBytesRem;
        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)))
 
        /* 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;
        }
        
                        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 */
        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,
        {
                /* 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 */
                {
                        /* 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;
                          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 */
                }
                
                /* 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)
 
                /* 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
                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;
                        
        /* 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
  */
  *
  *  \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)
 {
        /* Determine the type of the current descriptor */
        if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
index 4df31f1..5cddada 100644 (file)
                /** Interface Class value for the Human Interface Device class. */
                #define HID_CLASS                 0x03
 
                /** 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
        /* Enums: */
                /** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
                enum GenericHIDHost_GetConfigDescriptorDataCodes_t
                        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 */
                        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);
                };      
 
        /* 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
 
 #endif
index 57aae09..6bff6af 100644 (file)
                #include "ConfigDescriptor.h"
                
        /* Macros: */
                #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
 
                /** HID Class specific request to send a HID report to the device. */
                #define REQ_SetReport             0x09