Reverted Endpoint/Pipe non-sequential configuration hack, placed restriction on the configuration order instead to ensure maximum reliability.

Altered all low level device and host mode demos to ensure that endpoints and pipes are configured in ascending order properly.

Rewrote all low level host mode demos' configuration descriptor parser code to ensure that pipes are enumerated in ascending order, and to ensure maximum compatibility with devices.

Incremented all device mode demo's device descriptor revision numbers to ensure that any descriptor changes are re-fetched on machines which have enumerated previous versions.
pull/1469/head
Dean Camera 14 years ago
parent a509729b2d
commit 158afe9109

@ -55,7 +55,7 @@ USB_Descriptor_Device_t DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x204A,
.ReleaseNumber = 0x0001,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = NO_DESCRIPTOR,
.ProductStrIndex = 0x01,

@ -93,20 +93,20 @@
#endif
/** Endpoint number for the CDC control interface event notification endpoint. */
#define CDC_NOTIFICATION_EPNUM 3
/** Size of the CDC control interface notification endpoint bank, in bytes. */
#define CDC_NOTIFICATION_EPSIZE 8
#define CDC_NOTIFICATION_EPNUM 2
/** Endpoint number for the CDC data interface TX (data IN) endpoint. */
#define CDC_TX_EPNUM 1
#define CDC_TX_EPNUM 3
/** Endpoint number for the CDC data interface RX (data OUT) endpoint. */
#define CDC_RX_EPNUM 2
#define CDC_RX_EPNUM 4
/** Size of the CDC data interface TX and RX data endpoint banks, in bytes. */
#define CDC_TXRX_EPSIZE 16
/** Size of the CDC control interface notification endpoint bank, in bytes. */
#define CDC_NOTIFICATION_EPSIZE 8
/* Type Defines: */
/** Type define for a CDC class-specific functional header descriptor. This indicates to the host that the device
* contains one or more CDC functional data descriptors, which give the CDC interface's capabilities and configuration.

@ -55,7 +55,7 @@ USB_Descriptor_Device_t DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = PRODUCT_ID_CODE,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.00),
.ManufacturerStrIndex = NO_DESCRIPTOR,
.ProductStrIndex = 0x01,

@ -55,7 +55,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2047,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -55,7 +55,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2046,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -67,7 +67,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x204E,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -81,7 +81,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x204F,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -91,7 +91,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2043,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -97,7 +97,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2042,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -130,7 +130,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x204D,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -55,7 +55,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2048,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -67,7 +67,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2045,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -110,7 +110,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2061,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -91,7 +91,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2041,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -55,7 +55,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x204C,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -67,7 +67,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2044,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -103,7 +103,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2062,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -43,7 +43,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
VendorID: 0x03EB,
ProductID: 0x2040,
ReleaseNumber: 0x0001,
ReleaseNumber: VERSION_BCD(00.01),
ManufacturerStrIndex: 0x01,
ProductStrIndex: 0x02,

@ -68,7 +68,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2065,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -43,15 +43,15 @@
#include <LUFA/Drivers/USB/USB.h>
/* Macros: */
/** Endpoint number of the TMC notification IN endpoint. */
#define TMC_NOTIFICATION_EPNUM 2
/** Endpoint number of the TMC device-to-host data IN endpoint. */
#define TMC_IN_EPNUM 3
/** Endpoint number of the TMC host-to-device data OUT endpoint. */
#define TMC_OUT_EPNUM 4
/** Endpoint number of the TMC notification IN endpoint. */
#define TMC_NOTIFICATION_EPNUM 2
/** Size in bytes of the TMC data endpoints. */
#define TMC_IO_EPSIZE 64

@ -121,12 +121,12 @@ void EVENT_USB_Device_ConfigurationChanged(void)
bool ConfigSuccess = true;
/* Setup TMC In, Out and Notification Endpoints */
ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
TMC_IO_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_IN_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_IN,
TMC_IO_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_OUT_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_OUT,
TMC_IO_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
TMC_IO_EPSIZE, ENDPOINT_BANK_SINGLE);
/* Indicate endpoint configuration success or failure */
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);

@ -55,7 +55,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2047,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -55,7 +55,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2046,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -67,7 +67,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x204E,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -42,23 +42,23 @@
#include <avr/pgmspace.h>
/* Macros: */
/** Endpoint number of the first CDC interface's device-to-host notification IN endpoint. */
#define CDC1_NOTIFICATION_EPNUM 3
/** Endpoint number of the first CDC interface's device-to-host data IN endpoint. */
#define CDC1_TX_EPNUM 1
/** Endpoint number of the first CDC interface's host-to-device data OUT endpoint. */
#define CDC1_RX_EPNUM 2
/** Endpoint number of the second CDC interface's device-to-host notification IN endpoint. */
#define CDC2_NOTIFICATION_EPNUM 4
/** Endpoint number of the first CDC interface's device-to-host notification IN endpoint. */
#define CDC1_NOTIFICATION_EPNUM 3
/** Endpoint number of the second CDC interface's device-to-host data IN endpoint. */
#define CDC2_TX_EPNUM 5
#define CDC2_TX_EPNUM 4
/** Endpoint number of the second CDC interface's host-to-device data OUT endpoint. */
#define CDC2_RX_EPNUM 6
#define CDC2_RX_EPNUM 5
/** Endpoint number of the second CDC interface's device-to-host notification IN endpoint. */
#define CDC2_NOTIFICATION_EPNUM 6
/** Size in bytes of the CDC device-to-host notification IN endpoints. */
#define CDC_NOTIFICATION_EPSIZE 8

@ -123,20 +123,20 @@ void EVENT_USB_Device_ConfigurationChanged(void)
bool ConfigSuccess = true;
/* Setup first CDC Interface's Endpoints */
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC1_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC1_TX_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_IN,
CDC_TXRX_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC1_RX_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_OUT,
CDC_TXRX_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC1_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
/* Setup second CDC Interface's Endpoints */
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC2_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC2_TX_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_IN,
CDC_TXRX_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC2_RX_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_OUT,
CDC_TXRX_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC2_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
/* Reset line encoding baud rates so that the host knows to send new values */
LineEncoding1.BaudRateBPS = 0;

@ -81,7 +81,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x204F,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -91,7 +91,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2043,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -75,10 +75,10 @@
/* Macros: */
/** Endpoint number of the Joystick HID reporting IN endpoint. */
#define JOYSTICK_EPNUM 1
#define JOYSTICK_EPNUM 1
/** Size in bytes of the Joystick HID reporting IN endpoint. */
#define JOYSTICK_EPSIZE 8
#define JOYSTICK_EPSIZE 8
/** Descriptor header type value, to indicate a HID class HID descriptor. */
#define DTYPE_HID 0x21

@ -98,7 +98,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2042,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -131,7 +131,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x204D,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -55,7 +55,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2048,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),,
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -60,11 +60,11 @@
/** Audio class descriptor jack type value for an external (physical) MIDI input or output jack. */
#define JACKTYPE_EXTERNAL 0x02
/** Endpoint number of the MIDI streaming data OUT endpoint, for host-to-device data transfers. */
#define MIDI_STREAM_OUT_EPNUM 1
/** Endpoint number of the MIDI streaming data IN endpoint, for device-to-host data transfers. */
#define MIDI_STREAM_IN_EPNUM 2
#define MIDI_STREAM_IN_EPNUM 1
/** Endpoint number of the MIDI streaming data OUT endpoint, for host-to-device data transfers. */
#define MIDI_STREAM_OUT_EPNUM 2
/** Endpoint size in bytes of the Audio isochronous streaming data IN and OUT endpoints. */
#define MIDI_STREAM_EPSIZE 64

@ -94,10 +94,10 @@ void EVENT_USB_Device_ConfigurationChanged(void)
bool ConfigSuccess = true;
/* Setup MIDI Data Endpoints */
ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_OUT,
MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_IN,
MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_OUT,
MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
/* Indicate endpoint configuration success or failure */
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);

@ -67,7 +67,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2045,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -91,7 +91,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2041,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -55,7 +55,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x204C,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -42,21 +42,21 @@
#include <avr/pgmspace.h>
/* Macros: */
/** Endpoint number of the CDC device-to-host notification IN endpoint. */
#define CDC_NOTIFICATION_EPNUM 3
/** Endpoint number of the CDC device-to-host data IN endpoint. */
#define CDC_TX_EPNUM 1
/** Endpoint number of the CDC host-to-device data OUT endpoint. */
#define CDC_RX_EPNUM 2
/** Size in bytes of the CDC device-to-host notification IN endpoint. */
#define CDC_NOTIFICATION_EPSIZE 8
/** Endpoint number of the CDC device-to-host notification IN endpoint. */
#define CDC_NOTIFICATION_EPNUM 3
/** Size in bytes of the CDC data IN and OUT endpoints. */
#define CDC_TXRX_EPSIZE 64
/** Size in bytes of the CDC device-to-host notification IN endpoint. */
#define CDC_NOTIFICATION_EPSIZE 8
/* Type Defines: */
/** Type define for a CDC class-specific functional header descriptor. This indicates to the host that the device
* contains one or more CDC functional data descriptors, which give the CDC interface's capabilities and configuration.

@ -67,7 +67,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2044,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -50,7 +50,10 @@ uint8_t ProcessConfigurationDescriptor(void)
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
uint8_t FoundEndpoints = 0;
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
USB_Descriptor_Endpoint_t* EventsEndpoint = NULL;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
@ -62,7 +65,7 @@ uint8_t ProcessConfigurationDescriptor(void)
case HOST_GETCONFIG_BuffOverflow:
return DescriptorTooLarge;
default:
return ControlError;
return DevControlError;
}
/* The Bluetooth USB transport addendum mandates that the data (not streaming voice) endpoints
@ -71,63 +74,48 @@ uint8_t ProcessConfigurationDescriptor(void)
/* Ensure that an interface was found, and the end of the descriptor was not reached */
if (!(CurrConfigBytesRem))
return NoBTInterfaceFound;
return NoCompatibleInterfaceFound;
/* Get the data IN, data OUT and event notification endpoints for the Bluetooth interface */
while (FoundEndpoints != ((1 << BLUETOOTH_DATA_IN_PIPE) | (1 << BLUETOOTH_DATA_OUT_PIPE) |
(1 << BLUETOOTH_EVENTS_PIPE)))
while (!(DataINEndpoint) || !(DataOUTEndpoint))
{
/* Fetch the next endpoint from the current Bluetooth interface */
/* Get the next Still Image interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextInterfaceBluetoothDataEndpoint))
DComp_NextInterfaceBluetoothDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoEndpointFound;
/* Data endpoints not found within the first bluetooth device interface, error out */
return NoCompatibleInterfaceFound;
}
/* Retrieve the endpoint address from the endpoint descriptor */
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Check if the endpoint is a bulk or interrupt type endpoint */
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
/* If the endpoint is a IN type endpoint */
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the events IN pipe */
Pipe_ConfigurePipe(BLUETOOTH_EVENTS_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_SINGLE);
Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
/* Set the flag indicating that the events notification pipe has been found */
FoundEndpoints |= (1 << BLUETOOTH_EVENTS_PIPE);
}
/* Check if the found endpoint is a interrupt or bulk type descriptor */
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
EventsEndpoint = EndpointData;
else
DataINEndpoint = EndpointData;
}
else
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the data IN pipe */
Pipe_ConfigurePipe(BLUETOOTH_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_SINGLE);
/* Set the flag indicating that the data IN pipe has been found */
FoundEndpoints |= (1 << BLUETOOTH_DATA_IN_PIPE);
}
else
{
/* Configure the data OUT pipe */
Pipe_ConfigurePipe(BLUETOOTH_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_SINGLE);
/* Set the flag indicating that the data OUT pipe has been found */
FoundEndpoints |= (1 << BLUETOOTH_DATA_OUT_PIPE);
}
DataOUTEndpoint = EndpointData;
}
}
/* Configure the Bluetooth data IN pipe */
Pipe_ConfigurePipe(BLUETOOTH_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE);
/* Configure the Bluetooth data OUT pipe */
Pipe_ConfigurePipe(BLUETOOTH_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, PIPE_BANK_SINGLE);
/* Configure the Bluetooth events pipe */
Pipe_ConfigurePipe(BLUETOOTH_EVENTS_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EventsEndpoint->EndpointAddress, EventsEndpoint->EndpointSize, PIPE_BANK_SINGLE);
Pipe_SetInterruptPeriod(EventsEndpoint->PollingIntervalMS);
/* Valid data found, return success */
return SuccessfulConfigRead;
@ -146,17 +134,10 @@ uint8_t DComp_NextInterfaceBluetoothDataEndpoint(void* CurrentDescriptor)
{
/* Determine the type of the current descriptor */
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
/* Indicate that the descriptor being searched for has been found */
return DESCRIPTOR_SEARCH_Found;
}
return DESCRIPTOR_SEARCH_Found;
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
/* Indicate that the search has failed prematurely and should be aborted */
return DESCRIPTOR_SEARCH_Fail;
}
/* Current descriptor does not match what this comparator is looking for */
return DESCRIPTOR_SEARCH_NotFound;
return DESCRIPTOR_SEARCH_Fail;
else
return DESCRIPTOR_SEARCH_NotFound;
}

@ -39,7 +39,10 @@
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
#include "BluetoothHost.h"
/* Macros: */
#define BLUETOOTH_DATA_IN_PIPE 1
#define BLUETOOTH_DATA_OUT_PIPE 2
#define BLUETOOTH_EVENTS_PIPE 3
/* Enums: */
/** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
@ -49,10 +52,7 @@
DevControlError = 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 */
NoBTInterfaceFound = 4, /**< A compatible Bluetooth interface was not found in the device's Configuration Descriptor */
NoEndpointFound = 5, /**< A compatible set of Bluetooth endpoints were not found in the
* device's Bluetooth interface
*/
NoCompatibleInterfaceFound = 4, /**< A compatible interface with the required endpoints was not found */
};
/* Function Prototypes: */

@ -39,11 +39,9 @@
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
#include "../ConfigDescriptor.h"
/* Macros: */
#define BLUETOOTH_DATA_IN_PIPE 1
#define BLUETOOTH_DATA_OUT_PIPE 2
#define BLUETOOTH_EVENTS_PIPE 3
#define BLUETOOTH_MAX_OPEN_CHANNELS 6
#define CHANNEL_PSM_SDP 0x0001

@ -50,7 +50,9 @@ uint8_t ProcessConfigurationDescriptor(void)
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
uint8_t FoundEndpoints = 0;
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
@ -65,15 +67,15 @@ uint8_t ProcessConfigurationDescriptor(void)
return ControlError;
}
/* Get the HID interface from the configuration descriptor */
/* Get the first HID interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoHIDInterfaceFound;
return NoCompatibleInterfaceFound;
}
while (FoundEndpoints != ((1 << HID_DATA_IN_PIPE) | (1 << HID_DATA_OUT_PIPE)))
while (!(DataINEndpoint) || !(DataOUTEndpoint))
{
/* Get the next HID interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
@ -81,11 +83,19 @@ uint8_t ProcessConfigurationDescriptor(void)
{
/* Not all HID devices have an OUT endpoint - if we've reached the end of the HID descriptor
* but only found the mandatory IN endpoint, it's safe to continue with the device enumeration */
if (FoundEndpoints == (1 << HID_DATA_IN_PIPE))
if (DataINEndpoint)
break;
/* Descriptor not found, error out */
return NoEndpointFound;
/* Clear any found endpoints */
DataOUTEndpoint = NULL;
/* Get the next HID interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCompatibleInterfaceFound;
}
}
/* Retrieve the endpoint address from the endpoint descriptor */
@ -93,22 +103,23 @@ uint8_t ProcessConfigurationDescriptor(void)
/* If the endpoint is a IN type endpoint */
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the HID data IN pipe */
Pipe_ConfigurePipe(HID_DATA_IN_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
FoundEndpoints |= (1 << HID_DATA_IN_PIPE);
}
DataINEndpoint = EndpointData;
else
{
/* Configure the HID data OUT pipe */
Pipe_ConfigurePipe(HID_DATA_OUT_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
FoundEndpoints |= (1 << HID_DATA_OUT_PIPE);
}
DataOUTEndpoint = EndpointData;
}
/* Configure the HID data IN pipe */
Pipe_ConfigurePipe(HID_DATA_IN_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE);
Pipe_SetInterruptPeriod(DataINEndpoint->PollingIntervalMS);
/* Check if the HID interface contained an optional OUT data endpoint */
if (DataOUTEndpoint)
{
/* Configure the HID data OUT pipe */
Pipe_ConfigurePipe(HID_DATA_OUT_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_OUT,
DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, PIPE_BANK_SINGLE);
}
/* Valid data found, return success */
return SuccessfulConfigRead;

@ -43,7 +43,13 @@
/* Macros: */
/** Interface Class value for the Human Interface Device class. */
#define HID_CLASS 0x03
#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. */
@ -53,8 +59,7 @@
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: */

@ -53,12 +53,6 @@
#include "ConfigDescriptor.h"
/* Macros: */
/** Pipe number for the HID data IN pipe. */
#define HID_DATA_IN_PIPE 1
/** Pipe number for the HID data OUT pipe. */
#define HID_DATA_OUT_PIPE 2
/** HID Class specific request to send a HID report to the device. */
#define REQ_SetReport 0x09

@ -50,6 +50,8 @@ uint8_t ProcessConfigurationDescriptor(void)
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
@ -63,41 +65,43 @@ uint8_t ProcessConfigurationDescriptor(void)
default:
return ControlError;
}
/* Get the joystick interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextJoystickInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoHIDInterfaceFound;
}
/* Get the joystick interface's HID descriptor */
/* Get the first HID interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)
DComp_NextJoystickInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoHIDDescriptorFound;
return NoCompatibleInterfaceFound;
}
/* Save the HID report size for later use */
HIDReportSize = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_HID_t).HIDReportLength;
/* Get the joystick interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextJoystickInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
while (!(DataINEndpoint))
{
/* Descriptor not found, error out */
return NoEndpointFound;
/* Get the next HID interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextJoystickInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Get the next HID interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextJoystickInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCompatibleInterfaceFound;
}
}
/* Retrieve the endpoint address from the endpoint descriptor */
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)
DataINEndpoint = EndpointData;
}
/* Retrieve the endpoint address from the endpoint descriptor */
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Configure the joystick data pipe */
Pipe_ConfigurePipe(JOYSTICK_DATAPIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
/* Configure the HID data IN pipe */
Pipe_ConfigurePipe(JOYSTICK_DATA_IN_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE);
Pipe_SetInterruptPeriod(DataINEndpoint->PollingIntervalMS);
/* Valid data found, return success */
return SuccessfulConfigRead;
}

@ -54,6 +54,9 @@
/** Descriptor header type constant for a HID report descriptor. */
#define DTYPE_Report 0x22
/** Pipe number for the joystick report data pipe. */
#define JOYSTICK_DATA_IN_PIPE 1
/* Enums: */
/** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
enum JoystickHostWithParser_GetConfigDescriptorDataCodes_t
@ -64,7 +67,7 @@
InvalidConfigDataReturned = 3, /**< The device returned an invalid Configuration Descriptor */
NoHIDInterfaceFound = 4, /**< A compatible HID interface was not found in the device's Configuration Descriptor */
NoHIDDescriptorFound = 5, /**< A compatible HID descriptor was not found in the device's HID interface */
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: */

@ -211,7 +211,7 @@ void Joystick_HID_Task(void)
break;
case HOST_STATE_Configured:
/* Select and unfreeze joystick data pipe */
Pipe_SelectPipe(JOYSTICK_DATAPIPE);
Pipe_SelectPipe(JOYSTICK_DATA_IN_PIPE);
Pipe_Unfreeze();
/* Check to see if a packet has been received */

@ -54,9 +54,6 @@
#include "HIDReport.h"
/* Macros: */
/** Pipe number for the joystick report data pipe. */
#define JOYSTICK_DATAPIPE 1
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1

@ -50,6 +50,8 @@ uint8_t ProcessConfigurationDescriptor(void)
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
@ -64,28 +66,41 @@ uint8_t ProcessConfigurationDescriptor(void)
return ControlError;
}
/* Get the keyboard interface from the configuration descriptor */
/* Get the first HID interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextKeyboardInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoHIDInterfaceFound;
return NoCompatibleInterfaceFound;
}
/* Get the keyboard interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextKeyboardInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
while (!(DataINEndpoint))
{
/* Descriptor not found, error out */
return NoEndpointFound;
/* Get the next HID interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextKeyboardInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Get the next HID interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextKeyboardInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCompatibleInterfaceFound;
}
}
/* Retrieve the endpoint address from the endpoint descriptor */
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)
DataINEndpoint = EndpointData;
}
/* Retrieve the endpoint address from the endpoint descriptor */
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Configure the keyboard data pipe */
Pipe_ConfigurePipe(KEYBOARD_DATAPIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
/* Configure the HID data IN pipe */
Pipe_ConfigurePipe(KEYBOARD_DATA_IN_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE);
Pipe_SetInterruptPeriod(DataINEndpoint->PollingIntervalMS);
/* Valid data found, return success */
return SuccessfulConfigRead;

@ -48,6 +48,9 @@
/** Interface Protocol value for a Boot Protocol Keyboard compliant device. */
#define KEYBOARD_PROTOCOL 0x01
/** Pipe number for the keyboard data IN pipe. */
#define KEYBOARD_DATA_IN_PIPE 1
/* Enums: */
/** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
enum KeyboardHost_GetConfigDescriptorDataCodes_t
@ -56,8 +59,7 @@
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: */

@ -131,7 +131,7 @@ void ReadNextReport(void)
USB_KeyboardReport_Data_t KeyboardReport;
/* Select keyboard data pipe */
Pipe_SelectPipe(KEYBOARD_DATAPIPE);
Pipe_SelectPipe(KEYBOARD_DATA_IN_PIPE);
/* Unfreeze keyboard data pipe */
Pipe_Unfreeze();

@ -53,9 +53,6 @@
#include "ConfigDescriptor.h"
/* Macros: */
/** Pipe number for the keyboard data IN pipe. */
#define KEYBOARD_DATAPIPE 1
/** HID Class Specific request to set the report protocol mode. */
#define REQ_SetProtocol 0x0B

@ -50,6 +50,8 @@ uint8_t ProcessConfigurationDescriptor(void)
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
@ -64,39 +66,63 @@ uint8_t ProcessConfigurationDescriptor(void)
return ControlError;
}
/* Get the keyboard interface from the configuration descriptor */
/* Get the first HID interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextKeyboardInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoHIDInterfaceFound;
return NoCompatibleInterfaceFound;
}
/* Get the keyboard interface's HID descriptor */
/* Get the HID descriptor from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoHIDDescriptorFound;
return NoCompatibleInterfaceFound;
}
/* Save the HID report size for later use */
HIDReportSize = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_HID_t).HIDReportLength;
/* Get the keyboard interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextKeyboardInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
while (!(DataINEndpoint))
{
/* Descriptor not found, error out */
return NoEndpointFound;
/* Get the next HID interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextKeyboardInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Get the next HID interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextKeyboardInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCompatibleInterfaceFound;
}
/* Get the HID descriptor from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCompatibleInterfaceFound;
}
/* Save the HID report size for later use */
HIDReportSize = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_HID_t).HIDReportLength;
}
/* Retrieve the endpoint address from the endpoint descriptor */
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)
DataINEndpoint = EndpointData;
}
/* Retrieve the endpoint address from the endpoint descriptor */
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Configure the keyboard data pipe */
Pipe_ConfigurePipe(KEYBOARD_DATAPIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
/* Configure the HID data IN pipe */
Pipe_ConfigurePipe(KEYBOARD_DATA_IN_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE);
Pipe_SetInterruptPeriod(DataINEndpoint->PollingIntervalMS);
/* Valid data found, return success */
return SuccessfulConfigRead;
@ -161,6 +187,8 @@ uint8_t DComp_NextHID(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_HID)
return DESCRIPTOR_SEARCH_Found;
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
return DESCRIPTOR_SEARCH_Fail;
else
return DESCRIPTOR_SEARCH_NotFound;
return DESCRIPTOR_SEARCH_NotFound;
}

@ -54,6 +54,9 @@
/** Descriptor header type constant for a HID report descriptor. */
#define DTYPE_Report 0x22
/** Pipe number for the keyboard report data pipe. */
#define KEYBOARD_DATA_IN_PIPE 1
/* Enums: */
/** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
enum KeyboardHostWithParser_GetConfigDescriptorDataCodes_t
@ -62,9 +65,7 @@
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 */
NoHIDDescriptorFound = 5, /**< A compatible HID descriptor was not found in the device's HID interface */
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: */

@ -212,7 +212,7 @@ void Keyboard_HID_Task(void)
break;
case HOST_STATE_Configured:
/* Select and unfreeze keyboard data pipe */
Pipe_SelectPipe(KEYBOARD_DATAPIPE);
Pipe_SelectPipe(KEYBOARD_DATA_IN_PIPE);
Pipe_Unfreeze();
/* Check to see if a packet has been received */

@ -49,9 +49,6 @@
#include "HIDReport.h"
/* Macros: */
/** Pipe number for the keyboard report data pipe. */
#define KEYBOARD_DATAPIPE 1
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1

@ -50,7 +50,9 @@ uint8_t ProcessConfigurationDescriptor(void)
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
uint8_t FoundEndpoints = 0;
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
@ -65,47 +67,50 @@ uint8_t ProcessConfigurationDescriptor(void)
return ControlError;
}
/* Get the MIDI Audio Streaming interface from the configuration descriptor */
/* Get the first MIDI interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMIDIStreamingInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCDCInterfaceFound;
return NoCompatibleInterfaceFound;
}
/* Get the IN and OUT data endpoints for the MIDI interface */
while (FoundEndpoints != ((1 << MIDI_DATAPIPE_IN) | (1 << MIDI_DATAPIPE_OUT)))
while (!(DataINEndpoint) || !(DataOUTEndpoint))
{
/* Fetch the next bulk endpoint from the current MIDI streaming interface */
/* Get the next MIDI interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMIDIStreamingDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoEndpointFound;
/* Clear any found endpoints */
DataINEndpoint = NULL;
DataOUTEndpoint = NULL;
/* Get the next Mass Storage interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMIDIStreamingInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCompatibleInterfaceFound;
}
}
/* Retrieve the endpoint address from the endpoint descriptor */
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Check if the endpoint is a bulk IN or bulk OUT endpoint */
/* If the endpoint is a IN type endpoint */
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the data IN pipe */
Pipe_ConfigurePipe(MIDI_DATAPIPE_IN, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
/* Set the flag indicating that the data IN pipe has been found */
FoundEndpoints |= (1 << MIDI_DATAPIPE_IN);
}
DataINEndpoint = EndpointData;
else
{
/* Configure the data OUT pipe */
Pipe_ConfigurePipe(MIDI_DATAPIPE_OUT, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
/* Set the flag indicating that the data OUT pipe has been found */
FoundEndpoints |= (1 << MIDI_DATAPIPE_OUT);
}
DataOUTEndpoint = EndpointData;
}
/* Configure the MIDI data IN pipe */
Pipe_ConfigurePipe(MIDI_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE);
/* Configure the MIDI data OUT pipe */
Pipe_ConfigurePipe(MIDI_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, PIPE_BANK_SINGLE);
/* Valid data found, return success */
return SuccessfulConfigRead;

@ -51,6 +51,12 @@
/** Interface Class value for the MIDI Audio Streaming protocol. */
#define MIDI_STREAMING_PROTOCOL 0x00
/** Pipe number for the MIDI data IN pipe. */
#define MIDI_DATA_IN_PIPE 1
/** Pipe number for the MIDI data OUT pipe. */
#define MIDI_DATA_OUT_PIPE 2
/* Enums: */
/** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
enum MIDIHost_GetConfigDescriptorDataCodes_t
@ -59,8 +65,7 @@
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 */
NoCDCInterfaceFound = 4, /**< A compatible CDC interface was not found in the device's Configuration Descriptor */
NoEndpointFound = 5, /**< Compatible CDC endpoints were not found in the device's CDC interface */
NoCompatibleInterfaceFound = 4, /**< A compatible interface with the required endpoints was not found */
};
/* Function Prototypes: */

@ -175,7 +175,7 @@ void MIDI_Host_Task(void)
USB_HostState = HOST_STATE_Configured;
break;
case HOST_STATE_Configured:
Pipe_SelectPipe(MIDI_DATAPIPE_IN);
Pipe_SelectPipe(MIDI_DATA_IN_PIPE);
if (Pipe_IsINReceived())
{
@ -196,7 +196,7 @@ void MIDI_Host_Task(void)
Pipe_ClearIN();
}
Pipe_SelectPipe(MIDI_DATAPIPE_OUT);
Pipe_SelectPipe(MIDI_DATA_OUT_PIPE);
static uint8_t PrevJoystickStatus;

@ -71,12 +71,6 @@
*/
#define MIDI_CHANNEL(channel) (channel - 1)
/** Pipe number for the MIDI data IN pipe. */
#define MIDI_DATAPIPE_IN 1
/** Pipe number for the MIDI data OUT pipe. */
#define MIDI_DATAPIPE_OUT 2
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1

@ -50,7 +50,9 @@ uint8_t ProcessConfigurationDescriptor(void)
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
uint8_t FoundEndpoints = 0;
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
@ -65,49 +67,50 @@ uint8_t ProcessConfigurationDescriptor(void)
return ControlError;
}
/* Get the mass storage interface from the configuration descriptor */
/* Get the first Mass Storage interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoInterfaceFound;
return NoCompatibleInterfaceFound;
}
/* Get the IN and OUT data endpoints for the mass storage interface */
while (FoundEndpoints != ((1 << MASS_STORE_DATA_IN_PIPE) | (1 << MASS_STORE_DATA_OUT_PIPE)))
while (!(DataINEndpoint) || !(DataOUTEndpoint))
{
/* Fetch the next bulk endpoint from the current mass storage interface */
/* Get the next Mass Storage interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMSInterfaceBulkDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoEndpointFound;
/* Clear any found endpoints */
DataINEndpoint = NULL;
DataOUTEndpoint = NULL;
/* Get the next Mass Storage interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCompatibleInterfaceFound;
}
}
/* Retrieve the endpoint address from the endpoint descriptor */
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Check if the endpoint is a bulk IN or bulk OUT endpoint, set appropriate globals */
/* If the endpoint is a IN type endpoint */
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the data IN pipe */
Pipe_ConfigurePipe(MASS_STORE_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_DOUBLE);
/* Set the flag indicating that the data IN pipe has been found */
FoundEndpoints |= (1 << MASS_STORE_DATA_IN_PIPE);
}
DataINEndpoint = EndpointData;
else
{
/* Configure the data OUT pipe */
Pipe_ConfigurePipe(MASS_STORE_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_DOUBLE);
/* Set the flag indicating that the data OUT pipe has been found */
FoundEndpoints |= (1 << MASS_STORE_DATA_OUT_PIPE);
}
DataOUTEndpoint = EndpointData;
}
/* Configure the Mass Storage data IN pipe */
Pipe_ConfigurePipe(MASS_STORE_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE);
/* Configure the Mass Storage data OUT pipe */
Pipe_ConfigurePipe(MASS_STORE_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, PIPE_BANK_SINGLE);
/* Valid data found, return success */
return SuccessfulConfigRead;

@ -51,6 +51,12 @@
/** Interface Protocol value for the Bulk Only transport protocol. */
#define MASS_STORE_PROTOCOL 0x50
/** Pipe number of the Mass Storage data IN pipe. */
#define MASS_STORE_DATA_IN_PIPE 1
/** Pipe number of the Mass Storage data OUT pipe. */
#define MASS_STORE_DATA_OUT_PIPE 2
/* Enums: */
/** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
enum MassStorageHost_GetConfigDescriptorDataCodes_t
@ -59,8 +65,7 @@
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 */
NoInterfaceFound = 4, /**< A compatible MSD interface was not found in the device's Configuration Descriptor */
NoEndpointFound = 5, /**< The correct MSD endpoint descriptors were not found in the device's MSD interface */
NoCompatibleInterfaceFound = 4, /**< A compatible interface with the required endpoints was not found */
};
/* Function Prototypes: */

@ -65,12 +65,6 @@
/** Timeout period between the issuing of a CBW to a device, and the reception of the first packet. */
#define COMMAND_DATA_TIMEOUT_MS 10000
/** Pipe number of the Mass Storage data IN pipe. */
#define MASS_STORE_DATA_IN_PIPE 1
/** Pipe number of the Mass Storage data OUT pipe. */
#define MASS_STORE_DATA_OUT_PIPE 2
/** Additional error code for Mass Storage functions when a device returns a logical command failure. */
#define MASS_STORE_SCSI_COMMAND_FAILED 0xC0

@ -50,6 +50,8 @@ uint8_t ProcessConfigurationDescriptor(void)
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
@ -64,29 +66,42 @@ uint8_t ProcessConfigurationDescriptor(void)
return ControlError;
}
/* Get the mouse interface from the configuration descriptor */
/* Get the first HID interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMouseInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoHIDInterfaceFound;
return NoCompatibleInterfaceFound;
}
/* Get the mouse interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMouseInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
while (!(DataINEndpoint))
{
/* Descriptor not found, error out */
return NoEndpointFound;
/* Get the next HID interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMouseInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Get the next HID interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMouseInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCompatibleInterfaceFound;
}
}
/* Retrieve the endpoint address from the endpoint descriptor */
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)
DataINEndpoint = EndpointData;
}
/* Retrieve the endpoint address from the endpoint descriptor */
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Configure the mouse data pipe */
Pipe_ConfigurePipe(MOUSE_DATAPIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
/* Configure the HID data IN pipe */
Pipe_ConfigurePipe(MOUSE_DATA_IN_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE);
Pipe_SetInterruptPeriod(DataINEndpoint->PollingIntervalMS);
/* Valid data found, return success */
return SuccessfulConfigRead;
}

@ -48,6 +48,9 @@
/** Interface Protocol value for a Boot Protocol Mouse compliant device. */
#define MOUSE_PROTOCOL 0x02
/** Pipe number for the mouse data IN pipe. */
#define MOUSE_DATA_IN_PIPE 1
/* Enums: */
/** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
enum MouseHost_GetConfigDescriptorDataCodes_t
@ -56,8 +59,7 @@
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: */

@ -132,7 +132,7 @@ void ReadNextReport(void)
uint8_t LEDMask = LEDS_NO_LEDS;
/* Select mouse data pipe */
Pipe_SelectPipe(MOUSE_DATAPIPE);
Pipe_SelectPipe(MOUSE_DATA_IN_PIPE);
/* Unfreeze keyboard data pipe */
Pipe_Unfreeze();

@ -53,9 +53,6 @@
#include "ConfigDescriptor.h"
/* Macros: */
/** Pipe number for the mouse data IN pipe. */
#define MOUSE_DATAPIPE 1
/** HID Class Specific request to set the report protocol mode. */
#define REQ_SetProtocol 0x0B

@ -50,6 +50,8 @@ uint8_t ProcessConfigurationDescriptor(void)
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
@ -63,40 +65,64 @@ uint8_t ProcessConfigurationDescriptor(void)
default:
return ControlError;
}
/* Get the mouse interface from the configuration descriptor */
/* Get the first HID interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMouseInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoHIDInterfaceFound;
return NoCompatibleInterfaceFound;
}
/* Get the mouse interface's HID descriptor */
/* Get the HID descriptor from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoHIDDescriptorFound;
return NoCompatibleInterfaceFound;
}
/* Save the HID report size for later use */
HIDReportSize = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_HID_t).HIDReportLength;
/* Get the mouse interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMouseInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
while (!(DataINEndpoint))
{
/* Descriptor not found, error out */
return NoEndpointFound;
/* Get the next HID interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMouseInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Get the next HID interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextMouseInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCompatibleInterfaceFound;
}
/* Get the HID descriptor from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCompatibleInterfaceFound;
}
/* Save the HID report size for later use */
HIDReportSize = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_HID_t).HIDReportLength;
}
/* Retrieve the endpoint address from the endpoint descriptor */
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)
DataINEndpoint = EndpointData;
}
/* Retrieve the endpoint address from the endpoint descriptor */
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Configure the mouse data pipe */
Pipe_ConfigurePipe(MOUSE_DATAPIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
/* Configure the HID data IN pipe */
Pipe_ConfigurePipe(MOUSE_DATA_IN_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE);
Pipe_SetInterruptPeriod(DataINEndpoint->PollingIntervalMS);
/* Valid data found, return success */
return SuccessfulConfigRead;

@ -53,6 +53,9 @@
/** Descriptor header type constant for a HID report descriptor. */
#define DTYPE_Report 0x22
/** Pipe number for the mouse report data pipe. */
#define MOUSE_DATA_IN_PIPE 1
/* Enums: */
/** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
@ -62,9 +65,7 @@
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 */
NoHIDDescriptorFound = 5, /**< A compatible HID descriptor was not found in the device's HID interface */
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: */

@ -212,7 +212,7 @@ void Mouse_HID_Task(void)
break;
case HOST_STATE_Configured:
/* Select and unfreeze mouse data pipe */
Pipe_SelectPipe(MOUSE_DATAPIPE);
Pipe_SelectPipe(MOUSE_DATA_IN_PIPE);
Pipe_Unfreeze();
/* Check to see if a packet has been received */

@ -54,9 +54,6 @@
#include "HIDReport.h"
/* Macros: */
/** Pipe number for the mouse report data pipe. */
#define MOUSE_DATAPIPE 1
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1

@ -49,7 +49,9 @@ uint8_t ProcessConfigurationDescriptor(void)
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
uint8_t FoundEndpoints = 0;
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
@ -64,52 +66,58 @@ uint8_t ProcessConfigurationDescriptor(void)
return ControlError;
}
/* Get the printer interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextBidirectionalPrinterInterface))
/* Get the first Printer interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextBidirectionalPrinterInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoInterfaceFound;
return NoCompatibleInterfaceFound;
}
/* 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;
/* Get the IN and OUT data endpoints for the printer interface */
while (FoundEndpoints != ((1 << PRINTER_DATA_OUT_PIPE) | (1 << PRINTER_DATA_IN_PIPE)))
while (!(DataINEndpoint) || !(DataOUTEndpoint))
{
/* Fetch the next bulk endpoint from the current printer interface */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextPrinterInterfaceBulkDataEndpoint))
/* Get the next Printer interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextPrinterInterfaceBulkDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoEndpointFound;
/* Clear any found endpoints */
DataINEndpoint = NULL;
DataOUTEndpoint = NULL;
/* Get the next Printer interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextBidirectionalPrinterInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCompatibleInterfaceFound;
}
/* 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;
}
/* Retrieve the endpoint address from the endpoint descriptor */
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Check if the endpoint is a bulk IN or bulk OUT endpoint, set appropriate globals */
/* If the endpoint is a IN type endpoint */
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the data IN pipe */
Pipe_ConfigurePipe(PRINTER_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_SINGLE);
Pipe_SetInfiniteINRequests();
/* Set the flag indicating that the data IN pipe has been found */
FoundEndpoints |= (1 << PRINTER_DATA_IN_PIPE);
}
DataINEndpoint = EndpointData;
else
{
/* Configure the data OUT pipe */
Pipe_ConfigurePipe(PRINTER_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_SINGLE);
/* Set the flag indicating that the data OUT pipe has been found */
FoundEndpoints |= (1 << PRINTER_DATA_OUT_PIPE);
}
DataOUTEndpoint = EndpointData;
}
/* Configure the Printer data IN pipe */
Pipe_ConfigurePipe(PRINTER_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE);
/* Configure the Printer data OUT pipe */
Pipe_ConfigurePipe(PRINTER_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, PIPE_BANK_SINGLE);
/* Valid data found, return success */
return SuccessfulConfigRead;

@ -47,6 +47,12 @@
/** Interface Protocol value for a Bidirectional communication encapsulation. */
#define PRINTER_PROTOCOL 0x02
/** Pipe number of the Printer data IN pipe. */
#define PRINTER_DATA_IN_PIPE 1
/** Pipe number of the Printer data OUT pipe. */
#define PRINTER_DATA_OUT_PIPE 2
/* Enums: */
/** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
enum PrinterHost_GetConfigDescriptorDataCodes_t
@ -55,8 +61,7 @@
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 */
NoInterfaceFound = 4, /**< A compatible printer interface was not found in the device's Configuration Descriptor */
NoEndpointFound = 5, /**< The printer data endpoints were not found in the device's Configuration Descriptor */
NoCompatibleInterfaceFound = 4, /**< A compatible interface with the required endpoints was not found */
};
/* External Variables: */

@ -53,12 +53,6 @@
/** Printer class-specific request to soft-reset the device. */
#define REQ_SoftReset 2
/** Pipe number of the Printer data IN pipe. */
#define PRINTER_DATA_IN_PIPE 1
/** Pipe number of the Printer data OUT pipe. */
#define PRINTER_DATA_OUT_PIPE 2
/* Function Prototypes: */
uint8_t Printer_SendData(const void* const PrinterCommands,

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

@ -60,6 +60,15 @@
/** Interface Class value for the CDC data protocol. */
#define CDC_DATA_PROTOCOL 0x00
/** Pipe number for the RNDIS data IN pipe. */
#define RNDIS_DATA_IN_PIPE 1
/** Pipe number for the RNDIS data OUT pipe. */
#define RNDIS_DATA_OUT_PIPE 2
/** Pipe number for the RNDIS notification pipe. */
#define RNDIS_NOTIFICATION_PIPE 3
/* Enums: */
/** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
enum RNDISHost_GetConfigDescriptorDataCodes_t
@ -68,8 +77,7 @@
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 */
NoRNDISInterfaceFound = 4, /**< A compatible RNDIS interface was not found in the device's Configuration Descriptor */
NoEndpointFound = 5, /**< Compatible RNDIS endpoints were not found in the device's RNDIS interface */
NoCompatibleInterfaceFound = 4, /**< A compatible interface with the required endpoints was not found */
};
/* Function Prototypes: */

@ -281,7 +281,7 @@ uint8_t RNDIS_GetPacketLength(uint16_t* const PacketLength)
{
uint8_t ErrorCode;
Pipe_SelectPipe(RNDIS_DATAPIPE_IN);
Pipe_SelectPipe(RNDIS_DATA_IN_PIPE);
Pipe_SetPipeToken(PIPE_TOKEN_IN);
Pipe_Unfreeze();

@ -44,6 +44,7 @@
#include <LUFA/Drivers/USB/USB.h>
#include "RNDISConstants.h"
#include "../RNDISEthernetHost.h"
/* Type Defines: */
/** Type define for a RNDIS message header, sent before RNDIS messages. */
@ -186,15 +187,6 @@
/** Implemented RNDIS Version Minor. */
#define REMOTE_NDIS_VERSION_MINOR 0x00
/** Pipe number for the RNDIS data IN pipe. */
#define RNDIS_DATAPIPE_IN 1
/** Pipe number for the RNDIS data OUT pipe. */
#define RNDIS_DATAPIPE_OUT 2
/** Pipe number for the RNDIS notification pipe. */
#define RNDIS_NOTIFICATIONPIPE 3
/** Additional error code for RNDIS functions when a device returns a logical command failure. */
#define RNDIS_COMMAND_FAILED 0xC0

@ -50,7 +50,10 @@ uint8_t ProcessConfigurationDescriptor(void)
uint8_t ConfigDescriptorData[512];
void* CurrConfigLocation = ConfigDescriptorData;
uint16_t CurrConfigBytesRem;
uint8_t FoundEndpoints = 0;
USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
USB_Descriptor_Endpoint_t* EventsEndpoint = NULL;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
@ -65,69 +68,64 @@ uint8_t ProcessConfigurationDescriptor(void)
return ControlError;
}
/* Get the Still Image interface from the configuration descriptor */
/* Get the first Still Image interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextStillImageInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoInterfaceFound;
return NoCompatibleInterfaceFound;
}
/* Get the IN and OUT data and event endpoints for the Still Image interface */
while (FoundEndpoints != ((1 << SIMAGE_EVENTS_PIPE) | (1 << SIMAGE_DATA_IN_PIPE) | (1 << SIMAGE_DATA_OUT_PIPE)))
while (!(DataINEndpoint) || !(DataOUTEndpoint))
{
/* Fetch the next endpoint from the current Still Image interface */
/* Get the next Still Image interface's data endpoint descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextStillImageInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoEndpointFound;
/* Clear any found endpoints */
DataINEndpoint = NULL;
DataOUTEndpoint = NULL;
EventsEndpoint = NULL;
/* Get the next Still Image interface from the configuration descriptor */
if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
DComp_NextStillImageInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Descriptor not found, error out */
return NoCompatibleInterfaceFound;
}
}
/* Retrieve the endpoint address from the endpoint descriptor */
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
/* Check if the found endpoint is a interrupt or bulk type descriptor */
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
/* If the endpoint is a IN type endpoint */
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* If the endpoint is a IN type interrupt endpoint */
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the events pipe */
Pipe_ConfigurePipe(SIMAGE_EVENTS_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_DOUBLE);
Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
/* Set the flag indicating that the events pipe has been found */
FoundEndpoints |= (1 << SIMAGE_EVENTS_PIPE);
}
/* Check if the found endpoint is a interrupt or bulk type descriptor */
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
EventsEndpoint = EndpointData;
else
DataINEndpoint = EndpointData;
}
else
{
/* Check if the endpoint is a bulk IN or bulk OUT endpoint */
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
/* Configure the data IN pipe */
Pipe_ConfigurePipe(SIMAGE_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_DOUBLE);
/* Set the flag indicating that the data IN pipe has been found */
FoundEndpoints |= (1 << SIMAGE_DATA_IN_PIPE);
}
else
{
/* Configure the data OUT pipe */
Pipe_ConfigurePipe(SIMAGE_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
PIPE_BANK_DOUBLE);
/* Set the flag indicating that the data OUT pipe has been found */
FoundEndpoints |= (1 << SIMAGE_DATA_OUT_PIPE);
}
DataOUTEndpoint = EndpointData;
}
}
/* Configure the Still Image data IN pipe */
Pipe_ConfigurePipe(SIMAGE_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN,
DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE);
/* Configure the Still Image data OUT pipe */
Pipe_ConfigurePipe(SIMAGE_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT,
DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, PIPE_BANK_SINGLE);
/* Configure the Still Image events pipe */
Pipe_ConfigurePipe(SIMAGE_EVENTS_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EventsEndpoint->EndpointAddress, EventsEndpoint->EndpointSize, PIPE_BANK_SINGLE);
Pipe_SetInterruptPeriod(EventsEndpoint->PollingIntervalMS);
/* Valid data found, return success */
return SuccessfulConfigRead;

@ -51,6 +51,15 @@
/** Interface Class value for the Still Image Device protocol. */
#define SIMAGE_PROTOCOL 0x01
/** Pipe number of the Still Image data IN pipe. */
#define SIMAGE_DATA_IN_PIPE 1
/** Pipe number of the Still Image data OUT pipe. */
#define SIMAGE_DATA_OUT_PIPE 2
/** Pipe number of the Still Image events pipe. */
#define SIMAGE_EVENTS_PIPE 3
/* Enums: */
/** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
enum StillImageHost_GetConfigDescriptorDataCodes_t
@ -59,8 +68,7 @@
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 */
NoInterfaceFound = 4, /**< A compatible SI interface was not found in the device's Configuration Descriptor */
NoEndpointFound = 5, /**< The correct SI endpoint descriptors were not found in the device's SI interface */
NoCompatibleInterfaceFound = 4, /**< A compatible interface with the required endpoints was not found */
};
/* Function Prototypes: */

@ -40,17 +40,9 @@
#include <LUFA/Drivers/USB/USB.h>
#include "PIMACodes.h"
#include "../StillImageHost.h"
/* Macros: */
/** Pipe number of the Still Image data IN pipe. */
#define SIMAGE_DATA_IN_PIPE 0x01
/** Pipe number of the Still Image data OUT pipe. */
#define SIMAGE_DATA_OUT_PIPE 0x02
/** Pipe number of the Still Image events pipe. */
#define SIMAGE_EVENTS_PIPE 0x03
/* Macros: */
/** Length in bytes of a given Unicode string's character length.
*
* \param[in] chars Total number of Unicode characters in the string

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

@ -60,6 +60,15 @@
/** Interface Class value for the CDC data protocol. */
#define CDC_DATA_PROTOCOL 0x00
/** Pipe number for the CDC data IN pipe. */
#define CDC_DATA_IN_PIPE 1
/** Pipe number for the CDC data OUT pipe. */
#define CDC_DATA_OUT_PIPE 2
/** Pipe number for the CDC notification pipe. */
#define CDC_NOTIFICATION_PIPE 3
/* Enums: */
/** Enum for the possible return codes of the \ref ProcessConfigurationDescriptor() function. */
enum CDCHost_GetConfigDescriptorDataCodes_t
@ -68,8 +77,7 @@
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 */
NoCDCInterfaceFound = 4, /**< A compatible CDC interface was not found in the device's Configuration Descriptor */
NoEndpointFound = 5, /**< Compatible CDC endpoints were not found in the device's CDC interface */
NoCompatibleInterfaceFound = 4, /**< A compatible interface with the required endpoints was not found */
};
/* Function Prototypes: */

@ -173,7 +173,7 @@ void CDC_Host_Task(void)
break;
case HOST_STATE_Configured:
/* Select the data IN pipe */
Pipe_SelectPipe(CDC_DATAPIPE_IN);
Pipe_SelectPipe(CDC_DATA_IN_PIPE);
Pipe_Unfreeze();
/* Check to see if a packet has been received */
@ -205,7 +205,7 @@ void CDC_Host_Task(void)
Pipe_Freeze();
/* Select and unfreeze the notification pipe */
Pipe_SelectPipe(CDC_NOTIFICATIONPIPE);
Pipe_SelectPipe(CDC_NOTIFICATION_PIPE);
Pipe_Unfreeze();
/* Check if a packet has been received */

@ -53,15 +53,6 @@
#include "ConfigDescriptor.h"
/* Macros: */
/** Pipe number for the CDC data IN pipe. */
#define CDC_DATAPIPE_IN 1
/** Pipe number for the CDC data OUT pipe. */
#define CDC_DATAPIPE_OUT 2
/** Pipe number for the CDC notification pipe. */
#define CDC_NOTIFICATIONPIPE 3
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1

@ -62,21 +62,30 @@ bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioIn
{
memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State));
if (AudioInterfaceInfo->Config.DataINEndpointNumber)
for (uint8_t EndpointNum = 1; EndpointNum < ENDPOINT_TOTAL_ENDPOINTS; EndpointNum++)
{
if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_ISOCHRONOUS,
ENDPOINT_DIR_IN, AudioInterfaceInfo->Config.DataINEndpointSize,
ENDPOINT_BANK_DOUBLE)))
uint16_t Size;
uint8_t Type;
uint8_t Direction;
if (EndpointNum == AudioInterfaceInfo->Config.DataINEndpointNumber)
{
return false;
Size = AudioInterfaceInfo->Config.DataINEndpointSize;
Direction = ENDPOINT_DIR_IN;
Type = EP_TYPE_ISOCHRONOUS;
}
}
if (AudioInterfaceInfo->Config.DataOUTEndpointNumber)
{
if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_ISOCHRONOUS,
ENDPOINT_DIR_OUT, AudioInterfaceInfo->Config.DataOUTEndpointSize,
ENDPOINT_BANK_DOUBLE)))
else if (EndpointNum == AudioInterfaceInfo->Config.DataOUTEndpointNumber)
{
Size = AudioInterfaceInfo->Config.DataOUTEndpointSize;
Direction = ENDPOINT_DIR_OUT;
Type = EP_TYPE_ISOCHRONOUS;
}
else
{
continue;
}
if (!(Endpoint_ConfigureEndpoint(EndpointNum, Type, Direction, Size, ENDPOINT_BANK_DOUBLE)))
{
return false;
}

@ -100,27 +100,46 @@ bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfac
{
memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State));
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_IN, CDCInterfaceInfo->Config.DataINEndpointSize,
CDCInterfaceInfo->Config.DataINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
for (uint8_t EndpointNum = 1; EndpointNum < ENDPOINT_TOTAL_ENDPOINTS; EndpointNum++)
{
return false;
}
uint16_t Size;
uint8_t Type;
uint8_t Direction;
bool DoubleBanked;
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, CDCInterfaceInfo->Config.DataOUTEndpointSize,
CDCInterfaceInfo->Config.DataOUTEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->Config.NotificationEndpointNumber, EP_TYPE_INTERRUPT,
ENDPOINT_DIR_IN, CDCInterfaceInfo->Config.NotificationEndpointSize,
CDCInterfaceInfo->Config.NotificationEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
if (EndpointNum == CDCInterfaceInfo->Config.DataINEndpointNumber)
{
Size = CDCInterfaceInfo->Config.DataINEndpointSize;
Direction = ENDPOINT_DIR_IN;
Type = EP_TYPE_BULK;
DoubleBanked = CDCInterfaceInfo->Config.DataINEndpointDoubleBank;
}
else if (EndpointNum == CDCInterfaceInfo->Config.DataOUTEndpointNumber)
{
Size = CDCInterfaceInfo->Config.DataOUTEndpointSize;
Direction = ENDPOINT_DIR_OUT;
Type = EP_TYPE_BULK;
DoubleBanked = CDCInterfaceInfo->Config.DataOUTEndpointDoubleBank;
}
else if (EndpointNum == CDCInterfaceInfo->Config.NotificationEndpointNumber)
{
Size = CDCInterfaceInfo->Config.NotificationEndpointSize;
Direction = ENDPOINT_DIR_IN;
Type = EP_TYPE_INTERRUPT;
DoubleBanked = CDCInterfaceInfo->Config.NotificationEndpointDoubleBank;
}
else
{
continue;
}
if (!(Endpoint_ConfigureEndpoint(EndpointNum, Type, Direction, Size,
DoubleBanked ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
}
return true;
}

@ -39,26 +39,39 @@ bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInter
{
memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));
if (MIDIInterfaceInfo->Config.DataINEndpointNumber)
for (uint8_t EndpointNum = 1; EndpointNum < ENDPOINT_TOTAL_ENDPOINTS; EndpointNum++)
{
if (!(Endpoint_ConfigureEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_IN, MIDIInterfaceInfo->Config.DataINEndpointSize,
MIDIInterfaceInfo->Config.DataINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
uint16_t Size;
uint8_t Type;
uint8_t Direction;
bool DoubleBanked;
if (EndpointNum == MIDIInterfaceInfo->Config.DataINEndpointNumber)
{
return false;
Size = MIDIInterfaceInfo->Config.DataINEndpointSize;
Direction = ENDPOINT_DIR_IN;
Type = EP_TYPE_BULK;
DoubleBanked = MIDIInterfaceInfo->Config.DataINEndpointDoubleBank;
}
}
if (MIDIInterfaceInfo->Config.DataOUTEndpointNumber)
{
if (!(Endpoint_ConfigureEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, MIDIInterfaceInfo->Config.DataOUTEndpointSize,
MIDIInterfaceInfo->Config.DataOUTEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
else if (EndpointNum == MIDIInterfaceInfo->Config.DataOUTEndpointNumber)
{
Size = MIDIInterfaceInfo->Config.DataOUTEndpointSize;
Direction = ENDPOINT_DIR_OUT;
Type = EP_TYPE_BULK;
DoubleBanked = MIDIInterfaceInfo->Config.DataOUTEndpointDoubleBank;
}
else
{
continue;
}
if (!(Endpoint_ConfigureEndpoint(EndpointNum, Type, Direction, Size,
DoubleBanked ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
}
return true;
}

@ -75,20 +75,39 @@ bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceIn
{
memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State));
if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_IN, MSInterfaceInfo->Config.DataINEndpointSize,
MSInterfaceInfo->Config.DataINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
for (uint8_t EndpointNum = 1; EndpointNum < ENDPOINT_TOTAL_ENDPOINTS; EndpointNum++)
{
return false;
}
uint16_t Size;
uint8_t Type;
uint8_t Direction;
bool DoubleBanked;
if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, MSInterfaceInfo->Config.DataOUTEndpointSize,
MSInterfaceInfo->Config.DataOUTEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
if (EndpointNum == MSInterfaceInfo->Config.DataINEndpointNumber)
{
Size = MSInterfaceInfo->Config.DataINEndpointSize;
Direction = ENDPOINT_DIR_IN;
Type = EP_TYPE_BULK;
DoubleBanked = MSInterfaceInfo->Config.DataINEndpointDoubleBank;
}
else if (EndpointNum == MSInterfaceInfo->Config.DataOUTEndpointNumber)
{
Size = MSInterfaceInfo->Config.DataOUTEndpointSize;
Direction = ENDPOINT_DIR_OUT;
Type = EP_TYPE_BULK;
DoubleBanked = MSInterfaceInfo->Config.DataOUTEndpointDoubleBank;
}
else
{
continue;
}
if (!(Endpoint_ConfigureEndpoint(EndpointNum, Type, Direction, Size,
DoubleBanked ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
}
return true;
}

@ -114,27 +114,46 @@ bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISIn
{
memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.DataINEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_IN, RNDISInterfaceInfo->Config.DataINEndpointSize,
RNDISInterfaceInfo->Config.DataINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
for (uint8_t EndpointNum = 1; EndpointNum < ENDPOINT_TOTAL_ENDPOINTS; EndpointNum++)
{
return false;
}
uint16_t Size;
uint8_t Type;
uint8_t Direction;
bool DoubleBanked;
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpointNumber, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, RNDISInterfaceInfo->Config.DataOUTEndpointSize,
RNDISInterfaceInfo->Config.DataOUTEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.NotificationEndpointNumber, EP_TYPE_INTERRUPT,
ENDPOINT_DIR_IN, RNDISInterfaceInfo->Config.NotificationEndpointSize,
RNDISInterfaceInfo->Config.NotificationEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
if (EndpointNum == RNDISInterfaceInfo->Config.DataINEndpointNumber)
{
Size = RNDISInterfaceInfo->Config.DataINEndpointSize;
Direction = ENDPOINT_DIR_IN;
Type = EP_TYPE_BULK;
DoubleBanked = RNDISInterfaceInfo->Config.DataINEndpointDoubleBank;
}
else if (EndpointNum == RNDISInterfaceInfo->Config.DataOUTEndpointNumber)
{
Size = RNDISInterfaceInfo->Config.DataOUTEndpointSize;
Direction = ENDPOINT_DIR_OUT;
Type = EP_TYPE_BULK;
DoubleBanked = RNDISInterfaceInfo->Config.DataOUTEndpointDoubleBank;
}
else if (EndpointNum == RNDISInterfaceInfo->Config.NotificationEndpointNumber)
{
Size = RNDISInterfaceInfo->Config.NotificationEndpointSize;
Direction = ENDPOINT_DIR_IN;
Type = EP_TYPE_INTERRUPT;
DoubleBanked = RNDISInterfaceInfo->Config.NotificationEndpointDoubleBank;
}
else
{
continue;
}
if (!(Endpoint_ConfigureEndpoint(EndpointNum, Type, Direction, Size,
DoubleBanked ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
{
return false;
}
}
return true;
}

@ -43,8 +43,7 @@ bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
const uint8_t UECFG0XData,
const uint8_t UECFG1XData)
{
#if defined(CONTROL_ONLY_DEVICE)
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
Endpoint_SelectEndpoint(Number);
Endpoint_EnableEndpoint();
UECFG1X = 0;
@ -52,51 +51,6 @@ bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
UECFG1X = UECFG1XData;
return Endpoint_IsConfigured();
#else
uint8_t UECFG0XTemp[ENDPOINT_TOTAL_ENDPOINTS];
uint8_t UECFG1XTemp[ENDPOINT_TOTAL_ENDPOINTS];
uint8_t UEIENXTemp[ENDPOINT_TOTAL_ENDPOINTS];
for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
{
Endpoint_SelectEndpoint(EPNum);
UECFG0XTemp[EPNum] = UECFG0X;
UECFG1XTemp[EPNum] = UECFG1X;
UEIENXTemp[EPNum] = UEIENX;
}
UECFG0XTemp[Number] = UECFG0XData;
UECFG1XTemp[Number] = UECFG1XData;
UEIENXTemp[Number] = 0;
for (uint8_t EPNum = 1; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
{
Endpoint_SelectEndpoint(EPNum);
UEIENX = 0;
UEINTX = 0;
UECFG1X = 0;
Endpoint_DisableEndpoint();
}
for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
{
if (!(UECFG1XTemp[EPNum] & (1 << ALLOC)))
continue;
Endpoint_SelectEndpoint(EPNum);
Endpoint_EnableEndpoint();
UECFG0X = UECFG0XTemp[EPNum];
UECFG1X = UECFG1XTemp[EPNum];
UEIENX = UEIENXTemp[EPNum];
if (!(Endpoint_IsConfigured()))
return false;
}
Endpoint_SelectEndpoint(Number);
return true;
#endif
}
void Endpoint_ClearEndpoints(void)

@ -267,6 +267,9 @@
* More banks uses more USB DPRAM, but offers better performance. Isochronous type
* endpoints <b>must</b> have at least two banks.
*
* \note Endpoints <b>must</b> be configured in ascending order, or bank corruption will occur.
* \n\n
*
* \note Certain models of USB AVR's endpoints may have different maximum packet sizes based on the endpoint's
* index - refer to the chosen USB AVR's datasheet to determine the maximum bank size for each endpoint.
* \n\n
@ -442,7 +445,7 @@
return ((UEINT & (1 << EndpointNumber)) ? true : false);
}
/** Determines if the selected IN endpoint is ready for a new packet.
/** Determines if the selected IN endpoint is ready for a new packet to be sent to the host.
*
* \ingroup Group_EndpointPacketManagement
*
@ -454,7 +457,7 @@
return ((UEINTX & (1 << TXINI)) ? true : false);
}
/** Determines if the selected OUT endpoint has received new packet.
/** Determines if the selected OUT endpoint has received new packet from the host.
*
* \ingroup Group_EndpointPacketManagement
*

@ -44,61 +44,17 @@ bool Pipe_ConfigurePipe(const uint8_t Number,
const uint16_t Size,
const uint8_t Banks)
{
uint8_t UPCFG0XTemp[PIPE_TOTAL_PIPES];
uint8_t UPCFG1XTemp[PIPE_TOTAL_PIPES];
uint8_t UPCFG2XTemp[PIPE_TOTAL_PIPES];
uint8_t UPCONXTemp[PIPE_TOTAL_PIPES];
uint8_t UPINRQXTemp[PIPE_TOTAL_PIPES];
uint8_t UPIENXTemp[PIPE_TOTAL_PIPES];
for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
{
Pipe_SelectPipe(PNum);
UPCFG0XTemp[PNum] = UPCFG0X;
UPCFG1XTemp[PNum] = UPCFG1X;
UPCFG2XTemp[PNum] = UPCFG2X;
UPCONXTemp[PNum] = UPCONX;
UPINRQXTemp[PNum] = UPINRQX;
UPIENXTemp[PNum] = UPIENX;
}
UPCFG0XTemp[Number] = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0));
UPCFG1XTemp[Number] = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size));
UPCFG2XTemp[Number] = 0;
UPCONXTemp[Number] = (1 << INMODE);
UPINRQXTemp[Number] = 0;
UPIENXTemp[Number] = 0;
for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
{
Pipe_SelectPipe(PNum);
UPIENX = 0;
UPINTX = 0;
UPCFG1X = 0;
Pipe_DisablePipe();
}
Pipe_SelectPipe(Number);
Pipe_EnablePipe();
for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
{
if (!(UPCFG1XTemp[PNum] & (1 << ALLOC)))
continue;
Pipe_SelectPipe(PNum);
Pipe_EnablePipe();
UPCFG1X = 0;
UPCFG0X = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0));
UPCFG1X = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size));
UPCFG0X = UPCFG0XTemp[PNum];
UPCFG1X = UPCFG1XTemp[PNum];
UPCFG2X = UPCFG2XTemp[PNum];
UPCONX |= UPCONXTemp[PNum];
UPINRQX = UPINRQXTemp[PNum];
UPIENX = UPIENXTemp[PNum];
Pipe_SetInfiniteINRequests();
if (!(Pipe_IsConfigured()))
return false;
}
Pipe_SelectPipe(Number);
return true;
return Pipe_IsConfigured();
}
void Pipe_ClearPipes(void)

@ -462,7 +462,7 @@
return ((UPINTX & (1 << RWAL)) ? true : false);
}
/** Determines if an IN request has been received on the currently selected pipe.
/** Determines if a packet has been received on the currently selected IN pipe from the attached device.
*
* \ingroup Group_PipePacketManagement
*
@ -474,7 +474,7 @@
return ((UPINTX & (1 << RXINI)) ? true : false);
}
/** Determines if the currently selected pipe is ready to send an OUT request.
/** Determines if the currently selected OUT pipe is ready to send an OUT packet to the attached device.
*
* \ingroup Group_PipePacketManagement
*
@ -839,6 +839,9 @@
* uses more USB DPRAM, but offers better performance. Isochronous type pipes <b>must</b>
* have at least two banks.
*
* \note Endpoints <b>must</b> be configured in ascending order, or bank corruption will occur.
* \n\n
*
* \note Certain models of USB AVR's pipes may have different maximum packet sizes based on the pipe's
* index - refer to the chosen USB AVR's datasheet to determine the maximum bank size for each pipe.
* \n\n

@ -45,6 +45,7 @@
* - Removed the EVENT_USB_InitFailure() event, not specifying a USB mode now defaults to UID selection mode
* - Renamed and moved class driver common constant definitions to make the naming scheme more uniform
* - Changed default value for the reset polarity parameter in the AVRISP-MKII project so that it defaults to active low drive
* - Rewritten configuration descriptor parser for all host mode projects and class drivers to ensure better compatibility
*
* <b>Fixed:</b>
* - Fixed USB_GetHIDReportItemInfo() function modifying the given report item's data when the report item does not exist

@ -19,6 +19,7 @@
* -# Change makefiles to allow for absolute LUFA location to be used
* -# Re-add interrupt Pipe/Endpoint support
* -# Fix intermittent device mode enumeration errors
* -# Shrink binary size for 8U2 parts
* - Documentation/Support
* -# Add detailed overviews of how each demo works
* -# Add board overviews

@ -21,6 +21,9 @@
* specified, the controller will default to UID selection mode.
*
* <b>Device Mode</b>
* - Endpoints MUST be allocated in ascending order to ensure that bank corruption does not occur. Ensure that your user application
* allocated endpoints in ascending order - or if your application uses the USB device mode class drivers, ensure that each instance's
* endpoint indexes are non-overlapped with other interface's endpoints.
* - The signature for the CALLBACK_USB_GetDescriptor() callback has changed, the "void** const DescriptorAddress" parameter is
* now "const void** const DescriptorAddress". Existing applications should update their callback signatures to match this, and
* eliminate any casting of descriptor pointers to a non-const pointer.
@ -28,6 +31,9 @@
* for each class driver for the new class specific descriptor type names.
*
* <b>Host Mode</b>
* - Pipes MUST be allocated in ascending order to ensure that bank corruption does not occur. Ensure that your user application
* allocated pipes in ascending order - or if your application uses the USB host mode class drivers, ensure that each instance's
* pipe indexes are non-overlapped with other interface's pipes.
* - The PRNT_Host_SendData() function has been renamed to \ref PRNT_Host_SendString(). Existing applications should simply
* replace all references to the obsolete function name with the new function name.
* - The names of the class specific descriptor type defines in the USB Class drivers have changed - refer to the driver documentation

@ -55,7 +55,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2060,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -69,7 +69,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2063,
.ReleaseNumber = 0x0001,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -67,7 +67,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2044,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -89,7 +89,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2042,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -93,7 +93,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2063,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -67,7 +67,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x204B,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -67,7 +67,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x2045,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

@ -67,7 +67,7 @@ USB_Descriptor_Device_t PROGMEM USART_DeviceDescriptor =
.VendorID = 0x03EB,
.ProductID = 0x204B,
.ReleaseNumber = 0x0000,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,

Loading…
Cancel
Save