Add partial project documentation to the incomplete PrinterHost demo.
authorDean Camera <dean@fourwalledcubicle.com>
Sun, 19 Jul 2009 12:36:19 +0000 (12:36 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Sun, 19 Jul 2009 12:36:19 +0000 (12:36 +0000)
Change over Printer_GetDeviceID() to require a pointer to the destination buffer plus the buffer size, rather than using a pointer to a special structure.

Make new Printer_SendData() function to hide the implementation of sending data to an attached printer, cleaning up the main demo source file body.

Demos/Host/Incomplete/PrinterHost/ConfigDescriptor.c
Demos/Host/Incomplete/PrinterHost/ConfigDescriptor.h
Demos/Host/Incomplete/PrinterHost/Lib/PrinterCommands.c
Demos/Host/Incomplete/PrinterHost/Lib/PrinterCommands.h
Demos/Host/Incomplete/PrinterHost/PrinterHost.c
Demos/Host/Incomplete/PrinterHost/PrinterHost.h
LUFA/ManPages/ChangeLog.txt

index 67a0fa7..d4eaff9 100644 (file)
@@ -61,7 +61,7 @@ uint8_t ProcessConfigurationDescriptor(void)
        \r
        /* Get the printer interface from the configuration descriptor */\r
        if ((ErrorCode = USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
-                                                  NextBidirectionalPrinterInterface)))\r
+                                                  DComp_NextBidirectionalPrinterInterface)))\r
        {\r
                /* Descriptor not found, error out */\r
                return NoInterfaceFound;\r
@@ -70,12 +70,12 @@ uint8_t ProcessConfigurationDescriptor(void)
        PrinterInterfaceNumber = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).InterfaceNumber;\r
        PrinterAltSetting      = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).AlternateSetting;\r
 \r
-       /* Get the IN and OUT data endpoints for the mass storage interface */\r
+       /* Get the IN and OUT data endpoints for the printer interface */\r
        while (FoundEndpoints != ((1 << PRINTER_DATA_OUT_PIPE) | (1 << PRINTER_DATA_IN_PIPE)))\r
        {\r
                /* Fetch the next bulk endpoint from the current printer interface */\r
                if ((ErrorCode = USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
-                                                          NextInterfaceBulkDataEndpoint)))\r
+                                                          DComp_NextInterfaceBulkDataEndpoint)))\r
                {\r
                        /* Descriptor not found, error out */\r
                        return NoEndpointFound;\r
@@ -112,16 +112,16 @@ uint8_t ProcessConfigurationDescriptor(void)
        return SuccessfulConfigRead;\r
 }\r
 \r
-uint8_t NextBidirectionalPrinterInterface(void* CurrentDescriptor)\r
+uint8_t DComp_NextBidirectionalPrinterInterface(void* CurrentDescriptor)\r
 {\r
-       /* PURPOSE: Find next Bidirectional protocol printer class interface descriptor */\r
+       /* PURPOSE: Find next bidirectional protocol printer class interface descriptor */\r
 \r
        if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)\r
        {\r
                /* Check the descriptor class and protocol, break out if correct class/protocol interface found */\r
                if ((DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Class    == PRINTER_CLASS)    &&\r
                    (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).SubClass == PRINTER_SUBCLASS) &&\r
-                       (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Protocol == PROTOCOL_BIDIRECTIONAL))\r
+                       (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Protocol == PRINTER_PROTOCOL))\r
                {\r
                        return DESCRIPTOR_SEARCH_Found;\r
                }\r
@@ -130,7 +130,7 @@ uint8_t NextBidirectionalPrinterInterface(void* CurrentDescriptor)
        return DESCRIPTOR_SEARCH_NotFound;\r
 }\r
 \r
-uint8_t NextInterfaceBulkDataEndpoint(void* CurrentDescriptor)\r
+uint8_t DComp_NextInterfaceBulkDataEndpoint(void* CurrentDescriptor)\r
 {\r
        /* PURPOSE: Find next interface bulk endpoint descriptor before next interface descriptor */\r
 \r
index bbe2372..3e24adc 100644 (file)
                #include <LUFA/Drivers/USB/USB.h>\r
                \r
                #include "PrinterHost.h"\r
+               #include "Lib/PrinterCommands.h"\r
                \r
        /* Macros: */\r
+               /** Interface Class value for the Printer Device class */\r
                #define PRINTER_CLASS                    0x07\r
+\r
+               /** Interface Subclass value for the Printer Device class */\r
                #define PRINTER_SUBCLASS                 0x01\r
+\r
+               /** Interface Protocol value for a Bidirectional communication encapsulation */\r
+               #define PRINTER_PROTOCOL                 0x02\r
                \r
-               #define PRINTER_DATA_OUT_PIPE            1\r
-               #define PRINTER_DATA_IN_PIPE             2\r
-               \r
+               /** Maximum size of a device configuration descriptor which can be processed by the host, in bytes */\r
                #define MAX_CONFIG_DESCRIPTOR_SIZE       512\r
 \r
        /* Enums: */\r
+               /** Enum for the possible return codes of the ProcessConfigurationDescriptor() function. */\r
                enum PrinterHost_GetConfigDescriptorDataCodes_t\r
                {\r
-                       SuccessfulConfigRead                 = 0,\r
-                       ControlError                         = 1,\r
-                       DescriptorTooLarge                   = 2,\r
-                       InvalidConfigDataReturned            = 3,\r
-                       NoInterfaceFound                     = 4,\r
-                       NoEndpointFound                      = 5,\r
+                       SuccessfulConfigRead            = 0, /**< Configuration Descriptor was processed successfully */\r
+                       ControlError                    = 1, /**< A control request to the device failed to complete successfully */\r
+                       DescriptorTooLarge              = 2, /**< The device's Configuration Descriptor is too large to process */\r
+                       InvalidConfigDataReturned       = 3, /**< The device returned an invalid Configuration Descriptor */\r
+                       NoInterfaceFound                = 4, /**< A compatible printer interface was not found in the device's Configuration Descriptor */\r
+                       NoEndpointFound                 = 5, /**< The printer data endpoints were not found in the device's Configuration Descriptor */\r
                };\r
        \r
        /* External Variables: */\r
+               /** Interface index of the Bidirectional Printer interface within the device, once the Configuration\r
+                *  Descriptor has been processed.\r
+                */\r
                uint8_t PrinterInterfaceNumber;\r
+               \r
+               /** Interface Alternate Setting index of the Bidirectional Printer interface within the device, once\r
+                *  the Configuration Descriptor has been processed.\r
+                */\r
                uint8_t PrinterAltSetting;\r
 \r
        /* Function Prototypes: */\r
                uint8_t ProcessConfigurationDescriptor(void);   \r
 \r
-               uint8_t NextBidirectionalPrinterInterface(void* CurrentDescriptor);\r
-               uint8_t NextInterfaceBulkDataEndpoint(void* CurrentDescriptor);\r
+               uint8_t DComp_NextBidirectionalPrinterInterface(void* CurrentDescriptor);\r
+               uint8_t DComp_NextInterfaceBulkDataEndpoint(void* CurrentDescriptor);\r
 \r
 #endif\r
index 9324a14..075b2d6 100644 (file)
 \r
 #include "PrinterCommands.h"\r
 \r
-uint8_t Printer_GetDeviceID(Device_ID_String_t* DeviceIDString)\r
+uint8_t Printer_SendData(char* PrinterCommands)\r
+{\r
+       uint8_t ErrorCode;\r
+\r
+       Pipe_SelectPipe(PRINTER_DATA_OUT_PIPE);\r
+       Pipe_Unfreeze();\r
+       \r
+       if ((ErrorCode = Pipe_Write_Stream_LE(PrinterCommands, strlen(PrinterCommands))) != PIPE_RWSTREAM_NoError)\r
+         return ErrorCode;\r
+\r
+       Pipe_ClearOUT();\r
+       while (!(Pipe_IsOUTReady()));\r
+       \r
+       Pipe_Freeze();\r
+\r
+       return PIPE_RWSTREAM_NoError;\r
+}\r
+\r
+/** Issues a Printer class Get Device ID command to the attached device, to retrieve the device ID string (which indicates\r
+ *  the accepted printer languages, the printer's model and other pertinent information).\r
+ *\r
+ *  \param[out] DeviceIDString Pointer to the destination where the returned string should be stored\r
+ *  \param[in] BufferSize  Size in bytes of the allocated buffer for the returned Device ID string\r
+ *\r
+ *  \return A value from the USB_Host_SendControlErrorCodes_t enum\r
+ */\r
+uint8_t Printer_GetDeviceID(char* DeviceIDString, uint8_t BufferSize)\r
 {\r
        uint8_t  ErrorCode = HOST_SENDCONTROL_Successful;\r
        uint16_t DeviceIDStringLength;\r
@@ -41,28 +67,34 @@ uint8_t Printer_GetDeviceID(Device_ID_String_t* DeviceIDString)
                        bRequest:      GET_DEVICE_ID,\r
                        wValue:        0,\r
                        wIndex:        0,\r
-                       wLength:       sizeof(DeviceIDString->Length),\r
+                       wLength:       sizeof(DeviceIDStringLength),\r
                };\r
 \r
-       if ((ErrorCode = USB_Host_SendControlRequest(DeviceIDString)) != HOST_SENDCONTROL_Successful)\r
+       if ((ErrorCode = USB_Host_SendControlRequest(&DeviceIDStringLength)) != HOST_SENDCONTROL_Successful)\r
          return ErrorCode;\r
        \r
-       DeviceIDStringLength = SwapEndian_16(DeviceIDString->Length);\r
+       DeviceIDStringLength = SwapEndian_16(DeviceIDStringLength);\r
 \r
-       /* Protect against overflow for the null terminator if the string length is equal to or larger than the buffer */\r
-       if (DeviceIDStringLength >= sizeof(DeviceIDString->String))\r
-         DeviceIDStringLength = sizeof(DeviceIDString->String) - 1;\r
+       if (DeviceIDStringLength > BufferSize)\r
+         DeviceIDStringLength = BufferSize;\r
 \r
-       USB_ControlRequest.wLength = DeviceIDStringLength;\r
+       USB_ControlRequest.wLength = (DeviceIDStringLength - 1);\r
        \r
        if ((ErrorCode = USB_Host_SendControlRequest(DeviceIDString)) != HOST_SENDCONTROL_Successful)\r
          return ErrorCode;\r
        \r
-       DeviceIDString->String[DeviceIDStringLength] = 0x00;\r
+       DeviceIDString[DeviceIDStringLength] = 0x00;\r
        \r
        return HOST_SENDCONTROL_Successful;\r
 }\r
 \r
+/** Issues a Printer class Get Port Status command to the attached device, to retrieve the current status flags of the\r
+ *  printer.\r
+ *\r
+ *  \param[out] PortStatus  Pointer to the destination where the printer's status flag values should be stored\r
+ *\r
+ *  \return A value from the USB_Host_SendControlErrorCodes_t enum\r
+ */\r
 uint8_t Printer_GetPortStatus(uint8_t* PortStatus)\r
 {\r
        USB_ControlRequest = (USB_Request_Header_t)\r
@@ -77,6 +109,11 @@ uint8_t Printer_GetPortStatus(uint8_t* PortStatus)
        return USB_Host_SendControlRequest(PortStatus);\r
 }\r
 \r
+/** Issues a Printer class Soft Reset command to the attached device, to reset the printer ready for new input without\r
+ *  physically cycling the printer's power.\r
+ *\r
+ *  \return A value from the USB_Host_SendControlErrorCodes_t enum\r
+ */\r
 uint8_t Printer_SoftReset(void)\r
 {\r
        USB_ControlRequest = (USB_Request_Header_t)\r
index e9c1d9f..01f1f14 100644 (file)
 \r
        /* Includes: */\r
                #include <avr/io.h>\r
+               #include <string.h>\r
 \r
                #include <LUFA/Drivers/USB/USB.h>\r
 \r
        /* Macros: */\r
-               #define PROTOCOL_UNIDIRECTIONAL      0x01\r
-               #define PROTOCOL_BIDIRECTIONAL       0x02\r
-               #define PROTOCOL_IEEE1284            0x03\r
-               \r
+               /** Printer class-specific request to retrieve the printer's ID string */\r
                #define GET_DEVICE_ID                0\r
+\r
+               /** Printer class-specific request to retrieve the printer's virtual port status flags */\r
                #define GET_PORT_STATUS              1\r
+\r
+               /** Printer class-specific request to soft-reset the device */\r
                #define SOFT_RESET                   2\r
 \r
-       /* Type Defines: */\r
-               typedef struct\r
-               {\r
-                       uint16_t Length;\r
-                       uint8_t  String[128];\r
-               } Device_ID_String_t;\r
+               /** Pipe number of the Printer data IN pipe */\r
+               #define PRINTER_DATA_IN_PIPE         1\r
+\r
+               /** Pipe number of the Printer data OUT pipe */\r
+               #define PRINTER_DATA_OUT_PIPE        2\r
                \r
        /* Function Prototypes: */\r
-               uint8_t Printer_GetDeviceID(Device_ID_String_t* DeviceIDString);\r
+               uint8_t Printer_SendData(char* PrinterCommands);\r
+               uint8_t Printer_GetDeviceID(char* DeviceIDString, uint8_t BufferSize);\r
                uint8_t Printer_GetPortStatus(uint8_t* PortStatus);\r
                uint8_t Printer_SoftReset(void);\r
        \r
index 643f919..ea179b6 100644 (file)
@@ -150,7 +150,7 @@ void USB_Printer_Host(void)
                        }\r
                        \r
                        /* Some printers use alternate settings to determine the communication protocol used - if so, send a SetInterface\r
-                        * request to switch to the interface alternate setting with the Bidirection protocol */\r
+                        * request to switch to the interface alternate setting with the Bidirectional protocol */\r
                        if (PrinterAltSetting)\r
                        {\r
                                USB_ControlRequest = (USB_Request_Header_t)\r
@@ -181,8 +181,8 @@ void USB_Printer_Host(void)
                case HOST_STATE_Configured:\r
                        puts_P(PSTR("Retrieving Device ID...\r\n"));\r
                \r
-                       Device_ID_String_t DeviceIDString;\r
-                       if ((ErrorCode = Printer_GetDeviceID(&DeviceIDString)) != HOST_SENDCONTROL_Successful)\r
+                       char DeviceIDString[128];\r
+                       if ((ErrorCode = Printer_GetDeviceID(DeviceIDString, sizeof(DeviceIDString))) != HOST_SENDCONTROL_Successful)\r
                        {\r
                                puts_P(PSTR("Control Error (Get DeviceID).\r\n"));\r
                                printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);\r
@@ -195,7 +195,7 @@ void USB_Printer_Host(void)
                                break;\r
                        }\r
 \r
-                       printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString.String);\r
+                       printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString);\r
 \r
                        puts_P(PSTR("Printer Enumerated.\r\n"));\r
                                        \r
@@ -205,30 +205,25 @@ void USB_Printer_Host(void)
                        /* Indicate device busy via the status LEDs */\r
                        LEDs_SetAllLEDs(LEDMASK_USB_BUSY);\r
                \r
-            //--------------------------------------------------------------\r
-                       #define TEST_TEXT_PAGE "\033%-12345X\033E LUFA PCL Test Page \033E\033%-12345X"\r
-//                     #define TEST_TEXT_PAGE "\033@\033i\001\033X\001\060\000\r\nLUFA ESCP/2 Test Page\r\n"\r
-                       #define PAGE_SIZE      (sizeof(TEST_TEXT_PAGE) - 1)\r
+                       char PCL_Test_Page[]   = "\033%-12345X\033E LUFA PCL Test Page \033E\033%-12345X";\r
+//                     char ESCP2_Test_Page[] =  "\033@\033i\001\033X\001\060\000\r\nLUFA ESCP/2 Test Page\r\n";\r
 \r
-                       Pipe_SelectPipe(PRINTER_DATA_OUT_PIPE);\r
-            Pipe_Unfreeze();\r
-                       \r
-                       puts_P(PSTR("Waiting for Printer to Become Ready...\r\n"));\r
-                       \r
-                       while (!(Pipe_IsReadWriteAllowed()));\r
+                       printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), strlen(PCL_Test_Page));\r
 \r
-                       printf_P(PSTR("Printer Write Allowed, Sending Page (%d bytes)...\r\n"), PAGE_SIZE);\r
-                               \r
-                       Pipe_Write_Stream_LE(TEST_TEXT_PAGE, PAGE_SIZE);\r
-            Pipe_ClearOUT();\r
+                       if ((ErrorCode = Printer_SendData(PCL_Test_Page)) != PIPE_RWSTREAM_NoError)\r
+                       {\r
+                               puts_P(PSTR("Error Sending Test Page.\r\n"));\r
+                               printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);\r
 \r
-                       puts_P(PSTR("Page Sent, Waiting for Pipe...\r\n"));\r
+                               /* Indicate error via status LEDs */\r
+                               LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
 \r
-                       while (!(Pipe_IsReadWriteAllowed()));\r
-            Pipe_Freeze();                             \r
+                               /* Wait until USB device disconnected */\r
+                               USB_HostState = HOST_STATE_WaitForDeviceRemoval;\r
+                               break;\r
+                       }\r
 \r
-                       puts_P(PSTR("Pipe Frozen.\r\n"));\r
-            //--------------------------------------------------------------\r
+                       puts_P(PSTR("Test Page Sent, Waiting for Pipe...\r\n"));\r
                \r
                        /* Indicate device no longer busy */\r
                        LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
index c0bbebf..5851349 100644 (file)
@@ -37,6 +37,7 @@
                #include <avr/pgmspace.h>\r
                #include <avr/power.h>\r
                #include <stdio.h>\r
+               #include <string.h>\r
 \r
                #include "ConfigDescriptor.h"\r
                #include "Lib/PrinterCommands.h"\r
index 62997d7..04d5d09 100644 (file)
@@ -49,7 +49,7 @@
   *  - Changed bootloaders to use FLASHEND rather than the existence of RAMPZ to determine if far FLASH pointers are needed to fix\r
   *    bootloaders on some of the USB AVR devices where avr-libc erronously defines RAMPZ\r
   *  - Fixes to MassStorageHost for better device compatibility (increase command timeout, change MassStore_WaitForDataReceived()\r
-  *    to only unfreeze and check one data pipe at a time) to prevent incorrect enumerations and freezes\r
+  *    to only unfreeze and check one data pipe at a time) to prevent incorrect device enumerations and freezes while trasferring data\r
   *  - Make Pipe_ConfigurePipe() mask the given endpoint number against PIPE_EPNUM_MASK to ensure the endpoint IN direction bit is\r
   *    cleared to prevent endpoint type corruption\r
   *  - Fix documentation mentioning Pipe_GetCurrentToken() function when real name is Pipe_GetPipeToken()\r