From 8ba51f090f7cafb36e1108cc58e68f5d71bc13c0 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Wed, 4 Nov 2009 13:16:53 +0000 Subject: 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. --- LUFA/Drivers/USB/Class/Host/CDC.h | 2 +- LUFA/Drivers/USB/Class/Host/HIDParser.c | 58 ++++--- LUFA/Drivers/USB/Class/Host/HIDParser.h | 2 +- LUFA/Drivers/USB/Class/Host/MIDI.h | 2 +- LUFA/Drivers/USB/Class/Host/MassStorage.h | 8 +- LUFA/Drivers/USB/Class/Host/Printer.c | 250 ++++++++++++++++++++++++++++++ LUFA/Drivers/USB/Class/Host/Printer.h | 209 +++++++++++++++++++++++++ LUFA/Drivers/USB/Class/Host/StillImage.h | 2 +- LUFA/Drivers/USB/Class/MassStorage.h | 2 +- 9 files changed, 495 insertions(+), 40 deletions(-) create mode 100644 LUFA/Drivers/USB/Class/Host/Printer.c create mode 100644 LUFA/Drivers/USB/Class/Host/Printer.h (limited to 'LUFA/Drivers/USB/Class') 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 + * must 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 + * may 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. * -- cgit v1.2.3