|
|
@ -35,6 +35,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
#include "BootloaderPrinter.h"
|
|
|
|
#include "BootloaderPrinter.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** LUFA Printer Class driver interface configuration and state information. This structure is
|
|
|
|
|
|
|
|
* passed to all Printer Class driver functions, so that multiple instances of the same class
|
|
|
|
|
|
|
|
* within a device can be differentiated from one another.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
USB_ClassInfo_PRNT_Device_t TextOnly_Printer_Interface =
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
.Config =
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
.InterfaceNumber = 0,
|
|
|
|
|
|
|
|
.DataINEndpoint =
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
.Address = PRINTER_IN_EPADDR,
|
|
|
|
|
|
|
|
.Size = PRINTER_IO_EPSIZE,
|
|
|
|
|
|
|
|
.Banks = 1,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
.DataOUTEndpoint =
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
.Address = PRINTER_OUT_EPADDR,
|
|
|
|
|
|
|
|
.Size = PRINTER_IO_EPSIZE,
|
|
|
|
|
|
|
|
.Banks = 1,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
.IEEE1284String =
|
|
|
|
|
|
|
|
"MFG:Generic;"
|
|
|
|
|
|
|
|
"MDL:Generic_/_Text_Only;"
|
|
|
|
|
|
|
|
"CMD:1284.4;"
|
|
|
|
|
|
|
|
"CLS:PRINTER",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** Intel HEX parser state machine state information, to track the contents of
|
|
|
|
/** Intel HEX parser state machine state information, to track the contents of
|
|
|
|
* a HEX file streamed in as a sequence of arbitrary bytes.
|
|
|
|
* a HEX file streamed in as a sequence of arbitrary bytes.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -310,26 +339,25 @@ int main(void)
|
|
|
|
|
|
|
|
|
|
|
|
while (RunBootloader)
|
|
|
|
while (RunBootloader)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
USB_USBTask();
|
|
|
|
uint8_t BytesReceived = PRNT_Device_BytesReceived(&TextOnly_Printer_Interface);
|
|
|
|
|
|
|
|
|
|
|
|
Endpoint_SelectEndpoint(PRINTER_OUT_EPADDR);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Check if we have received new printer data from the host */
|
|
|
|
if (BytesReceived)
|
|
|
|
if (Endpoint_IsOUTReceived()) {
|
|
|
|
{
|
|
|
|
LEDs_ToggleLEDs(LEDMASK_USB_BUSY);
|
|
|
|
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
|
|
|
|
|
|
|
|
|
|
|
/* Read all bytes of data from the host and parse them */
|
|
|
|
while (BytesReceived--)
|
|
|
|
while (Endpoint_IsReadWriteAllowed())
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
int16_t ReceivedByte = PRNT_Device_ReceiveByte(&TextOnly_Printer_Interface);
|
|
|
|
|
|
|
|
|
|
|
|
/* Feed the next byte of data to the HEX parser */
|
|
|
|
/* Feed the next byte of data to the HEX parser */
|
|
|
|
ParseIntelHEXByte(Endpoint_Read_8());
|
|
|
|
ParseIntelHEXByte(ReceivedByte);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Send an ACK to the host, ready for the next data packet */
|
|
|
|
|
|
|
|
Endpoint_ClearOUT();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
|
|
|
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PRNT_Device_USBTask(&TextOnly_Printer_Interface);
|
|
|
|
|
|
|
|
USB_USBTask();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Disconnect from the host - USB interface will be reset later along with the AVR */
|
|
|
|
/* Disconnect from the host - USB interface will be reset later along with the AVR */
|
|
|
@ -397,8 +425,7 @@ void EVENT_USB_Device_ConfigurationChanged(void)
|
|
|
|
bool ConfigSuccess = true;
|
|
|
|
bool ConfigSuccess = true;
|
|
|
|
|
|
|
|
|
|
|
|
/* Setup Printer Data Endpoints */
|
|
|
|
/* Setup Printer Data Endpoints */
|
|
|
|
ConfigSuccess &= Endpoint_ConfigureEndpoint(PRINTER_IN_EPADDR, EP_TYPE_BULK, PRINTER_IO_EPSIZE, 1);
|
|
|
|
ConfigSuccess &= PRNT_Device_ConfigureEndpoints(&TextOnly_Printer_Interface);
|
|
|
|
ConfigSuccess &= Endpoint_ConfigureEndpoint(PRINTER_OUT_EPADDR, EP_TYPE_BULK, PRINTER_IO_EPSIZE, 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Indicate endpoint configuration success or failure */
|
|
|
|
/* Indicate endpoint configuration success or failure */
|
|
|
|
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
|
|
|
|
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
|
|
|
@ -410,58 +437,5 @@ void EVENT_USB_Device_ConfigurationChanged(void)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void EVENT_USB_Device_ControlRequest(void)
|
|
|
|
void EVENT_USB_Device_ControlRequest(void)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* Process Printer specific control requests */
|
|
|
|
PRNT_Device_ProcessControlRequest(&TextOnly_Printer_Interface);
|
|
|
|
switch (USB_ControlRequest.bRequest)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case PRNT_REQ_GetDeviceID:
|
|
|
|
|
|
|
|
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Generic printer IEEE 1284 identification string, will bind to an in-built driver on
|
|
|
|
|
|
|
|
* Windows systems, and will fall-back to a text-only printer driver on *nix.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
const char PrinterIDString[] =
|
|
|
|
|
|
|
|
"MFG:Generic;"
|
|
|
|
|
|
|
|
"MDL:Generic_/_Text_Only;"
|
|
|
|
|
|
|
|
"CMD:1284.4;"
|
|
|
|
|
|
|
|
"CLS:PRINTER";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Endpoint_ClearSETUP();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (!(Endpoint_IsINReady()))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Endpoint_Write_16_BE(sizeof(PrinterIDString));
|
|
|
|
|
|
|
|
Endpoint_Write_Control_Stream_LE(PrinterIDString, strlen(PrinterIDString));
|
|
|
|
|
|
|
|
Endpoint_ClearStatusStage();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PRNT_REQ_GetPortStatus:
|
|
|
|
|
|
|
|
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Endpoint_ClearSETUP();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (!(Endpoint_IsINReady()))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Endpoint_Write_8(PRNT_PORTSTATUS_NOTERROR | PRNT_PORTSTATUS_SELECT);
|
|
|
|
|
|
|
|
Endpoint_ClearStatusStage();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PRNT_REQ_SoftReset:
|
|
|
|
|
|
|
|
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Endpoint_ClearSETUP();
|
|
|
|
|
|
|
|
Endpoint_ClearStatusStage();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|