1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016,2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "usb_host_config.h"
10 #if ((defined USB_HOST_CONFIG_PRINTER) && (USB_HOST_CONFIG_PRINTER))
11 #include "usb_host.h"
12 #include "usb_host_printer.h"
13
14 /*******************************************************************************
15 * API
16 ******************************************************************************/
17
18 /*!
19 * @brief printer in pipe transfer callback.
20 *
21 * @param param callback parameter.
22 * @param transfer callback transfer.
23 * @param status transfer status.
24 */
25 static void USB_HostPrinterInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
26
27 /*!
28 * @brief printer out pipe transfer callback.
29 *
30 * @param param callback parameter.
31 * @param transfer callback transfer.
32 * @param status transfer status.
33 */
34 static void USB_HostPrinterOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
35
36 /*!
37 * @brief printer control pipe transfer callback.
38 *
39 * @param param callback parameter.
40 * @param transfer callback transfer.
41 * @param status transfer status.
42 */
43 static void USB_HostPrinterControlPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
44
45 /*!
46 * @brief printer open interface. It is called when set interface request success or open alternate setting 0 interface.
47 *
48 * @param printerInstance printer instance pointer.
49 *
50 * @return kStatus_USB_Success or error codes.
51 */
52 static usb_status_t USB_HostPrinterOpenInterface(usb_host_printer_instance_t *printerInstance);
53
54 /*!
55 * @brief printer set interface callback, open pipes.
56 *
57 * @param param callback parameter.
58 * @param transfer callback transfer.
59 * @param status transfer status.
60 */
61 static void USB_HostPrinterSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
62
63 /*!
64 * @brief printer send control transfer common code.
65 *
66 * @param classHandle the class handle.
67 * @param requestType setup packet request type.
68 * @param request setup packet request value.
69 * @param wvalue setup packet wValue.
70 * @param windex setup packet wIndex.
71 * @param wlength setup packet wlength value.
72 * @param data data buffer pointer
73 * @param callbackFn this callback is called after this function completes.
74 * @param callbackParam the first parameter in the callback function.
75 *
76 * @return An error code or kStatus_USB_Success.
77 */
78 static usb_status_t USB_HostPrinterControl(usb_host_printer_instance_t *printerInstance,
79 uint8_t requestType,
80 uint8_t request,
81 uint16_t wvalue,
82 uint16_t windex,
83 uint16_t wlength,
84 uint8_t *data,
85 transfer_callback_t callbackFn,
86 void *callbackParam);
87
88 /*******************************************************************************
89 * Definitions
90 ******************************************************************************/
91 /*******************************************************************************
92 * Prototypes
93 ******************************************************************************/
94 /*******************************************************************************
95 * Variables
96 ******************************************************************************/
97 /*******************************************************************************
98 * Code
99 ******************************************************************************/
100
101 #if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
USB_HostPrinterClearInHaltCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)102 static void USB_HostPrinterClearInHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
103 {
104 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
105
106 if (printerInstance->inCallbackFn != NULL)
107 {
108 /* callback to application, callback function is initialized in USB_HostPrinterRecv */
109 printerInstance->inCallbackFn(printerInstance->outCallbackParam, printerInstance->stallDataBuffer,
110 printerInstance->stallDataLength, kStatus_USB_TransferStall);
111 }
112 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
113 }
114
USB_HostPrinterClearOutHaltCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)115 static void USB_HostPrinterClearOutHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
116 {
117 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
118
119 if (printerInstance->outCallbackFn != NULL)
120 {
121 /* callback to application, callback function is initialized in USB_HostPrinterSend */
122 printerInstance->outCallbackFn(printerInstance->outCallbackParam, printerInstance->stallDataBuffer,
123 printerInstance->stallDataLength, kStatus_USB_TransferStall);
124 }
125 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
126 }
127
USB_HostPrinterClearHalt(usb_host_printer_instance_t * printerInstance,usb_host_transfer_t * stallTransfer,host_inner_transfer_callback_t callbackFn,uint8_t endpoint)128 static usb_status_t USB_HostPrinterClearHalt(usb_host_printer_instance_t *printerInstance,
129 usb_host_transfer_t *stallTransfer,
130 host_inner_transfer_callback_t callbackFn,
131 uint8_t endpoint)
132 {
133 usb_status_t status;
134 usb_host_transfer_t *transfer;
135
136 /* malloc one transfer */
137 status = USB_HostMallocTransfer(printerInstance->hostHandle, &transfer);
138 if (status != kStatus_USB_Success)
139 {
140 #ifdef HOST_ECHO
141 usb_echo("allocate transfer error\r\n");
142 #endif
143 return status;
144 }
145 printerInstance->stallDataBuffer = stallTransfer->transferBuffer;
146 printerInstance->stallDataLength = stallTransfer->transferSofar;
147 /* save the application callback function */
148 printerInstance->controlCallbackFn = NULL;
149 printerInstance->controlCallbackParam = NULL;
150 /* initialize transfer */
151 transfer->callbackFn = callbackFn;
152 transfer->callbackParam = printerInstance;
153 transfer->transferBuffer = NULL;
154 transfer->transferLength = 0;
155 transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_CLEAR_FEATURE;
156 transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
157 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT);
158 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(endpoint);
159 transfer->setupPacket->wLength = 0;
160 status = USB_HostSendSetup(printerInstance->hostHandle, printerInstance->controlPipe, transfer);
161
162 if (status != kStatus_USB_Success)
163 {
164 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
165 }
166 printerInstance->controlTransfer = transfer;
167
168 return status;
169 }
170 #endif
171
USB_HostPrinterInPipeCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)172 static void USB_HostPrinterInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
173 {
174 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
175
176 #if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
177 if (status == kStatus_USB_TransferStall)
178 {
179 if (USB_HostPrinterClearHalt(
180 printerInstance, transfer, USB_HostPrinterClearInHaltCallback,
181 (USB_REQUEST_TYPE_DIR_IN | ((usb_host_pipe_t *)printerInstance->inPipe)->endpointAddress)) ==
182 kStatus_USB_Success)
183 {
184 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
185 return;
186 }
187 }
188 #endif
189
190 if (printerInstance->inCallbackFn != NULL)
191 {
192 /* callback to application, callback function is initialized in USB_HostPrinterRecv */
193 printerInstance->inCallbackFn(printerInstance->inCallbackParam, transfer->transferBuffer,
194 transfer->transferSofar, status);
195 }
196 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
197 }
198
USB_HostPrinterOutPipeCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)199 static void USB_HostPrinterOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
200 {
201 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
202
203 #if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
204 if (status == kStatus_USB_TransferStall)
205 {
206 if (USB_HostPrinterClearHalt(
207 printerInstance, transfer, USB_HostPrinterClearOutHaltCallback,
208 (USB_REQUEST_TYPE_DIR_OUT | ((usb_host_pipe_t *)printerInstance->outPipe)->endpointAddress)) ==
209 kStatus_USB_Success)
210 {
211 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
212 return;
213 }
214 }
215 #endif
216 if (printerInstance->outCallbackFn != NULL)
217 {
218 /* callback to application, callback function is initialized in USB_HostPrinterSend */
219 printerInstance->outCallbackFn(printerInstance->outCallbackParam, transfer->transferBuffer,
220 transfer->transferSofar, status);
221 }
222 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
223 }
224
USB_HostPrinterControlPipeCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)225 static void USB_HostPrinterControlPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
226 {
227 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
228
229 printerInstance->controlTransfer = NULL;
230 if (printerInstance->controlCallbackFn != NULL)
231 {
232 /* callback to application, callback to application, callback function is initialized in the
233 USB_HostPrinterControl,
234 USB_HostPrinterSetInterface or USB_HostHubClassRequestCommon, but is the same function */
235 printerInstance->controlCallbackFn(printerInstance->controlCallbackParam, transfer->transferBuffer,
236 transfer->transferSofar, status);
237 }
238 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
239 }
240
USB_HostPrinterOpenInterface(usb_host_printer_instance_t * printerInstance)241 static usb_status_t USB_HostPrinterOpenInterface(usb_host_printer_instance_t *printerInstance)
242 {
243 usb_status_t status;
244 uint8_t epIndex = 0;
245 usb_host_pipe_init_t pipeInit;
246 usb_descriptor_endpoint_t *epDesc = NULL;
247 usb_host_interface_t *interfacePointer;
248
249 if (printerInstance->inPipe != NULL)
250 {
251 status = USB_HostClosePipe(printerInstance->hostHandle, printerInstance->inPipe);
252
253 if (status != kStatus_USB_Success)
254 {
255 #ifdef HOST_ECHO
256 usb_echo("error when close pipe\r\n");
257 #endif
258 }
259 printerInstance->inPipe = NULL;
260 }
261 if (printerInstance->outPipe != NULL) /* close interrupt out pipe if it is open */
262 {
263 status = USB_HostClosePipe(printerInstance->hostHandle, printerInstance->outPipe);
264
265 if (status != kStatus_USB_Success)
266 {
267 #ifdef HOST_ECHO
268 usb_echo("error when close pipe\r\n");
269 #endif
270 }
271 printerInstance->outPipe = NULL;
272 }
273
274 /* open interface pipes */
275 interfacePointer = (usb_host_interface_t *)printerInstance->interfaceHandle;
276 for (epIndex = 0; epIndex < interfacePointer->epCount; ++epIndex)
277 {
278 epDesc = interfacePointer->epList[epIndex].epDesc;
279 if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
280 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
281 ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_BULK))
282 {
283 pipeInit.devInstance = printerInstance->deviceHandle;
284 pipeInit.pipeType = USB_ENDPOINT_BULK;
285 pipeInit.direction = USB_IN;
286 pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
287 pipeInit.interval = epDesc->bInterval;
288 pipeInit.maxPacketSize = (uint16_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
289 USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK));
290 pipeInit.numberPerUframe = (uint8_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
291 USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK));
292 pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
293
294 printerInstance->inPacketSize = pipeInit.maxPacketSize;
295
296 status = USB_HostOpenPipe(printerInstance->hostHandle, &printerInstance->inPipe, &pipeInit);
297 if (status != kStatus_USB_Success)
298 {
299 #ifdef HOST_ECHO
300 usb_echo("USB_HostPrinterSetInterface fail to open pipe\r\n");
301 #endif
302 return kStatus_USB_Error;
303 }
304 }
305 else if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
306 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
307 ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_BULK))
308 {
309 pipeInit.devInstance = printerInstance->deviceHandle;
310 pipeInit.pipeType = USB_ENDPOINT_BULK;
311 pipeInit.direction = USB_OUT;
312 pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
313 pipeInit.interval = epDesc->bInterval;
314 pipeInit.maxPacketSize = (uint16_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
315 USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK));
316 pipeInit.numberPerUframe = (uint8_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
317 USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK));
318 pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
319
320 printerInstance->outPacketSize = pipeInit.maxPacketSize;
321
322 status = USB_HostOpenPipe(printerInstance->hostHandle, &printerInstance->outPipe, &pipeInit);
323 if (status != kStatus_USB_Success)
324 {
325 #ifdef HOST_ECHO
326 usb_echo("USB_HostPrinterSetInterface fail to open pipe\r\n");
327 #endif
328 return kStatus_USB_Error;
329 }
330 }
331 else
332 {
333 }
334 }
335
336 return kStatus_USB_Success;
337 }
338
USB_HostPrinterSetInterfaceCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)339 static void USB_HostPrinterSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
340 {
341 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
342
343 printerInstance->controlTransfer = NULL;
344 if (status == kStatus_USB_Success)
345 {
346 status = USB_HostPrinterOpenInterface(printerInstance); /* printer open interface */
347 }
348
349 if (printerInstance->controlCallbackFn != NULL)
350 {
351 /* callback to application, callback to application, callback function is initialized in the
352 USB_HostPrinterControl,
353 USB_HostPrinterSetInterface or USB_HostHubClassRequestCommon, but is the same function */
354 printerInstance->controlCallbackFn(printerInstance->controlCallbackParam, NULL, 0, status);
355 }
356 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
357 }
358
USB_HostPrinterInit(usb_device_handle deviceHandle,usb_host_class_handle * classHandle)359 usb_status_t USB_HostPrinterInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle)
360 {
361 uint32_t infoValue = 0U;
362 uint32_t *temp;
363 /* malloc printer class instance */
364 usb_host_printer_instance_t *printerInstance =
365 (usb_host_printer_instance_t *)OSA_MemoryAllocate(sizeof(usb_host_printer_instance_t));
366
367 if (printerInstance == NULL)
368 {
369 return kStatus_USB_AllocFail;
370 }
371
372 /* initialize printer instance */
373 printerInstance->deviceHandle = deviceHandle;
374 printerInstance->interfaceHandle = NULL;
375
376 (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetHostHandle, &infoValue);
377 temp = (uint32_t *)infoValue;
378 printerInstance->hostHandle = (usb_host_handle)temp;
379 (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceControlPipe, &infoValue);
380 temp = (uint32_t *)infoValue;
381 printerInstance->controlPipe = (usb_host_pipe_handle)temp;
382
383 *classHandle = printerInstance;
384 return kStatus_USB_Success;
385 }
386
USB_HostPrinterSetInterface(usb_host_class_handle classHandle,usb_host_interface_handle interfaceHandle,uint8_t alternateSetting,transfer_callback_t callbackFn,void * callbackParam)387 usb_status_t USB_HostPrinterSetInterface(usb_host_class_handle classHandle,
388 usb_host_interface_handle interfaceHandle,
389 uint8_t alternateSetting,
390 transfer_callback_t callbackFn,
391 void *callbackParam)
392 {
393 usb_status_t status;
394 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
395 usb_host_transfer_t *transfer;
396
397 if (classHandle == NULL)
398 {
399 return kStatus_USB_InvalidParameter;
400 }
401
402 /* notify host driver the interface is open */
403 status = USB_HostOpenDeviceInterface(printerInstance->deviceHandle, interfaceHandle);
404 if (status != kStatus_USB_Success)
405 {
406 return status;
407 }
408 printerInstance->interfaceHandle = interfaceHandle;
409
410 /* cancel transfers */
411 if (printerInstance->inPipe != NULL)
412 {
413 status = USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->inPipe, NULL);
414
415 if (status != kStatus_USB_Success)
416 {
417 #ifdef HOST_ECHO
418 usb_echo("error when cancel pipe\r\n");
419 #endif
420 }
421 }
422 if (printerInstance->outPipe != NULL)
423 {
424 status = USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->outPipe, NULL);
425
426 if (status != kStatus_USB_Success)
427 {
428 #ifdef HOST_ECHO
429 usb_echo("error when cancel pipe\r\n");
430 #endif
431 }
432 }
433
434 if (alternateSetting == 0U) /* open interface directly */
435 {
436 if (callbackFn != NULL)
437 {
438 status = USB_HostPrinterOpenInterface(printerInstance);
439 callbackFn(callbackParam, NULL, 0, status);
440 }
441 }
442 else /* send setup transfer */
443 {
444 /* malloc one transfer */
445 if (USB_HostMallocTransfer(printerInstance->hostHandle, &transfer) != kStatus_USB_Success)
446 {
447 #ifdef HOST_ECHO
448 usb_echo("error to get transfer\r\n");
449 #endif
450 return kStatus_USB_Error;
451 }
452
453 /* save the application callback function */
454 printerInstance->controlCallbackFn = callbackFn;
455 printerInstance->controlCallbackParam = callbackParam;
456 /* initialize transfer */
457 transfer->callbackFn = USB_HostPrinterSetInterfaceCallback;
458 transfer->callbackParam = printerInstance;
459 transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
460 transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
461 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
462 ((usb_host_interface_t *)printerInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber);
463 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
464 transfer->setupPacket->wLength = 0;
465 transfer->transferBuffer = NULL;
466 transfer->transferLength = 0;
467 status = USB_HostSendSetup(printerInstance->hostHandle, printerInstance->controlPipe, transfer);
468
469 if (status == kStatus_USB_Success)
470 {
471 printerInstance->controlTransfer = transfer;
472 }
473 else
474 {
475 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
476 }
477 }
478
479 return status;
480 }
481
USB_HostPrinterDeinit(usb_device_handle deviceHandle,usb_host_class_handle classHandle)482 usb_status_t USB_HostPrinterDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
483 {
484 usb_status_t status;
485 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
486
487 if (deviceHandle == NULL)
488 {
489 return kStatus_USB_InvalidHandle;
490 }
491
492 if (classHandle != NULL) /* class instance has initialized */
493 {
494 if (printerInstance->inPipe != NULL)
495 {
496 status =
497 USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->inPipe, NULL); /* cancel pipe */
498 if (status != kStatus_USB_Success)
499 {
500 #ifdef HOST_ECHO
501 usb_echo("error when cancel pipe\r\n");
502 #endif
503 }
504 status = USB_HostClosePipe(printerInstance->hostHandle, printerInstance->inPipe); /* close pipe */
505
506 if (status != kStatus_USB_Success)
507 {
508 #ifdef HOST_ECHO
509 usb_echo("error when close pipe\r\n");
510 #endif
511 }
512 printerInstance->inPipe = NULL;
513 }
514 if (printerInstance->outPipe != NULL)
515 {
516 status =
517 USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->outPipe, NULL); /* cancel pipe */
518 if (status != kStatus_USB_Success)
519 {
520 #ifdef HOST_ECHO
521 usb_echo("error when cancel pipe\r\n");
522 #endif
523 }
524 status = USB_HostClosePipe(printerInstance->hostHandle, printerInstance->outPipe); /* close pipe */
525
526 if (status != kStatus_USB_Success)
527 {
528 #ifdef HOST_ECHO
529 usb_echo("error when close pipe\r\n");
530 #endif
531 }
532 printerInstance->outPipe = NULL;
533 }
534 if ((printerInstance->controlPipe != NULL) &&
535 (printerInstance->controlTransfer !=
536 NULL)) /* cancel control transfer if there is on-going control transfer */
537 {
538 status = USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->controlPipe,
539 printerInstance->controlTransfer);
540 if (status != kStatus_USB_Success)
541 {
542 #ifdef HOST_ECHO
543 usb_echo("error when cancel pipe\r\n");
544 #endif
545 }
546 }
547 (void)USB_HostCloseDeviceInterface(
548 deviceHandle, printerInstance->interfaceHandle); /* notify host driver the interface is closed */
549 OSA_MemoryFree(printerInstance);
550 }
551 else
552 {
553 (void)USB_HostCloseDeviceInterface(deviceHandle, NULL);
554 }
555
556 return kStatus_USB_Success;
557 }
558
USB_HostPrinterRecv(usb_host_class_handle classHandle,uint8_t * buffer,uint32_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)559 usb_status_t USB_HostPrinterRecv(usb_host_class_handle classHandle,
560 uint8_t *buffer,
561 uint32_t bufferLength,
562 transfer_callback_t callbackFn,
563 void *callbackParam)
564 {
565 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
566 usb_host_transfer_t *transfer;
567
568 if (classHandle == NULL)
569 {
570 return kStatus_USB_InvalidHandle;
571 }
572
573 if (printerInstance->inPipe == NULL)
574 {
575 return kStatus_USB_Error;
576 }
577
578 /* malloc one transfer */
579 if (USB_HostMallocTransfer(printerInstance->hostHandle, &transfer) != kStatus_USB_Success)
580 {
581 #ifdef HOST_ECHO
582 usb_echo("error to get transfer\r\n");
583 #endif
584 return kStatus_USB_Busy;
585 }
586 /* save the application callback function */
587 printerInstance->inCallbackFn = callbackFn;
588 printerInstance->inCallbackParam = callbackParam;
589 /* initialize transfer */
590 transfer->transferBuffer = buffer;
591 transfer->transferLength = bufferLength;
592 transfer->callbackFn = USB_HostPrinterInPipeCallback;
593 transfer->callbackParam = printerInstance;
594
595 /* call host driver api */
596 if (USB_HostRecv(printerInstance->hostHandle, printerInstance->inPipe, transfer) != kStatus_USB_Success)
597 {
598 #ifdef HOST_ECHO
599 usb_echo("fail to USB_HostRecv\r\n");
600 #endif
601 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
602 return kStatus_USB_Error;
603 }
604
605 return kStatus_USB_Success;
606 }
607
USB_HostPrinterGetPacketsize(usb_host_class_handle classHandle,uint8_t pipeType,uint8_t direction)608 uint16_t USB_HostPrinterGetPacketsize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction)
609 {
610 usb_host_printer_instance_t *phdcInstance = (usb_host_printer_instance_t *)classHandle;
611 if (classHandle == NULL)
612 {
613 return 0;
614 }
615
616 if (pipeType == USB_ENDPOINT_INTERRUPT)
617 {
618 if (direction == USB_IN)
619 {
620 return phdcInstance->inPacketSize;
621 }
622 else
623 {
624 return phdcInstance->outPacketSize;
625 }
626 }
627
628 return 0;
629 }
630
USB_HostPrinterSend(usb_host_class_handle classHandle,uint8_t * buffer,uint32_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)631 usb_status_t USB_HostPrinterSend(usb_host_class_handle classHandle,
632 uint8_t *buffer,
633 uint32_t bufferLength,
634 transfer_callback_t callbackFn,
635 void *callbackParam)
636 {
637 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
638 usb_host_transfer_t *transfer;
639
640 if (classHandle == NULL)
641 {
642 return kStatus_USB_InvalidHandle;
643 }
644
645 if (printerInstance->outPipe == NULL)
646 {
647 return kStatus_USB_Error;
648 }
649
650 /* malloc one transfer */
651 if (USB_HostMallocTransfer(printerInstance->hostHandle, &transfer) != kStatus_USB_Success)
652 {
653 #ifdef HOST_ECHO
654 usb_echo("error to get transfer\r\n");
655 #endif
656 return kStatus_USB_Error;
657 }
658 /* save the application callback function */
659 printerInstance->outCallbackFn = callbackFn;
660 printerInstance->outCallbackParam = callbackParam;
661 /* initialize transfer */
662 transfer->transferBuffer = buffer;
663 transfer->transferLength = bufferLength;
664 transfer->callbackFn = USB_HostPrinterOutPipeCallback;
665 transfer->callbackParam = printerInstance;
666
667 /* call host driver api */
668 if (USB_HostSend(printerInstance->hostHandle, printerInstance->outPipe, transfer) != kStatus_USB_Success)
669 {
670 #ifdef HOST_ECHO
671 usb_echo("fail to USB_HostSend\r\n");
672 #endif
673 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
674 return kStatus_USB_Error;
675 }
676
677 return kStatus_USB_Success;
678 }
679
USB_HostPrinterControl(usb_host_printer_instance_t * printerInstance,uint8_t requestType,uint8_t request,uint16_t wvalue,uint16_t windex,uint16_t wlength,uint8_t * data,transfer_callback_t callbackFn,void * callbackParam)680 static usb_status_t USB_HostPrinterControl(usb_host_printer_instance_t *printerInstance,
681 uint8_t requestType,
682 uint8_t request,
683 uint16_t wvalue,
684 uint16_t windex,
685 uint16_t wlength,
686 uint8_t *data,
687 transfer_callback_t callbackFn,
688 void *callbackParam)
689 {
690 usb_host_transfer_t *transfer;
691
692 if (printerInstance == NULL)
693 {
694 return kStatus_USB_InvalidHandle;
695 }
696
697 if (USB_HostMallocTransfer(printerInstance->hostHandle, &transfer) != kStatus_USB_Success)
698 {
699 #ifdef HOST_ECHO
700 usb_echo("error to get transfer\r\n");
701 #endif
702 return kStatus_USB_Busy;
703 }
704 /* save the application callback function */
705 printerInstance->controlCallbackFn = callbackFn;
706 printerInstance->controlCallbackParam = callbackParam;
707 /* initialize transfer */
708 transfer->transferBuffer = data;
709 transfer->transferLength = wlength;
710 transfer->callbackFn = USB_HostPrinterControlPipeCallback;
711 transfer->callbackParam = printerInstance;
712 transfer->setupPacket->bmRequestType = requestType;
713 transfer->setupPacket->bRequest = request;
714 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(wvalue);
715 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(windex);
716 transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN(wlength);
717
718 /* call host driver api */
719 if (USB_HostSendSetup(printerInstance->hostHandle, printerInstance->controlPipe, transfer) != kStatus_USB_Success)
720 {
721 #ifdef HOST_ECHO
722 usb_echo("fail for USB_HostSendSetup\r\n");
723 #endif
724 (void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
725 return kStatus_USB_Error;
726 }
727 printerInstance->controlTransfer = transfer;
728
729 return kStatus_USB_Success;
730 }
731
USB_HostPrinterGetDeviceId(usb_host_class_handle classHandle,uint8_t interfaceIndex,uint8_t alternateSetting,uint8_t * buffer,uint32_t length,transfer_callback_t callbackFn,void * callbackParam)732 usb_status_t USB_HostPrinterGetDeviceId(usb_host_class_handle classHandle,
733 uint8_t interfaceIndex,
734 uint8_t alternateSetting,
735 uint8_t *buffer,
736 uint32_t length,
737 transfer_callback_t callbackFn,
738 void *callbackParam)
739 {
740 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
741 uint32_t infoValue = 0U;
742
743 (void)USB_HostHelperGetPeripheralInformation(printerInstance->deviceHandle, (uint32_t)kUSB_HostGetDeviceConfigIndex,
744 &infoValue);
745
746 return USB_HostPrinterControl(
747 printerInstance, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
748 USB_HOST_PRINTER_GET_DEVICE_ID, (uint16_t)infoValue,
749 (uint16_t)((uint16_t)((uint16_t)interfaceIndex << 8U) | alternateSetting), (uint16_t)length, buffer, callbackFn,
750 callbackParam);
751 }
752
USB_HostPrinterGetPortStatus(usb_host_class_handle classHandle,uint8_t * portStatus,transfer_callback_t callbackFn,void * callbackParam)753 usb_status_t USB_HostPrinterGetPortStatus(usb_host_class_handle classHandle,
754 uint8_t *portStatus,
755 transfer_callback_t callbackFn,
756 void *callbackParam)
757 {
758 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
759
760 return USB_HostPrinterControl(
761 printerInstance, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
762 USB_HOST_PRINTER_GET_PORT_STATUS, 0,
763 (uint16_t)(((usb_host_interface_t *)printerInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber), 1,
764 portStatus, callbackFn, callbackParam);
765 }
766
USB_HostPrinterSoftReset(usb_host_class_handle classHandle,transfer_callback_t callbackFn,void * callbackParam)767 usb_status_t USB_HostPrinterSoftReset(usb_host_class_handle classHandle,
768 transfer_callback_t callbackFn,
769 void *callbackParam)
770 {
771 usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
772
773 return USB_HostPrinterControl(
774 printerInstance, USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
775 USB_HOST_PRINTER_SOFT_RESET, 0,
776 (uint16_t)(((usb_host_interface_t *)printerInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber), 0,
777 NULL, callbackFn, callbackParam);
778 }
779
780 #endif /* USB_HOST_CONFIG_PRINTER */
781