PrinterHost.c 8.29 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
             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.
*/

31
32
33
34
35
/** \file
 *
 *  Main source file for the PrinterHost demo. This file contains the main tasks of
 *  the demo and is responsible for the initial application hardware configuration.
 */
36
37
38

#include "PrinterHost.h"

39
40
41
/** Main program entry point. This routine configures the hardware required by the application, then
 *  starts the scheduler to run the application tasks.
 */
42
43
44
45
46
47
int main(void)
{
	SetupHardware();

	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);

48
	puts_P(PSTR(ESC_FG_CYAN "Printer Host Demo running.\r\n" ESC_FG_WHITE));
49
50
51
52
53
54
55
56
	
	for (;;)
	{
		USB_Printer_Host();
		USB_USBTask();
	}
}

57
/** Configures the board hardware and chip peripherals for the demo's functionality. */
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
void SetupHardware(void)
{
	/* Disable watchdog if enabled by bootloader/fuses */
	MCUSR &= ~(1 << WDRF);
	wdt_disable();

	/* Disable clock division */
	clock_prescale_set(clock_div_1);

	/* Hardware Initialization */
	SerialStream_Init(9600, false);
	LEDs_Init();
	USB_Init();
}

73
74
75
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
 *  starts the library USB task to begin the enumeration and USB management process.
 */
76
void EVENT_USB_Host_DeviceAttached(void)
77
{
78
	puts_P(PSTR(ESC_FG_GREEN "Device Attached.\r\n" ESC_FG_WHITE));
79
80
81
	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}

82
83
84
/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and
 *  stops the library USB task management process.
 */
85
void EVENT_USB_Host_DeviceUnattached(void)
86
{
87
	puts_P(PSTR(ESC_FG_GREEN "\r\nDevice Unattached.\r\n" ESC_FG_WHITE));
88
89
90
	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}

91
92
93
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
 *  enumerated by the host and is now ready to be used by the application.
 */
94
void EVENT_USB_Host_DeviceEnumerationComplete(void)
95
96
97
98
99
{
	LEDs_SetAllLEDs(LEDMASK_USB_READY);
}

/** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
100
void EVENT_USB_Host_HostError(uint8_t ErrorCode)
101
102
103
{
	USB_ShutDown();

104
105
	printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n"
	                         " -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode);
106
107
108
109
110

	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
	for(;;);
}

111
112
113
/** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while
 *  enumerating an attached USB device.
 */
114
void EVENT_USB_Host_DeviceEnumerationFailed(uint8_t ErrorCode, uint8_t SubErrorCode)
115
{
116
117
118
119
	printf_P(PSTR(ESC_FG_RED "Dev Enum Error\r\n"
	                         " -- Error Code %d\r\n"
	                         " -- Sub Error Code %d\r\n"
	                         " -- In State %d\r\n" ESC_FG_WHITE), ErrorCode, SubErrorCode, USB_HostState);
120
121
122
123

	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}

124
125
126
/** Task to set the configuration of the attached device after it has been enumerated, and to send some test page
 *  data to the attached printer.
 */
127
128
129
130
131
132
133
134
void USB_Printer_Host(void)
{
	uint8_t ErrorCode;

	switch (USB_HostState)
	{
		case HOST_STATE_Addressed:
			puts_P(PSTR("Getting Config Data.\r\n"));
135
136
137
			
			/* Select the control pipe for the request transfer */
			Pipe_SelectPipe(PIPE_CONTROLPIPE);			
138
139
140
141
142
		
			/* Get and process the configuration descriptor data */
			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
			{
				if (ErrorCode == ControlError)
143
				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
144
				else
145
				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
146
147
148
149

				printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);
				
				/* Indicate error via status LEDs */
150
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
151
152

				/* Wait until USB device disconnected */
153
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
154
155
				break;
			}
156
157
158
159
				
			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
			{
160
161
				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
162
163

				/* Indicate error via status LEDs */
164
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
165
166

				/* Wait until USB device disconnected */
167
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
168
169
				break;
			}
170
171
			
			/* Some printers use alternate settings to determine the communication protocol used - if so, send a SetInterface
172
			 * request to switch to the interface alternate setting with the Bidirectional protocol */
173
174
175
176
177
178
179
180
181
182
183
184
185
			if (PrinterAltSetting)
			{
				USB_ControlRequest = (USB_Request_Header_t)
					{
						bmRequestType: (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
						bRequest:      REQ_SetInterface,
						wValue:        PrinterAltSetting,
						wIndex:        PrinterInterfaceNumber,
						wLength:       0,
					};
					
				if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
				{
186
187
					printf_P(PSTR(ESC_FG_RED "Control Error (Set Interface).\r\n"
					                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
188
189
190
191
192
193
194
195
196
197

					/* Indicate error via status LEDs */
					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

					/* Wait until USB device disconnected */
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;					
				}
			}
			
198
199
			puts_P(PSTR("Retrieving Device ID...\r\n"));
		
200
			char DeviceIDString[300];
201
			if ((ErrorCode = Printer_GetDeviceID(DeviceIDString, sizeof(DeviceIDString))) != HOST_SENDCONTROL_Successful)
202
			{
203
				printf_P(PSTR(ESC_FG_RED "Control Error (Get Device ID).\r\n"
204
				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
205

206
				/* Indicate error via status LEDs */
207
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
208
209

				/* Wait until USB device disconnected */
210
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
211
212
				break;
			}
213

214
			printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString);
215
216

			puts_P(PSTR("Printer Enumerated.\r\n"));
217
218

			USB_HostState = HOST_STATE_Configured;
219
			break;
220
		case HOST_STATE_Configured:
221
222
223
			/* Indicate device busy via the status LEDs */
			LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
		
224
225
			char  TestPageData[]    = "\033%-12345X\033E" "LUFA PCL Test Page" "\033E\033%-12345X";
			uint16_t TestPageLength = strlen(TestPageData);
226
		
227
			printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), TestPageLength);
228

229
			if ((ErrorCode = Printer_SendData(&TestPageData, TestPageLength)) != PIPE_RWSTREAM_NoError)
230
			{
231
232
				printf_P(PSTR(ESC_FG_RED "Error Sending Test Page.\r\n"
				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
233

234
235
				/* Indicate error via status LEDs */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
236

237
238
239
240
				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}
241

242
			puts_P(PSTR("Test Page Sent.\r\n"));
243
244
		
			/* Indicate device no longer busy */
245
			LEDs_SetAllLEDs(LEDMASK_USB_READY);
246
247

			USB_HostState = HOST_STATE_WaitForDeviceRemoval;
248
249
250
			break;
	}
}