aboutsummaryrefslogtreecommitdiffstats
path: root/LUFA
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2009-11-04 13:16:53 +0000
committerDean Camera <dean@fourwalledcubicle.com>2009-11-04 13:16:53 +0000
commit8ba51f090f7cafb36e1108cc58e68f5d71bc13c0 (patch)
tree20e4d621f425148be803af0ab2f5c562bf6307d2 /LUFA
parent4670b39070afd12483b2dd31e2ec6300ce73eb39 (diff)
downloadlufa-8ba51f090f7cafb36e1108cc58e68f5d71bc13c0.tar.gz
lufa-8ba51f090f7cafb36e1108cc58e68f5d71bc13c0.tar.bz2
lufa-8ba51f090f7cafb36e1108cc58e68f5d71bc13c0.zip
Added new Printer Host mode Class driver.
Added new Printer Host mode ClassDriver demo. Added table of supported classes and modes to the main USB Class Driver documentation.
Diffstat (limited to 'LUFA')
-rw-r--r--LUFA/Drivers/USB/Class/Host/CDC.h2
-rw-r--r--LUFA/Drivers/USB/Class/Host/HIDParser.c58
-rw-r--r--LUFA/Drivers/USB/Class/Host/HIDParser.h2
-rw-r--r--LUFA/Drivers/USB/Class/Host/MIDI.h2
-rw-r--r--LUFA/Drivers/USB/Class/Host/MassStorage.h8
-rw-r--r--LUFA/Drivers/USB/Class/Host/Printer.c250
-rw-r--r--LUFA/Drivers/USB/Class/Host/Printer.h209
-rw-r--r--LUFA/Drivers/USB/Class/Host/StillImage.h2
-rw-r--r--LUFA/Drivers/USB/Class/MassStorage.h2
-rw-r--r--LUFA/Drivers/USB/USB.h50
-rw-r--r--LUFA/ManPages/ChangeLog.txt2
-rw-r--r--LUFA/ManPages/MigrationInformation.txt1
-rw-r--r--LUFA/makefile1
13 files changed, 549 insertions, 40 deletions
diff --git a/LUFA/Drivers/USB/Class/Host/CDC.h b/LUFA/Drivers/USB/Class/Host/CDC.h
index 51b00da3b..4132d882c 100644
--- a/LUFA/Drivers/USB/Class/Host/CDC.h
+++ b/LUFA/Drivers/USB/Class/Host/CDC.h
@@ -72,7 +72,7 @@
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
- * after \ref HID_Host_ConfigurePipes() is called and the Host state machine is in the
+ * after \ref CDC_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
uint8_t ControlInterfaceNumber; /**< Interface index of the CDC-ACM control interface within the attached device */
diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.c b/LUFA/Drivers/USB/Class/Host/HIDParser.c
index 3090774ec..81062b1c8 100644
--- a/LUFA/Drivers/USB/Class/Host/HIDParser.c
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.c
@@ -39,8 +39,8 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
HID_StateTable_t* CurrStateTable = &StateTable[0];
HID_CollectionPath_t* CurrCollectionPath = NULL;
HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0];
- uint16_t UsageStack[HID_USAGE_STACK_DEPTH];
- uint8_t UsageStackSize = 0;
+ uint16_t UsageList[HID_USAGE_STACK_DEPTH];
+ uint8_t UsageListSize = 0;
memset(ParserData, 0x00, sizeof(HID_ReportInfo_t));
memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t));
@@ -138,23 +138,23 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
if (CurrReportIDInfo == NULL)
{
- if (ParserData->TotalDeviceReports++ > HID_MAX_REPORT_IDS)
+ if (ParserData->TotalDeviceReports == HID_MAX_REPORT_IDS)
return HID_PARSE_InsufficientReportIDItems;
- CurrReportIDInfo = &ParserData->ReportIDSizes[ParserData->TotalDeviceReports - 1];
+ CurrReportIDInfo = &ParserData->ReportIDSizes[ParserData->TotalDeviceReports++];
memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
}
}
ParserData->UsingReportIDs = true;
- CurrReportIDInfo->ReportID = CurrStateTable->ReportID;
+ CurrReportIDInfo->ReportID = CurrStateTable->ReportID;
break;
case (TYPE_LOCAL | TAG_LOCAL_USAGE):
- if (UsageStackSize == HID_USAGE_STACK_DEPTH)
- return HID_PARSE_UsageStackOverflow;
+ if (UsageListSize == HID_USAGE_STACK_DEPTH)
+ return HID_PARSE_UsageListOverflow;
- UsageStack[UsageStackSize++] = ReportItemData;
+ UsageList[UsageListSize++] = ReportItemData;
break;
case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN):
CurrStateTable->Attributes.Usage.MinMax.Minimum = ReportItemData;
@@ -187,14 +187,14 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
CurrCollectionPath->Type = ReportItemData;
CurrCollectionPath->Usage.Page = CurrStateTable->Attributes.Usage.Page;
- if (UsageStackSize)
+ if (UsageListSize)
{
- CurrCollectionPath->Usage.Usage = UsageStack[0];
+ CurrCollectionPath->Usage.Usage = UsageList[0];
- for (uint8_t i = 0; i < UsageStackSize; i++)
- UsageStack[i] = UsageStack[i + 1];
+ for (uint8_t i = 0; i < UsageListSize; i++)
+ UsageList[i] = UsageList[i + 1];
- UsageStackSize--;
+ UsageListSize--;
}
break;
@@ -219,28 +219,24 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
NewReportItem.CollectionPath = CurrCollectionPath;
NewReportItem.ReportID = CurrStateTable->ReportID;
- if (UsageStackSize)
+ if (UsageListSize)
{
- NewReportItem.Attributes.Usage.Usage = UsageStack[0];
+ NewReportItem.Attributes.Usage.Usage = UsageList[0];
- for (uint8_t i = 0; i < UsageStackSize; i++)
- UsageStack[i] = UsageStack[i + 1];
+ for (uint8_t i = 0; i < UsageListSize; i++)
+ UsageList[i] = UsageList[i + 1];
- UsageStackSize--;
+ UsageListSize--;
}
- switch (HIDReportItem & TAG_MASK)
- {
- case TAG_MAIN_INPUT:
- NewReportItem.ItemType = REPORT_ITEM_TYPE_In;
- break;
- case TAG_MAIN_OUTPUT:
- NewReportItem.ItemType = REPORT_ITEM_TYPE_Out;
- break;
- case TAG_MAIN_FEATURE:
- NewReportItem.ItemType = REPORT_ITEM_TYPE_Feature;
- break;
- }
+ uint8_t ItemTag = (HIDReportItem & TAG_MASK);
+
+ if (ItemTag == TAG_MAIN_INPUT)
+ NewReportItem.ItemType = REPORT_ITEM_TYPE_In;
+ else if (ItemTag == TAG_MAIN_OUTPUT)
+ NewReportItem.ItemType = REPORT_ITEM_TYPE_Out;
+ else
+ NewReportItem.ItemType = REPORT_ITEM_TYPE_Feature;
NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType];
@@ -268,7 +264,7 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
{
CurrStateTable->Attributes.Usage.MinMax.Minimum = 0;
CurrStateTable->Attributes.Usage.MinMax.Maximum = 0;
- UsageStackSize = 0;
+ UsageListSize = 0;
}
}
diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.h b/LUFA/Drivers/USB/Class/Host/HIDParser.h
index 7a1563a3a..751e40e0e 100644
--- a/LUFA/Drivers/USB/Class/Host/HIDParser.h
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.h
@@ -142,7 +142,7 @@
HID_PARSE_InsufficientReportItems = 3, /**< More than \ref HID_MAX_REPORTITEMS report items in the report. */
HID_PARSE_UnexpectedEndCollection = 4, /**< An END COLLECTION item found without matching COLLECTION item. */
HID_PARSE_InsufficientCollectionPaths = 5, /**< More than \ref HID_MAX_COLLECTIONS collections in the report. */
- HID_PARSE_UsageStackOverflow = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */
+ HID_PARSE_UsageListOverflow = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */
HID_PARSE_InsufficientReportIDItems = 7, /**< More than \ref HID_MAX_REPORT_IDS report IDs in the device. */
HID_PARSE_NoUnfilteredReportItems = 8, /**< All report items from the device were filtered by the filtering callback routine. */
};
diff --git a/LUFA/Drivers/USB/Class/Host/MIDI.h b/LUFA/Drivers/USB/Class/Host/MIDI.h
index b86699e2a..35671f902 100644
--- a/LUFA/Drivers/USB/Class/Host/MIDI.h
+++ b/LUFA/Drivers/USB/Class/Host/MIDI.h
@@ -71,7 +71,7 @@
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
- * after \ref HID_Host_ConfigurePipes() is called and the Host state machine is in the
+ * after \ref MIDI_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
diff --git a/LUFA/Drivers/USB/Class/Host/MassStorage.h b/LUFA/Drivers/USB/Class/Host/MassStorage.h
index 192e478dc..a651a88f8 100644
--- a/LUFA/Drivers/USB/Class/Host/MassStorage.h
+++ b/LUFA/Drivers/USB/Class/Host/MassStorage.h
@@ -60,8 +60,8 @@
/* Type Defines: */
/** Class state structure. An instance of this structure should be made within the user application,
- * and passed to each of the HID class driver functions as the HIDInterfaceInfo parameter. This
- * stores each HID interface's configuration and state information.
+ * and passed to each of the Mass Storage class driver functions as the MSInterfaceInfo parameter. This
+ * stores each Mass Storage interface's configuration and state information.
*/
typedef struct
{
@@ -75,10 +75,10 @@
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
- * after \ref HID_Host_ConfigurePipes() is called and the Host state machine is in the
+ * after \ref MS_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
- uint8_t InterfaceNumber; /**< Interface index of the HID interface within the attached device */
+ uint8_t InterfaceNumber; /**< Interface index of the Mass Storage interface within the attached device */
uint16_t DataINPipeSize; /**< Size in bytes of the MS interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the MS interface's OUT data pipe */
diff --git a/LUFA/Drivers/USB/Class/Host/Printer.c b/LUFA/Drivers/USB/Class/Host/Printer.c
new file mode 100644
index 000000000..bc8fba85f
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Host/Printer.c
@@ -0,0 +1,250 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_HOST)
+
+#define INCLUDE_FROM_PRINTER_CLASS_HOST_C
+#include "Printer.h"
+
+uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint16_t ConfigDescriptorSize,
+ uint8_t* DeviceConfigDescriptor)
+{
+ uint8_t FoundEndpoints = 0;
+
+ memset(&PRNTInterfaceInfo->State, 0x00, sizeof(PRNTInterfaceInfo->State));
+
+ if (DESCRIPTOR_TYPE(DeviceConfigDescriptor) != DTYPE_Configuration)
+ return PRNT_ENUMERROR_InvalidConfigDescriptor;
+
+ if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
+ DComp_NextPRNTInterface) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ return PRNT_ENUMERROR_NoPrinterInterfaceFound;
+ }
+
+ USB_Descriptor_Interface_t* PrinterInterface = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Interface_t);
+
+ PRNTInterfaceInfo->State.InterfaceNumber = PrinterInterface->InterfaceNumber;
+ PRNTInterfaceInfo->State.AlternateSetting = PrinterInterface->AlternateSetting;
+
+ while (FoundEndpoints != (PRNT_FOUND_DATAPIPE_IN | PRNT_FOUND_DATAPIPE_OUT))
+ {
+ if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &DeviceConfigDescriptor,
+ DComp_NextPRNTInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ return PRNT_ENUMERROR_EndpointsNotFound;
+ }
+
+ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(DeviceConfigDescriptor, USB_Descriptor_Endpoint_t);
+
+ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
+ {
+ Pipe_ConfigurePipe(PRNTInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
+ EndpointData->EndpointAddress, EndpointData->EndpointSize,
+ PIPE_BANK_DOUBLE);
+ PRNTInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
+
+ FoundEndpoints |= PRNT_FOUND_DATAPIPE_IN;
+ }
+ else
+ {
+ Pipe_ConfigurePipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
+ EndpointData->EndpointAddress, EndpointData->EndpointSize,
+ PIPE_BANK_DOUBLE);
+ PRNTInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
+
+ FoundEndpoints |= PRNT_FOUND_DATAPIPE_OUT;
+ }
+ }
+
+ PRNTInterfaceInfo->State.IsActive = true;
+ return PRNT_ENUMERROR_NoError;
+}
+
+static uint8_t DComp_NextPRNTInterface(void* CurrentDescriptor)
+{
+ if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
+ {
+ 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).Protocol == PRINTER_PROTOCOL))
+ {
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+static uint8_t DComp_NextPRNTInterfaceEndpoint(void* CurrentDescriptor)
+{
+ if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
+ {
+ uint8_t EndpointType = (DESCRIPTOR_CAST(CurrentDescriptor,
+ USB_Descriptor_Endpoint_t).Attributes & EP_TYPE_MASK);
+
+ if (EndpointType == EP_TYPE_BULK)
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
+ {
+ return DESCRIPTOR_SEARCH_Fail;
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+
+}
+
+uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+ if (PRNTInterfaceInfo->State.AlternateSetting)
+ {
+ uint8_t ErrorCode;
+
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ bmRequestType: (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
+ bRequest: REQ_SetInterface,
+ wValue: PRNTInterfaceInfo->State.AlternateSetting,
+ wIndex: PRNTInterfaceInfo->State.InterfaceNumber,
+ wLength: 0,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
+ }
+
+ return HOST_SENDCONTROL_Successful;
+}
+
+uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint8_t* const PortStatus)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ bmRequestType: (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+ bRequest: REQ_GetPortStatus,
+ wValue: 0,
+ wIndex: PRNTInterfaceInfo->State.InterfaceNumber,
+ wLength: sizeof(uint8_t),
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ return USB_Host_SendControlRequest(PortStatus);
+}
+
+uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ bmRequestType: (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ bRequest: REQ_SoftReset,
+ wValue: 0,
+ wIndex: PRNTInterfaceInfo->State.InterfaceNumber,
+ wLength: 0,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ return USB_Host_SendControlRequest(NULL);
+}
+
+uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, void* PrinterCommands, uint16_t CommandSize)
+{
+ uint8_t ErrorCode;
+
+ Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ if ((ErrorCode = Pipe_Write_Stream_LE(PrinterCommands, CommandSize, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ Pipe_ClearOUT();
+ while (!(Pipe_IsOUTReady()))
+ {
+ if (USB_HostState == HOST_STATE_Unattached)
+ return PIPE_RWSTREAM_DeviceDisconnected;
+ }
+
+ Pipe_Freeze();
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, char* DeviceIDString, uint16_t BufferSize)
+{
+ uint8_t ErrorCode = HOST_SENDCONTROL_Successful;
+ uint16_t DeviceIDStringLength = 0;
+
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ bmRequestType: (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+ bRequest: REQ_GetDeviceID,
+ wValue: 0,
+ wIndex: PRNTInterfaceInfo->State.InterfaceNumber,
+ wLength: sizeof(DeviceIDStringLength),
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ if ((ErrorCode = USB_Host_SendControlRequest(&DeviceIDStringLength)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
+
+ if (!(DeviceIDStringLength))
+ {
+ DeviceIDString[0] = 0x00;
+ return HOST_SENDCONTROL_Successful;
+ }
+
+ DeviceIDStringLength = SwapEndian_16(DeviceIDStringLength);
+
+ if (DeviceIDStringLength > BufferSize)
+ DeviceIDStringLength = BufferSize;
+
+ USB_ControlRequest.wLength = DeviceIDStringLength;
+
+ if ((ErrorCode = USB_Host_SendControlRequest(DeviceIDString)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
+
+ memmove(&DeviceIDString[0], &DeviceIDString[2], DeviceIDStringLength - 2);
+
+ DeviceIDString[DeviceIDStringLength - 2] = 0x00;
+
+ return HOST_SENDCONTROL_Successful;
+}
+
+#endif
diff --git a/LUFA/Drivers/USB/Class/Host/Printer.h b/LUFA/Drivers/USB/Class/Host/Printer.h
new file mode 100644
index 000000000..d61eb4a71
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Host/Printer.h
@@ -0,0 +1,209 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \ingroup Group_USBClassPrinter
+ * @defgroup Group_USBClassPrinterHost Printer Class Host Mode Driver
+ *
+ * \section Sec_Dependencies Module Source Dependencies
+ * The following files must be built with any user project that uses this module:
+ * - LUFA/Drivers/USB/Class/Host/Printer.c
+ *
+ * \section Module Description
+ * Host Mode USB Class driver framework interface, for the Printer USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef __PRINTER_CLASS_HOST_H__
+#define __PRINTER_CLASS_HOST_H__
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/Printer.h"
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Macros: */
+
+ /* Type Defines: */
+ /** Class state structure. An instance of this structure should be made within the user application,
+ * and passed to each of the Printer class driver functions as the PRNTInterfaceInfo parameter. This
+ * stores each Printer interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t DataINPipeNumber; /**< Pipe number of the Printer interface's IN data pipe */
+ uint8_t DataOUTPipeNumber; /**< Pipe number of the Printer interface's OUT data pipe */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
+ */
+ struct
+ {
+ bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
+ * after \ref PRNT_Host_ConfigurePipes() is called and the Host state machine is in the
+ * Configured state
+ */
+ uint8_t InterfaceNumber; /**< Interface index of the Printer interface within the attached device */
+ uint8_t AlternateSetting; /**< Alternate setting within the Printer Interface in the attached device */
+
+ uint16_t DataINPipeSize; /**< Size in bytes of the Printer interface's IN data pipe */
+ uint16_t DataOUTPipeSize; /**< Size in bytes of the Printer interface's OUT data pipe */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * <b>may</b> be set to initial values, but may also be ignored to default to sane values when
+ * the interface is enumerated.
+ */
+ } USB_ClassInfo_PRNT_Host_t;
+
+ /* Enums: */
+ enum PRNTHost_EnumerationFailure_ErrorCodes_t
+ {
+ PRNT_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
+ PRNT_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */
+ PRNT_ENUMERROR_NoPrinterInterfaceFound = 2, /**< A compatible Printer interface was not found in the device's Configuration Descriptor */
+ PRNT_ENUMERROR_EndpointsNotFound = 3, /**< Compatible Printer endpoints were not found in the device's interfaces */
+ };
+
+ /* Function Prototypes: */
+ /** General management task for a given Printer host class interface, required for the correct operation of
+ * the interface. This should be called frequently in the main program loop, before the master USB management task
+ * \ref USB_USBTask().
+ *
+ * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
+ */
+ void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+
+ /** Host interface configuration routine, to configure a given Printer host interface instance using the
+ * Configuration Descriptor read from an attached USB device. This function automatically updates the given Printer
+ * instance's state values and configures the pipes required to communicate with the interface if it is found within
+ * the device. This should be called once after the stack has enumerated the attached device, while the host state
+ * machine is in the Addressed state.
+ *
+ * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
+ * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor
+ * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
+ *
+ * \return A value from the \ref PRNTHost_EnumerationFailure_ErrorCodes_t enum
+ */
+ uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint16_t ConfigDescriptorSize,
+ uint8_t* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1, 3);
+
+ /** Configures the printer to enable Bidirectional mode, if it is not already in this mode. This should be called
+ * once the connected device's configuration has been set, to ensure the printer is ready to accept commands.
+ *
+ * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
+ */
+ uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Retrieves the status of the virtual Printer port's inbound status lines. The result can then be masked against the
+ * PRNT_PORTSTATUS_* macros to determine the printer port's status.
+ *
+ * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
+ * \param[out] PortStatus Location where the retrieved port status should be stored
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
+ */
+ uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint8_t* const PortStatus)
+ ATTR_NON_NULL_PTR_ARG(1, 2);
+
+ /** Soft-resets the attached printer, readying it for new commands.
+ *
+ * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
+ */
+ uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Sends the given raw data stream to the attached printer's input endpoint. This should contain commands that the
+ * printer is able to understand - for example, PCL data. Not all printers accept all printer languages; see
+ * \ref PRNT_Host_GetDeviceID() for details on determining acceptable languages for an attached printer.
+ *
+ * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
+ * \param[in] PrinterCommands Pointer to a buffer containing the raw command stream to send to the printer
+ * \param[in] CommandSize Size in bytes of the command stream to be sent
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
+ */
+ uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, void* PrinterCommands,
+ uint16_t CommandSize) ATTR_NON_NULL_PTR_ARG(1, 2);
+
+ /** Retrieves the attached printer device's ID string, formatted according to IEEE 1284. This string is sent as a
+ * Unicode string from the device and is automatically converted to an ASCII encoded C string by this function, thus
+ * the maximum reportable string length is two less than the size given (to accomodate the Unicode string length
+ * bytes which are removed).
+ *
+ * This string, when supported, contains the model, manufacturer and acceptable printer languages for the attached device.
+ *
+ * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state
+ * \param[out] DeviceIDString Pointer to a buffer where the Device ID string should be stored, in ASCII format
+ * \param[in] BufferSize Size in bytes of the buffer allocated for the Device ID string
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum
+ */
+ uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, char* DeviceIDString,
+ uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(1);
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Macros: */
+ #define PRINTER_CLASS 0x07
+ #define PRINTER_SUBCLASS 0x01
+ #define PRINTER_PROTOCOL 0x02
+
+ #define REQ_GetDeviceID 0
+ #define REQ_GetPortStatus 1
+ #define REQ_SoftReset 2
+
+ #define PRNT_FOUND_DATAPIPE_IN (1 << 0)
+ #define PRNT_FOUND_DATAPIPE_OUT (1 << 1)
+
+ /* Function Prototypes: */
+ #if defined(INCLUDE_FROM_PRINTER_CLASS_HOST_C)
+ static uint8_t DComp_NextPRNTInterface(void* const CurrentDescriptor);
+ static uint8_t DComp_NextPRNTInterfaceEndpoint(void* const CurrentDescriptor);
+ #endif
+ #endif
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/Class/Host/StillImage.h b/LUFA/Drivers/USB/Class/Host/StillImage.h
index 8a8552dab..4f7f7fad8 100644
--- a/LUFA/Drivers/USB/Class/Host/StillImage.h
+++ b/LUFA/Drivers/USB/Class/Host/StillImage.h
@@ -72,7 +72,7 @@
struct
{
bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid
- * after \ref HID_Host_ConfigurePipes() is called and the Host state machine is in the
+ * after \ref SI_Host_ConfigurePipes() is called and the Host state machine is in the
* Configured state
*/
diff --git a/LUFA/Drivers/USB/Class/MassStorage.h b/LUFA/Drivers/USB/Class/MassStorage.h
index 495a704ab..d2ad7dc09 100644
--- a/LUFA/Drivers/USB/Class/MassStorage.h
+++ b/LUFA/Drivers/USB/Class/MassStorage.h
@@ -37,7 +37,7 @@
* - LUFA/Drivers/USB/Class/Host/MassStorage.c
*
* \section Module Description
- * Mass Storage Class Driver module. This module contains an internal implementation of the USB Audio Class, for both
+ * Mass Storage Class Driver module. This module contains an internal implementation of the USB Mass Storage Class, for both
* Device and Host USB modes. User applications can use this class driver instead of implementing the Mass Storage class
* manually via the low-level LUFA APIs.
*
diff --git a/LUFA/Drivers/USB/USB.h b/LUFA/Drivers/USB/USB.h
index bac110c10..86b286eaf 100644
--- a/LUFA/Drivers/USB/USB.h
+++ b/LUFA/Drivers/USB/USB.h
@@ -68,6 +68,56 @@
* Multiple device mode class drivers can be used within a project, including multiple instances of the
* same class driver. In this way, USB Hosts and Devices can be made quickly using the internal class drivers
* so that more time and effort can be put into the end application instead of the USB protocol.
+ *
+ * The available class drivers and their modes are listed below.
+ *
+ * <table>
+ * <tr>
+ * <th width="100px">USB Class</th>
+ * <th width="80px">Device</th>
+ * <th width="80px">Host</th>
+ * </tr>
+ * <tr>
+ * <td>Audio</td>
+ * <td bgcolor="#00EE00">Yes</td>
+ * <td bgcolor="#EE0000">No</td>
+ * </tr>
+ * <tr>
+ * <td>CDC</td>
+ * <td bgcolor="#00EE00">Yes</td>
+ * <td bgcolor="#00EE00">Yes</td>
+ * </tr>
+ * <tr>
+ * <td>HID</td>
+ * <td bgcolor="#00EE00">Yes</td>
+ * <td bgcolor="#00EE00">Yes</td>
+ * </tr>
+ * <tr>
+ * <td>MIDI</td>
+ * <td bgcolor="#00EE00">Yes</td>
+ * <td bgcolor="#00EE00">Yes</td>
+ * </tr>
+ * <tr>
+ * <td>Mass Storage</td>
+ * <td bgcolor="#00EE00">Yes</td>
+ * <td bgcolor="#00EE00">Yes</td>
+ * </tr>
+ * <tr>
+ * <td>Printer</td>
+ * <td bgcolor="#EE0000">No</td>
+* <td bgcolor="#00EE00">Yes</td>
+ * </tr>
+ * <tr>
+ * <td>RNDIS</td>
+ * <td bgcolor="#EE0000">No</td>
+ * <td bgcolor="#00EE00">Yes</td>
+ * </tr>
+ * <tr>
+ * <td>Still Image</td>
+ * <td bgcolor="#EE0000">No</td>
+ * <td bgcolor="#00EE00">Yes</td>
+ * </tr>
+ * </table>
*/
#ifndef __USB_H__
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 38e6e8916..52f01fac7 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -16,6 +16,8 @@
* - Added stdio.h stream examples for the virtual CDC UART in the CDC host demos
* - Added new CDC/Mouse ClassDriver device demo
* - Added new Joystick Host ClassDriver and LowLevel demos
+ * - Added new Printer Host mode Class driver
+ * - Added new Printer Host mode ClassDriver demo
*
* <b>Changed:</b>
* - Removed mostly useless "TestApp" demo, as it was mainly useful only for checking for sytax errors in the library
diff --git a/LUFA/ManPages/MigrationInformation.txt b/LUFA/ManPages/MigrationInformation.txt
index a429d3d3c..e430e2d26 100644
--- a/LUFA/ManPages/MigrationInformation.txt
+++ b/LUFA/ManPages/MigrationInformation.txt
@@ -13,6 +13,7 @@
* \section Sec_MigrationXXXXXX Migrating from 090924 to XXXXXX
*
* <b>Host Mode</b>
+ * - The HID_PARSE_UsageStackOverflow HID parser error constant is now named \ref HID_PARSE_UsageListOverflow
* - The \ref CALLBACK_HIDParser_FilterHIDReportItem() HID Parser callback now passes a complete HID_ReportItem_t to the
* user application, instead of just its attributes.
*
diff --git a/LUFA/makefile b/LUFA/makefile
index c668399d4..ab2bb2320 100644
--- a/LUFA/makefile
+++ b/LUFA/makefile
@@ -28,6 +28,7 @@ LUFA_SRC_FILES = ./Drivers/USB/LowLevel/DevChapter9.c \
./Drivers/USB/Class/Host/HID.c \
./Drivers/USB/Class/Host/HIDParser.c \
./Drivers/USB/Class/Host/MassStorage.c \
+ ./Drivers/USB/Class/Host/Printer.c \
./Drivers/USB/Class/Host/StillImage.c \
./Drivers/Board/Temperature.c \
./Drivers/Peripheral/Serial.c \