| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
PrinterClassHost.c
Go to the documentation of this file.
1 /*
2 * @brief Host mode driver for the library USB Printer Class driver
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * Copyright(C) Dean Camera, 2011, 2012
7 * All rights reserved.
8 *
9 * @par
10 * Software that is described herein is for illustrative purposes only
11 * which provides customers with programming information regarding the
12 * LPC products. This software is supplied "AS IS" without any warranties of
13 * any kind, and NXP Semiconductors and its licensor disclaim any and
14 * all warranties, express or implied, including all implied warranties of
15 * merchantability, fitness for a particular purpose and non-infringement of
16 * intellectual property rights. NXP Semiconductors assumes no responsibility
17 * or liability for the use of the software, conveys no license or rights under any
18 * patent, copyright, mask work right, or any other intellectual property rights in
19 * or to any products. NXP Semiconductors reserves the right to make changes
20 * in the software without notification. NXP Semiconductors also makes no
21 * representation or warranty that such application will be suitable for the
22 * specified use without further testing or modification.
23 *
24 * @par
25 * Permission to use, copy, modify, and distribute this software and its
26 * documentation is hereby granted, under NXP Semiconductors' and its
27 * licensor's relevant copyrights in the software, without fee, provided that it
28 * is used in conjunction with NXP Semiconductors microcontrollers. This
29 * copyright, permission, and disclaimer notice must appear in all copies of
30 * this code.
31 */
32
33
34 #define __INCLUDE_FROM_USB_DRIVER
35 #include "../../Core/USBMode.h"
36
37 #if defined(USB_CAN_BE_HOST)
38
39 #define __INCLUDE_FROM_PRINTER_DRIVER
40 #define __INCLUDE_FROM_PRINTER_HOST_C
41 #include "PrinterClassHost.h"
42
43 uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
44 uint16_t ConfigDescriptorSize,
45 void* ConfigDescriptorData)
46 {
47 USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
48 USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
49 USB_Descriptor_Interface_t* PrinterInterface = NULL;
50 uint8_t portnum = PRNTInterfaceInfo->Config.PortNumber;
51
52 memset(&PRNTInterfaceInfo->State, 0x00, sizeof(PRNTInterfaceInfo->State));
53
54 if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
55 return PRNT_ENUMERROR_InvalidConfigDescriptor;
56
57 while (!(DataINEndpoint) || !(DataOUTEndpoint))
58 {
59 if (!(PrinterInterface) ||
60 USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
61 DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
62 {
63 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
64 DCOMP_PRNT_Host_NextPRNTInterface) != DESCRIPTOR_SEARCH_COMP_Found)
65 {
66 return PRNT_ENUMERROR_NoCompatibleInterfaceFound;
67 }
68
69 PrinterInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
70
71 DataINEndpoint = NULL;
72 DataOUTEndpoint = NULL;
73
74 continue;
75 }
76
77 USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
78
79 if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
80 DataINEndpoint = EndpointData;
81 else
82 DataOUTEndpoint = EndpointData;
83 }
84
85 for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
86 {
87 uint16_t Size;
88 uint8_t Type;
89 uint8_t Token;
90 uint8_t EndpointAddress;
91 bool DoubleBanked;
92
93 if (PipeNum == PRNTInterfaceInfo->Config.DataINPipeNumber)
94 {
95 Size = le16_to_cpu(DataINEndpoint->EndpointSize);
96 EndpointAddress = DataINEndpoint->EndpointAddress;
97 Token = PIPE_TOKEN_IN;
98 Type = EP_TYPE_BULK;
99 DoubleBanked = PRNTInterfaceInfo->Config.DataINPipeDoubleBank;
100
101 PRNTInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
102 }
103 else if (PipeNum == PRNTInterfaceInfo->Config.DataOUTPipeNumber)
104 {
105 Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
106 EndpointAddress = DataOUTEndpoint->EndpointAddress;
107 Token = PIPE_TOKEN_OUT;
108 Type = EP_TYPE_BULK;
109 DoubleBanked = PRNTInterfaceInfo->Config.DataOUTPipeDoubleBank;
110
111 PRNTInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
112 }
113 else
114 {
115 continue;
116 }
117
118 if (!(Pipe_ConfigurePipe(portnum,PipeNum, Type, Token, EndpointAddress, Size,
119 DoubleBanked ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE)))
120 {
121 return PRNT_ENUMERROR_PipeConfigurationFailed;
122 }
123 }
124
125 PRNTInterfaceInfo->State.InterfaceNumber = PrinterInterface->InterfaceNumber;
126 PRNTInterfaceInfo->State.AlternateSetting = PrinterInterface->AlternateSetting;
127 PRNTInterfaceInfo->State.IsActive = true;
128
129 return PRNT_ENUMERROR_NoError;
130 }
131
132 static uint8_t DCOMP_PRNT_Host_NextPRNTInterface(void* CurrentDescriptor)
133 {
134 USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
135
136 if (Header->Type == DTYPE_Interface)
137 {
138 USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
139
140 if ((Interface->Class == PRNT_CSCP_PrinterClass) &&
141 (Interface->SubClass == PRNT_CSCP_PrinterSubclass) &&
142 (Interface->Protocol == PRNT_CSCP_BidirectionalProtocol))
143 {
144 return DESCRIPTOR_SEARCH_Found;
145 }
146 }
147
148 return DESCRIPTOR_SEARCH_NotFound;
149 }
150
151 static uint8_t DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint(void* CurrentDescriptor)
152 {
153 USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
154
155 if (Header->Type == DTYPE_Endpoint)
156 {
157 USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
158
159 uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
160
161 if (EndpointType == EP_TYPE_BULK)
162 return DESCRIPTOR_SEARCH_Found;
163 }
164 else if (Header->Type == DTYPE_Interface)
165 {
166 return DESCRIPTOR_SEARCH_Fail;
167 }
168
169 return DESCRIPTOR_SEARCH_NotFound;
170 }
171
172 void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
173 {
174 if ((USB_HostState[PRNTInterfaceInfo->Config.PortNumber] != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
175 return;
176
177 #if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
178 PRNT_Host_Flush(PRNTInterfaceInfo);
179 #endif
180 }
181
182 uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
183 {
184 if (PRNTInterfaceInfo->State.AlternateSetting)
185 {
186 uint8_t ErrorCode;
187
188 if ((ErrorCode = USB_Host_SetInterfaceAltSetting(PRNTInterfaceInfo->Config.PortNumber,
189 PRNTInterfaceInfo->State.InterfaceNumber,
190 PRNTInterfaceInfo->State.AlternateSetting)) != HOST_SENDCONTROL_Successful)
191 {
192 return ErrorCode;
193 }
194 }
195
196 return HOST_SENDCONTROL_Successful;
197 }
198
199 uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
200 uint8_t* const PortStatus)
201 {
202 USB_ControlRequest = (USB_Request_Header_t)
203 {
204 .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
205 .bRequest = PRNT_REQ_GetPortStatus,
206 .wValue = 0,
207 .wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
208 .wLength = sizeof(uint8_t),
209 };
210 uint8_t portnum = PRNTInterfaceInfo->Config.PortNumber;
211
212 Pipe_SelectPipe(portnum,PIPE_CONTROLPIPE);
213 return USB_Host_SendControlRequest(portnum,PortStatus);
214 }
215
216 uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
217 {
218 USB_ControlRequest = (USB_Request_Header_t)
219 {
220 .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
221 .bRequest = PRNT_REQ_SoftReset,
222 .wValue = 0,
223 .wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
224 .wLength = 0,
225 };
226 uint8_t portnum = PRNTInterfaceInfo->Config.PortNumber;
227
228 Pipe_SelectPipe(portnum,PIPE_CONTROLPIPE);
229 return USB_Host_SendControlRequest(portnum,NULL);
230 }
231
232 uint8_t PRNT_Host_Flush(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
233 {
234 uint8_t portnum = PRNTInterfaceInfo->Config.PortNumber;
235 uint8_t ErrorCode;
236
237 if ((USB_HostState[portnum] != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
238 return PIPE_READYWAIT_DeviceDisconnected;
239
240 Pipe_SelectPipe(portnum,PRNTInterfaceInfo->Config.DataOUTPipeNumber);
241 Pipe_Unfreeze();
242
243 if (!(Pipe_BytesInPipe(portnum)))
244 return PIPE_READYWAIT_NoError;
245
246 bool BankFull = !(Pipe_IsReadWriteAllowed(portnum));
247
248 Pipe_ClearOUT(portnum);
249
250 if (BankFull)
251 {
252 if ((ErrorCode = Pipe_WaitUntilReady(portnum)) != PIPE_READYWAIT_NoError)
253 return ErrorCode;
254
255 Pipe_ClearOUT(portnum);
256 }
257
258 Pipe_Freeze();
259
260 return PIPE_READYWAIT_NoError;
261 }
262
263 uint8_t PRNT_Host_SendByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
264 const uint8_t Data)
265 {
266 uint8_t portnum = PRNTInterfaceInfo->Config.PortNumber;
267 uint8_t ErrorCode;
268 if ((USB_HostState[portnum] != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
269 return PIPE_READYWAIT_DeviceDisconnected;
270
271 Pipe_SelectPipe(portnum,PRNTInterfaceInfo->Config.DataOUTPipeNumber);
272 Pipe_Unfreeze();
273
274 if (!(Pipe_IsReadWriteAllowed(portnum)))
275 {
276 Pipe_ClearOUT(portnum);
277
278 if ((ErrorCode = Pipe_WaitUntilReady(portnum)) != PIPE_READYWAIT_NoError)
279 return ErrorCode;
280 }
281
282 Pipe_Write_8(portnum,Data);
283 Pipe_Freeze();
284
285 return PIPE_READYWAIT_NoError;
286 }
287
288 uint8_t PRNT_Host_SendString(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
289 void* String)
290 {
291 uint8_t ErrorCode;
292 uint8_t portnum = PRNTInterfaceInfo->Config.PortNumber;
293
294 if ((USB_HostState[portnum] != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
295 return PIPE_RWSTREAM_DeviceDisconnected;
296
297 Pipe_SelectPipe(portnum,PRNTInterfaceInfo->Config.DataOUTPipeNumber);
298 Pipe_Unfreeze();
299
300 if ((ErrorCode = Pipe_Write_Stream_LE(portnum,String, strlen(String), NULL)) != PIPE_RWSTREAM_NoError)
301 return ErrorCode;
302
303 Pipe_ClearOUT(portnum);
304
305 ErrorCode = Pipe_WaitUntilReady(portnum);
306
307 Pipe_Freeze();
308
309 return ErrorCode;
310 }
311
312 uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
313 void* Buffer,
314 const uint16_t Length)
315 {
316 uint8_t ErrorCode;
317 uint8_t portnum = PRNTInterfaceInfo->Config.PortNumber;
318
319 if ((USB_HostState[portnum] != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
320 return PIPE_RWSTREAM_DeviceDisconnected;
321
322 Pipe_SelectPipe(portnum,PRNTInterfaceInfo->Config.DataOUTPipeNumber);
323 Pipe_Unfreeze();
324
325 if ((ErrorCode = Pipe_Write_Stream_LE(portnum,Buffer, Length, NULL)) != PIPE_RWSTREAM_NoError)
326 return ErrorCode;
327
328 Pipe_ClearOUT(portnum);
329
330 ErrorCode = Pipe_WaitUntilReady(portnum);
331
332 Pipe_Freeze();
333
334 return ErrorCode;
335 }
336
337 uint16_t PRNT_Host_BytesReceived(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
338 {
339 uint8_t portnum = PRNTInterfaceInfo->Config.PortNumber;
340
341 if ((USB_HostState[portnum] != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
342 return 0;
343
344 Pipe_SelectPipe(portnum,PRNTInterfaceInfo->Config.DataINPipeNumber);
345 Pipe_Unfreeze();
346
347 if (Pipe_IsINReceived(portnum))
348 {
349 if (!(Pipe_BytesInPipe(portnum)))
350 {
351 Pipe_ClearIN(portnum);
352 Pipe_Freeze();
353 return 0;
354 }
355 else
356 {
357 Pipe_Freeze();
358 return Pipe_BytesInPipe(portnum);
359 }
360 }
361 else
362 {
363 Pipe_Freeze();
364
365 return 0;
366 }
367 }
368
369 int16_t PRNT_Host_ReceiveByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
370 {
371 uint8_t portnum = PRNTInterfaceInfo->Config.PortNumber;
372 int16_t ReceivedByte = -1;
373
374 if ((USB_HostState[portnum] != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
375 return PIPE_RWSTREAM_DeviceDisconnected;
376
377 Pipe_SelectPipe(portnum,PRNTInterfaceInfo->Config.DataINPipeNumber);
378 Pipe_Unfreeze();
379
380 if (Pipe_IsINReceived(portnum))
381 {
382 if (Pipe_BytesInPipe(portnum))
383 ReceivedByte = Pipe_Read_8(portnum);
384
385 if (!(Pipe_BytesInPipe(portnum)))
386 Pipe_ClearIN(portnum);
387 }
388
389 Pipe_Freeze();
390
391 return ReceivedByte;
392 }
393
394 uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
395 char* const DeviceIDString,
396 const uint16_t BufferSize)
397 {
398 uint8_t ErrorCode = HOST_SENDCONTROL_Successful;
399 uint16_t DeviceIDStringLength = 0;
400 uint8_t portnum = PRNTInterfaceInfo->Config.PortNumber;
401 USB_ControlRequest = (USB_Request_Header_t)
402 {
403 .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
404 .bRequest = PRNT_REQ_GetDeviceID,
405 .wValue = 0,
406 .wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
407 .wLength = sizeof(DeviceIDStringLength),
408 };
409
410 Pipe_SelectPipe(portnum,PIPE_CONTROLPIPE);
411
412 if ((ErrorCode = USB_Host_SendControlRequest(portnum,&DeviceIDStringLength)) != HOST_SENDCONTROL_Successful)
413 return ErrorCode;
414
415 if (!(DeviceIDStringLength))
416 {
417 DeviceIDString[0] = 0x00;
418 return HOST_SENDCONTROL_Successful;
419 }
420
421 DeviceIDStringLength = be16_to_cpu(DeviceIDStringLength);
422
423 if (DeviceIDStringLength > BufferSize)
424 DeviceIDStringLength = BufferSize;
425
426 USB_ControlRequest.wLength = DeviceIDStringLength;
427
428 if ((ErrorCode = USB_Host_SendControlRequest(portnum,DeviceIDString)) != HOST_SENDCONTROL_Successful)
429 return ErrorCode;
430
431 memmove(&DeviceIDString[0], &DeviceIDString[2], DeviceIDStringLength - 2);
432
433 DeviceIDString[DeviceIDStringLength - 2] = 0x00;
434
435 return HOST_SENDCONTROL_Successful;
436 }
437
438 #endif
439