Commit d3fb6273 authored by Dean Camera's avatar Dean Camera
Browse files

Fix PrinterHost demo so that it will only enumerate printers with...

Fix PrinterHost demo so that it will only enumerate printers with Bidirectional protocol encapsulation. Change enumeration code to automatically select the correct alternate setting for the printer interface to select the bidirectional protocol.
parent 9d2613d9
......@@ -30,13 +30,16 @@
#include "ConfigDescriptor.h"
uint8_t PrinterInterfaceNumber;
uint8_t PrinterAltSetting;
uint8_t ProcessConfigurationDescriptor(void)
{
uint8_t* ConfigDescriptorData;
uint16_t ConfigDescriptorSize;
uint8_t ErrorCode;
uint8_t FoundEndpoints = 0;
uint8_t FoundEndpointMask;
/* Get Configuration Descriptor size from the device */
if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
......@@ -58,31 +61,17 @@ uint8_t ProcessConfigurationDescriptor(void)
/* Get the printer interface from the configuration descriptor */
if ((ErrorCode = USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
NextPrinterInterface)))
NextBidirectionalPrinterInterface)))
{
/* Descriptor not found, error out */
return NoInterfaceFound;
}
/* Get the printer's communication protocol */
PrinterProtocol = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).Protocol;
/* Determine what endpoints to look for from the protocol */
switch (PrinterProtocol)
{
case PROTOCOL_UNIDIRECTIONAL:
FoundEndpointMask = (1 << PRINTER_DATA_OUT_PIPE);
break;
case PROTOCOL_BIDIRECTIONAL:
case PROTOCOL_IEEE1284:
FoundEndpointMask = ((1 << PRINTER_DATA_OUT_PIPE) | (1 << PRINTER_DATA_IN_PIPE));
break;
default:
return NoInterfaceFound;
}
PrinterInterfaceNumber = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).InterfaceNumber;
PrinterAltSetting = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).AlternateSetting;
/* Get the IN and OUT data endpoints for the mass storage interface */
while (FoundEndpoints != FoundEndpointMask)
while (FoundEndpoints != ((1 << PRINTER_DATA_OUT_PIPE) | (1 << PRINTER_DATA_IN_PIPE)))
{
/* Fetch the next bulk endpoint from the current printer interface */
if ((ErrorCode = USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
......@@ -123,15 +112,16 @@ uint8_t ProcessConfigurationDescriptor(void)
return SuccessfulConfigRead;
}
uint8_t NextPrinterInterface(void* CurrentDescriptor)
uint8_t NextBidirectionalPrinterInterface(void* CurrentDescriptor)
{
/* PURPOSE: Find next mass storage class interface descriptor */
/* PURPOSE: Find next Bidirectional protocol printer class interface descriptor */
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
/* Check the descriptor class and protocol, break out if correct class/protocol interface found */
if ((DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Class == PRINTER_CLASS) &&
(DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).SubClass == PRINTER_SUBCLASS))
(DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).SubClass == PRINTER_SUBCLASS) &&
(DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Protocol == PROTOCOL_BIDIRECTIONAL))
{
return DESCRIPTOR_SEARCH_Found;
}
......
......@@ -55,11 +55,15 @@
NoInterfaceFound = 4,
NoEndpointFound = 5,
};
/* External Variables: */
uint8_t PrinterInterfaceNumber;
uint8_t PrinterAltSetting;
/* Function Prototypes: */
uint8_t ProcessConfigurationDescriptor(void);
uint8_t NextPrinterInterface(void* CurrentDescriptor);
uint8_t NextBidirectionalPrinterInterface(void* CurrentDescriptor);
uint8_t NextInterfaceBulkDataEndpoint(void* CurrentDescriptor);
#endif
......@@ -36,8 +36,6 @@
#include "PrinterHost.h"
uint8_t PrinterProtocol;
int main(void)
{
......@@ -150,12 +148,37 @@ void USB_Printer_Host(void)
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
/* Some printers use alternate settings to determine the communication protocol used - if so, send a SetInterface
* request to switch to the interface alternate setting with the Bidirection protocol */
if (PrinterAltSetting)
{
USB_ControlRequest = (USB_Request_Header_t)
{
bmRequestType: (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
bRequest: REQ_SetInterface,
wValue: PrinterAltSetting,
wIndex: PrinterInterfaceNumber,
wLength: 0,
};
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
{
puts_P(PSTR("Control Error (Set Interface).\r\n"));
printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
}
USB_HostState = HOST_STATE_Configured;
break;
case HOST_STATE_Configured:
printf_P(PSTR("Printer Protocol: %d\r\n"), PrinterProtocol);
puts_P(PSTR("Retrieving Device ID...\r\n"));
Device_ID_String_t DeviceIDString;
......
......@@ -62,9 +62,6 @@
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_USB_BUSY (LEDS_LED2)
/* External Variables: */
extern uint8_t PrinterProtocol;
/* Function Prototypes: */
void EVENT_USB_DeviceAttached(void);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment