LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 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)
56 
57  while (!(DataINEndpoint) || !(DataOUTEndpoint))
58  {
59  if (!(PrinterInterface) ||
60  USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
62  {
63  if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
65  {
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  {
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 {
135 
136  if (Header->Type == DTYPE_Interface)
137  {
139 
140  if ((Interface->Class == PRNT_CSCP_PrinterClass) &&
141  (Interface->SubClass == PRNT_CSCP_PrinterSubclass) &&
142  (Interface->Protocol == PRNT_CSCP_BidirectionalProtocol))
143  {
145  }
146  }
147 
149 }
150 
151 static uint8_t DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint(void* CurrentDescriptor)
152 {
154 
155  if (Header->Type == DTYPE_Endpoint)
156  {
158 
159  uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
160 
161  if (EndpointType == EP_TYPE_BULK)
163  }
164  else if (Header->Type == DTYPE_Interface)
165  {
166  return DESCRIPTOR_SEARCH_Fail;
167  }
168 
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 
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 
197 }
198 
199 uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
200  uint8_t* const PortStatus)
201 {
203  {
204  .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
206  .wValue = 0,
207  .wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
208  .wLength = sizeof(uint8_t),
209  };
210  uint8_t portnum = PRNTInterfaceInfo->Config.PortNumber;
211 
213  return USB_Host_SendControlRequest(portnum,PortStatus);
214 }
215 
216 uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
217 {
219  {
220  .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
222  .wValue = 0,
223  .wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
224  .wLength = 0,
225  };
226  uint8_t portnum = PRNTInterfaceInfo->Config.PortNumber;
227 
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))
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))
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))
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))
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))
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;
402  {
403  .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
405  .wValue = 0,
406  .wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
407  .wLength = sizeof(DeviceIDStringLength),
408  };
409 
411 
412  if ((ErrorCode = USB_Host_SendControlRequest(portnum,&DeviceIDStringLength)) != HOST_SENDCONTROL_Successful)
413  return ErrorCode;
414 
415  if (!(DeviceIDStringLength))
416  {
417  DeviceIDString[0] = 0x00;
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 
436 }
437 
438 #endif
439