Make device mode configure the control endpoint even before the bus has been reset...
[pub/USBasp.git] / LUFA / Drivers / USB / Class / Host / Printer.c
index 428ea66..99977e5 100644 (file)
@@ -36,7 +36,8 @@
 #define  __INCLUDE_FROM_PRINTER_DRIVER
 #include "Printer.h"
 
-uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint16_t ConfigDescriptorSize,
+uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+                                 uint16_t ConfigDescriptorSize,
                                                             void* DeviceConfigDescriptor)
 {
        uint8_t FoundEndpoints = 0;
@@ -124,6 +125,11 @@ static uint8_t DCOMP_PRNT_NextPRNTInterfaceEndpoint(void* CurrentDescriptor)
        return DESCRIPTOR_SEARCH_NotFound;
 }
 
+void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+       PRNT_Host_Flush(PRNTInterfaceInfo);
+}
+
 uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
 {
        if (PRNTInterfaceInfo->State.AlternateSetting)
@@ -148,7 +154,8 @@ uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInte
        return HOST_SENDCONTROL_Successful;
 }
 
-uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, uint8_t* const PortStatus)
+uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+                                uint8_t* const PortStatus)
 {
        USB_ControlRequest = (USB_Request_Header_t)
                {
@@ -169,10 +176,10 @@ 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,
+                       .bRequest      = REQ_SoftReset,
+                       .wValue        = 0,
+                       .wIndex        = PRNTInterfaceInfo->State.InterfaceNumber,
+                       .wLength       = 0,
                };
 
        Pipe_SelectPipe(PIPE_CONTROLPIPE);
@@ -180,7 +187,64 @@ uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
        return USB_Host_SendControlRequest(NULL);
 }
 
-uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, void* PrinterCommands, const uint16_t CommandSize)
+uint8_t PRNT_Host_Flush(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+       if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
+         return PIPE_READYWAIT_DeviceDisconnected;
+         
+       uint8_t ErrorCode;
+
+       Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber);   
+       Pipe_Unfreeze();
+       
+       if (!(Pipe_BytesInPipe()))
+         return PIPE_READYWAIT_NoError;
+
+       bool BankFull = !(Pipe_IsReadWriteAllowed());
+
+       Pipe_ClearOUT();
+
+       if (BankFull)
+       {
+               if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
+                 return ErrorCode;
+
+               Pipe_ClearOUT();
+       }
+
+       Pipe_Freeze();
+       
+       return PIPE_READYWAIT_NoError;
+}
+
+uint8_t PRNT_Host_SendByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+                           const uint8_t Data)
+{
+       if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
+         return PIPE_READYWAIT_DeviceDisconnected;
+         
+       uint8_t ErrorCode;
+
+       Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber);   
+       Pipe_Unfreeze();
+       
+       if (!(Pipe_IsReadWriteAllowed()))
+       {
+               Pipe_ClearOUT();
+
+               if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
+                 return ErrorCode;
+       }
+
+       Pipe_Write_Byte(Data);  
+       Pipe_Freeze();
+       
+       return PIPE_READYWAIT_NoError;
+}
+
+uint8_t PRNT_Host_SendString(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+                             void* Buffer,
+                             const uint16_t Length)
 {
        uint8_t ErrorCode;
 
@@ -190,22 +254,75 @@ uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, v
        Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber);
        Pipe_Unfreeze();
        
-       if ((ErrorCode = Pipe_Write_Stream_LE(PrinterCommands, CommandSize, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+       if ((ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
          return ErrorCode;
 
        Pipe_ClearOUT();
-       while (!(Pipe_IsOUTReady()))
+       
+       ErrorCode = Pipe_WaitUntilReady();
+       
+       Pipe_Freeze();
+
+       return ErrorCode;
+}
+
+uint16_t PRNT_Host_BytesReceived(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+       if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
+         return 0;
+       
+       Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataINPipeNumber);
+       Pipe_Unfreeze();
+
+       if (Pipe_IsINReceived())
+       {
+               if (!(Pipe_BytesInPipe()))
+               {
+                       Pipe_ClearIN();
+                       Pipe_Freeze();
+                       return 0;
+               }
+               else
+               {
+                       Pipe_Freeze();
+                       return Pipe_BytesInPipe();
+               }
+       }
+       else
+       {
+               Pipe_Freeze();
+               
+               return 0;
+       }
+}
+
+int16_t PRNT_Host_ReceiveByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+       if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
+         return PIPE_RWSTREAM_DeviceDisconnected;
+
+       int16_t ReceivedByte = -1;
+
+       Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataINPipeNumber);
+       Pipe_Unfreeze();
+
+       if (Pipe_IsINReceived())
        {
-               if (USB_HostState == HOST_STATE_Unattached)
-                 return PIPE_RWSTREAM_DeviceDisconnected;
+               if (Pipe_BytesInPipe())
+                 ReceivedByte = Pipe_Read_Byte();
+
+               if (!(Pipe_BytesInPipe()))
+                 Pipe_ClearIN();
        }
        
        Pipe_Freeze();
 
-       return PIPE_RWSTREAM_NoError;
+       return ReceivedByte;
 }
 
-uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, char* DeviceIDString, const uint16_t BufferSize)
+uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+                              char* const DeviceIDString,
+                              const uint16_t BufferSize)
 {
        uint8_t  ErrorCode = HOST_SENDCONTROL_Successful;
        uint16_t DeviceIDStringLength = 0;