1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "usb_device_config.h"
10 #include "usb.h"
11 #include "usb_device.h"
12
13 #include "usb_device_class.h"
14
15 #if ((defined(USB_DEVICE_CONFIG_PRINTER)) && (USB_DEVICE_CONFIG_PRINTER > 0U))
16 #include "usb_device_printer.h"
17
18 /*******************************************************************************
19 * Definitions
20 ******************************************************************************/
21
22 /*******************************************************************************
23 * Prototypes
24 ******************************************************************************/
25
26 /*******************************************************************************
27 * Variables
28 ******************************************************************************/
29
USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE)30 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_printer_struct_t
31 s_PrinterHandle[USB_DEVICE_CONFIG_PRINTER];
32
33 /*******************************************************************************
34 * Code
35 ******************************************************************************/
36
37 static usb_status_t USB_DevicePrinterAllocateHandle(usb_device_printer_struct_t **printerHandle)
38 {
39 uint8_t index;
40
41 for (index = 0; index < USB_DEVICE_CONFIG_PRINTER; ++index)
42 {
43 if (s_PrinterHandle[index].deviceHandle == NULL)
44 {
45 *printerHandle = &(s_PrinterHandle[index]);
46 return kStatus_USB_Success;
47 }
48 }
49
50 return kStatus_USB_Busy;
51 }
52
USB_DevicePrinterFreeHandle(usb_device_printer_struct_t * printerHandle)53 static usb_status_t USB_DevicePrinterFreeHandle(usb_device_printer_struct_t *printerHandle)
54 {
55 /* ensure that printerHandle is not NULL before calling this function */
56 printerHandle->deviceHandle = NULL;
57 printerHandle->classConfig = NULL;
58 printerHandle->alternate = 0xFFu;
59 printerHandle->configuration = 0;
60 printerHandle->interfaceNumber = 0;
61
62 return kStatus_USB_Success;
63 }
64
65 /*!
66 * @brief bulk IN endpoint callback function.
67 *
68 * This callback function is used to notify upper layer the transfer result of a transfer.
69 * This callback pointer is passed when the bulk IN pipe initialized.
70 *
71 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
72 * @param message The result of the bulk IN pipe transfer.
73 * @param callbackParam The parameter for this callback. It is same with
74 * usb_device_endpoint_callback_struct_t::callbackParam.
75 * In the class, the value is the printer class handle.
76 *
77 * @retval kStatus_USB_Success The transfer is successful.
78 * @retval kStatus_USB_InvalidHandle The device handle not be found.
79 */
USB_DevicePrinterBulkInCallback(usb_device_handle handle,usb_device_endpoint_callback_message_struct_t * message,void * callbackParam)80 static usb_status_t USB_DevicePrinterBulkInCallback(usb_device_handle handle,
81 usb_device_endpoint_callback_message_struct_t *message,
82 void *callbackParam)
83 {
84 usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)callbackParam;
85 usb_status_t status = kStatus_USB_Error;
86
87 if (callbackParam == NULL)
88 {
89 return kStatus_USB_InvalidHandle;
90 }
91
92 printerHandle->bulkInBusy = 0U;
93 if ((NULL != printerHandle->classConfig) && (NULL != printerHandle->classConfig->classCallback))
94 {
95 /* Notify the application data received by calling the printer class callback.
96 ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
97 it is from the second parameter of classInit */
98 status = printerHandle->classConfig->classCallback((class_handle_t)printerHandle,
99 kUSB_DevicePrinterEventSendResponse, message);
100 }
101
102 return status;
103 }
104
105 /*!
106 * @brief bulk OUT endpoint callback function.
107 *
108 * This callback function is used to notify upper layer the transfer result of a transfer.
109 * This callback pointer is passed when the bulk OUT pipe initialized.
110 *
111 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
112 * @param message The result of the bulk OUT pipe transfer.
113 * @param callbackParam The parameter for this callback. It is same with
114 * usb_device_endpoint_callback_struct_t::callbackParam.
115 * In the class, the value is the printer class handle.
116 *
117 * @retval kStatus_USB_Success The transfer is successful.
118 * @retval kStatus_USB_InvalidHandle The device handle not be found.
119 */
USB_DevicePrinterBulkOutCallback(usb_device_handle handle,usb_device_endpoint_callback_message_struct_t * message,void * callbackParam)120 static usb_status_t USB_DevicePrinterBulkOutCallback(usb_device_handle handle,
121 usb_device_endpoint_callback_message_struct_t *message,
122 void *callbackParam)
123 {
124 usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)callbackParam;
125 usb_status_t status = kStatus_USB_Error;
126
127 if (printerHandle == NULL)
128 {
129 return kStatus_USB_InvalidHandle;
130 }
131 printerHandle->bulkOutBusy = 0U;
132 if ((NULL != printerHandle->classConfig) && (NULL != printerHandle->classConfig->classCallback))
133 {
134 /* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
135 it is from the second parameter of classInit */
136 status = printerHandle->classConfig->classCallback((class_handle_t)printerHandle,
137 kUSB_DevicePrinterEventRecvResponse, message);
138 }
139
140 return status;
141 }
142
143 /*!
144 * @brief Initialize the endpoints of the printer class.
145 *
146 * This callback function is used to initialize the endpoints of the printer class.
147 *
148 * @param printerHandle The device printer class handle. It equals the value returned from
149 * usb_device_class_config_struct_t::classHandle.
150 *
151 * @return A USB error code or kStatus_USB_Success.
152 */
USB_DevicePrinterEndpointsInit(usb_device_printer_struct_t * printerHandle)153 static usb_status_t USB_DevicePrinterEndpointsInit(usb_device_printer_struct_t *printerHandle)
154 {
155 /* ensure that printerHandle is not NULL before calling this function */
156 usb_device_interface_list_t *configInterfaceList;
157 usb_device_interface_struct_t *interface = NULL;
158 usb_status_t status = kStatus_USB_Error;
159 uint8_t interfaceIndex;
160 uint8_t index;
161
162 /* return error when configuration is invalid (0 or more than the configuration number) */
163 if ((printerHandle->configuration == 0U) ||
164 (printerHandle->configuration > printerHandle->classConfig->classInfomation->configurations))
165 {
166 return status;
167 }
168
169 configInterfaceList =
170 &(printerHandle->classConfig->classInfomation->interfaceList[printerHandle->configuration - 1U]);
171 for (interfaceIndex = 0; interfaceIndex < configInterfaceList->count; ++interfaceIndex)
172 {
173 if (USB_DEVICE_CONFIG_PRINTER_CLASS_CODE == configInterfaceList->interfaces[interfaceIndex].classCode)
174 {
175 /* index means the alternate interface's index here */
176 for (index = 0; index < configInterfaceList->interfaces[interfaceIndex].count; ++index)
177 {
178 if (configInterfaceList->interfaces[interfaceIndex].interface[index].alternateSetting ==
179 printerHandle->alternate)
180 {
181 interface = &(configInterfaceList->interfaces[interfaceIndex].interface[index]);
182 break;
183 }
184 }
185 printerHandle->interfaceNumber = configInterfaceList->interfaces[interfaceIndex].interfaceNumber;
186 break;
187 }
188 }
189 if (interface == NULL)
190 {
191 return status;
192 }
193
194 /* Keep new interface handle. */
195 printerHandle->interfaceHandle = interface;
196
197 /* Initialize the endpoints of the new interface. */
198 /* index means the endpoint's index here */
199 for (index = 0; index < interface->endpointList.count; ++index)
200 {
201 usb_device_endpoint_init_struct_t epInitStruct;
202 usb_device_endpoint_callback_struct_t epCallback;
203 epInitStruct.zlt = 0U;
204 epInitStruct.interval = interface->endpointList.endpoint[index].interval;
205 epInitStruct.endpointAddress = interface->endpointList.endpoint[index].endpointAddress;
206 epInitStruct.maxPacketSize = interface->endpointList.endpoint[index].maxPacketSize;
207 epInitStruct.transferType = interface->endpointList.endpoint[index].transferType;
208
209 if (((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
210 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT) == USB_IN)
211 {
212 epCallback.callbackFn = USB_DevicePrinterBulkInCallback;
213 printerHandle->bulkInPipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER;
214 printerHandle->bulkInPipeStall = 0U;
215 printerHandle->bulkInPipeDataLen = 0U;
216 }
217 else
218 {
219 epCallback.callbackFn = USB_DevicePrinterBulkOutCallback;
220 printerHandle->bulkOutPipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER;
221 printerHandle->bulkOutPipeStall = 0U;
222 printerHandle->bulkOutPipeDataLen = 0U;
223 }
224 epCallback.callbackParam = printerHandle;
225
226 status = USB_DeviceInitEndpoint(printerHandle->deviceHandle, &epInitStruct, &epCallback);
227 }
228
229 return status;
230 }
231
232 /*!
233 * @brief De-initialize the endpoints of the printer class.
234 *
235 * This callback function is used to de-initialize the endpoints of the printer class.
236 *
237 * @param printerHandle The device printer class handle. It equals the value returned from
238 * usb_device_class_config_struct_t::classHandle.
239 *
240 * @return A USB error code or kStatus_USB_Success.
241 */
USB_DevicePrinterEndpointsDeinit(usb_device_printer_struct_t * printerHandle)242 static usb_status_t USB_DevicePrinterEndpointsDeinit(usb_device_printer_struct_t *printerHandle)
243 {
244 /* ensure that printerHandle is not NULL before calling this function */
245 usb_status_t status = kStatus_USB_Error;
246 uint8_t index;
247
248 /* return directly when the interfaceHandle is NULL, it means USB_DevicePrinterEndpointsInit is not called */
249 if (printerHandle->interfaceHandle == NULL)
250 {
251 return kStatus_USB_Success;
252 }
253
254 for (index = 0; index < printerHandle->interfaceHandle->endpointList.count; ++index)
255 {
256 status = USB_DeviceDeinitEndpoint(printerHandle->deviceHandle,
257 printerHandle->interfaceHandle->endpointList.endpoint[index].endpointAddress);
258 }
259 printerHandle->interfaceHandle = NULL;
260
261 return status;
262 }
263
USB_DevicePrinterInit(uint8_t controllerId,usb_device_class_config_struct_t * config,class_handle_t * handle)264 usb_status_t USB_DevicePrinterInit(uint8_t controllerId,
265 usb_device_class_config_struct_t *config,
266 class_handle_t *handle)
267
268 {
269 usb_device_handle deviceHandle;
270 usb_device_printer_struct_t *printerHandle = NULL;
271 usb_status_t status;
272 OSA_SR_ALLOC();
273
274 /* get the controller's device handle */
275 status = USB_DeviceClassGetDeviceHandle(controllerId, &deviceHandle);
276 if (status != kStatus_USB_Success)
277 {
278 return status;
279 }
280 if (deviceHandle == NULL)
281 {
282 return kStatus_USB_InvalidHandle;
283 }
284
285 /* Allocate a printer class handle. */
286 OSA_ENTER_CRITICAL();
287 status = USB_DevicePrinterAllocateHandle(&printerHandle);
288 printerHandle->deviceHandle = deviceHandle; /* this printer instance is used */
289 OSA_EXIT_CRITICAL();
290 if (status != kStatus_USB_Success)
291 {
292 return status;
293 }
294
295 printerHandle->classConfig = config;
296 printerHandle->alternate = 0xFFU;
297 printerHandle->configuration = 0U;
298 printerHandle->interfaceNumber = 0U;
299 printerHandle->interfaceHandle = NULL;
300
301 *handle = (class_handle_t)printerHandle;
302
303 return status;
304 }
305
USB_DevicePrinterDeinit(class_handle_t handle)306 usb_status_t USB_DevicePrinterDeinit(class_handle_t handle)
307 {
308 usb_status_t status;
309 usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)handle;
310
311 if (NULL == handle)
312 {
313 return kStatus_USB_InvalidHandle;
314 }
315
316 status = USB_DevicePrinterEndpointsDeinit(printerHandle);
317 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
318 if (kStatus_USB_Success != USB_DevicePrinterFreeHandle(printerHandle))
319 {
320 return kStatus_USB_Error;
321 }
322 #else
323 (void)USB_DevicePrinterFreeHandle(printerHandle);
324 #endif
325 return status;
326 }
327
USB_DevicePrinterEvent(void * handle,uint32_t event,void * param)328 usb_status_t USB_DevicePrinterEvent(void *handle, uint32_t event, void *param)
329 {
330 usb_status_t status = kStatus_USB_Error;
331 usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)handle;
332 uint16_t temp16;
333 uint8_t temp8;
334 usb_device_class_event_t eventCode = (usb_device_class_event_t)event;
335
336 if ((handle == NULL) || (param == NULL))
337 {
338 return kStatus_USB_InvalidHandle;
339 }
340
341 switch (eventCode)
342 {
343 case kUSB_DeviceClassEventDeviceReset:
344 /* de-initialize printer instance */
345 printerHandle->interfaceHandle = NULL;
346 printerHandle->alternate = 0xFFU;
347 printerHandle->configuration = 0U;
348 printerHandle->interfaceNumber = 0U;
349 printerHandle->bulkInBusy = 0U;
350 printerHandle->bulkOutBusy = 0U;
351 status = kStatus_USB_Success;
352 break;
353
354 case kUSB_DeviceClassEventSetConfiguration:
355 temp8 = *((uint8_t *)param);
356 if (printerHandle->classConfig == NULL)
357 {
358 break;
359 }
360 if (temp8 == printerHandle->configuration)
361 {
362 status = kStatus_USB_Success;
363 break;
364 }
365
366 /* De-initialize the endpoints when current configuration is none zero. */
367 if (printerHandle->configuration != 0U)
368 {
369 status = USB_DevicePrinterEndpointsDeinit(printerHandle);
370 }
371 /* Save new configuration. */
372 printerHandle->configuration = temp8;
373 printerHandle->alternate = 0U;
374 printerHandle->bulkInBusy = 0U;
375 printerHandle->bulkOutBusy = 0U;
376
377 /* Initialize the endpoints of the new current configuration */
378 status = USB_DevicePrinterEndpointsInit(printerHandle);
379 break;
380
381 case kUSB_DeviceClassEventSetInterface:
382 if (printerHandle->classConfig == NULL)
383 {
384 break;
385 }
386
387 /* Get the new alternate setting of the interface */
388 temp16 = *((uint16_t *)param);
389 /* Get the alternate setting value */
390 temp8 = (uint8_t)(temp16 & 0xFFU);
391 /* Whether the interface belongs to the class. */
392 if (printerHandle->interfaceNumber != ((uint8_t)(temp16 >> 8U)))
393 {
394 break;
395 }
396 /* Only handle new alternate setting. */
397 if (temp8 == printerHandle->alternate)
398 {
399 status = kStatus_USB_Success;
400 break;
401 }
402
403 /* De-initialize old endpoints */
404 status = USB_DevicePrinterEndpointsDeinit(printerHandle);
405 printerHandle->alternate = temp8;
406 printerHandle->bulkInBusy = 0U;
407 printerHandle->bulkOutBusy = 0U;
408 /* Initialize new endpoints */
409 status = USB_DevicePrinterEndpointsInit(printerHandle);
410 break;
411
412 case kUSB_DeviceClassEventSetEndpointHalt:
413 if ((printerHandle->classConfig == NULL) || (printerHandle->interfaceHandle == NULL))
414 {
415 break;
416 }
417 /* Get the endpoint address */
418 temp8 = *((uint8_t *)param);
419 for (temp16 = 0; temp16 < printerHandle->interfaceHandle->endpointList.count; ++temp16)
420 {
421 if (temp8 == printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress)
422 {
423 /* Only stall the endpoint belongs to the class */
424 if (USB_IN == ((printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress &
425 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
426 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))
427 {
428 printerHandle->bulkInPipeStall = 1U;
429 }
430 else
431 {
432 printerHandle->bulkOutPipeStall = 1U;
433 }
434 status = USB_DeviceStallEndpoint(printerHandle->deviceHandle, temp8);
435 break;
436 }
437 }
438 break;
439
440 case kUSB_DeviceClassEventClearEndpointHalt:
441 if ((printerHandle->classConfig == NULL) || (printerHandle->interfaceHandle == NULL))
442 {
443 break;
444 }
445 /* Get the endpoint address */
446 temp8 = *((uint8_t *)param);
447 for (temp16 = 0; temp16 < printerHandle->interfaceHandle->endpointList.count; ++temp16)
448 {
449 if (temp8 == printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress)
450 {
451 /* Only un-stall the endpoint belongs to the class */
452 status = USB_DeviceUnstallEndpoint(printerHandle->deviceHandle, temp8);
453 if (USB_IN == (((temp8)&USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
454 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))
455 {
456 if (0U != printerHandle->bulkInPipeStall)
457 {
458 printerHandle->bulkInPipeStall = 0U;
459 if ((uint8_t *)USB_INVALID_TRANSFER_BUFFER != printerHandle->bulkInPipeDataBuffer)
460 {
461 status = USB_DeviceSendRequest(
462 printerHandle->deviceHandle,
463 (printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress &
464 USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK),
465 printerHandle->bulkInPipeDataBuffer, printerHandle->bulkInPipeDataLen);
466 if (kStatus_USB_Success != status)
467 {
468 usb_device_endpoint_callback_message_struct_t endpointCallbackMessage;
469 endpointCallbackMessage.buffer = printerHandle->bulkInPipeDataBuffer;
470 endpointCallbackMessage.length = printerHandle->bulkInPipeDataLen;
471 endpointCallbackMessage.isSetup = 0U;
472 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
473 if (kStatus_USB_Success !=
474 USB_DevicePrinterBulkInCallback(printerHandle->deviceHandle,
475 (void *)&endpointCallbackMessage, handle))
476 {
477 return kStatus_USB_Error;
478 }
479 #else
480 (void)USB_DevicePrinterBulkInCallback(printerHandle->deviceHandle,
481 (void *)&endpointCallbackMessage, handle);
482 #endif
483 }
484 printerHandle->bulkInPipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER;
485 printerHandle->bulkInPipeDataLen = 0U;
486 }
487 }
488 }
489 else
490 {
491 if (printerHandle->bulkOutPipeStall == 1U)
492 {
493 printerHandle->bulkOutPipeStall = 0U;
494 if ((uint8_t *)USB_INVALID_TRANSFER_BUFFER != printerHandle->bulkOutPipeDataBuffer)
495 {
496 status = USB_DeviceRecvRequest(
497 printerHandle->deviceHandle,
498 (printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress &
499 USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK),
500 printerHandle->bulkOutPipeDataBuffer, printerHandle->bulkOutPipeDataLen);
501 if (kStatus_USB_Success != status)
502 {
503 usb_device_endpoint_callback_message_struct_t endpointCallbackMessage;
504 endpointCallbackMessage.buffer = printerHandle->bulkOutPipeDataBuffer;
505 endpointCallbackMessage.length = printerHandle->bulkOutPipeDataLen;
506 endpointCallbackMessage.isSetup = 0U;
507 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
508 if (kStatus_USB_Success !=
509 USB_DevicePrinterBulkInCallback(printerHandle->deviceHandle,
510 (void *)&endpointCallbackMessage, handle))
511 {
512 return kStatus_USB_Error;
513 }
514 #else
515 (void)USB_DevicePrinterBulkInCallback(printerHandle->deviceHandle,
516 (void *)&endpointCallbackMessage, handle);
517 #endif
518 }
519 printerHandle->bulkOutPipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER;
520 printerHandle->bulkOutPipeDataLen = 0U;
521 }
522 }
523 }
524 break;
525 }
526 }
527 break;
528
529 case kUSB_DeviceClassEventClassRequest:
530 {
531 /* Handle the printer class specific request. */
532 usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param;
533 usb_device_printer_class_request_t classRequest;
534 if ((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) !=
535 USB_REQUEST_TYPE_RECIPIENT_INTERFACE)
536 {
537 break;
538 }
539
540 classRequest.interface = (uint8_t)(controlRequest->setup->wIndex >> 8);
541 if (classRequest.interface != printerHandle->interfaceNumber)
542 {
543 break;
544 }
545
546 classRequest.alternateSetting = (uint8_t)(controlRequest->setup->wIndex);
547 status = kStatus_USB_InvalidRequest;
548 switch (controlRequest->setup->bRequest)
549 {
550 case USB_DEVICE_PRINTER_GET_DEVICE_ID:
551 /* GET_DEVICE_ID */
552 if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
553 USB_REQUEST_TYPE_DIR_IN) &&
554 (controlRequest->setup->wLength != 0U))
555 {
556 classRequest.configIndex = (uint8_t)controlRequest->setup->wValue;
557
558 /* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
559 it is from the second parameter of classInit */
560 status = printerHandle->classConfig->classCallback(
561 (class_handle_t)printerHandle, kUSB_DevicePrinterEventGetDeviceId, &classRequest);
562 controlRequest->buffer = classRequest.buffer;
563 controlRequest->length = classRequest.length;
564 }
565 break;
566
567 case USB_DEVICE_PRINTER_GET_PORT_STATUS:
568 /* GET_PORT_STATUS */
569 if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
570 USB_REQUEST_TYPE_DIR_IN) &&
571 (controlRequest->setup->wLength == 1U))
572 {
573 /* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
574 it is from the second parameter of classInit */
575 status = printerHandle->classConfig->classCallback(
576 (class_handle_t)printerHandle, kUSB_DevicePrinterEventGetPortStatus, &classRequest);
577 controlRequest->buffer = classRequest.buffer;
578 controlRequest->length = classRequest.length;
579 }
580 break;
581
582 case USB_DEVICE_PRINTER_SOFT_RESET:
583 if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
584 USB_REQUEST_TYPE_DIR_OUT) &&
585 (controlRequest->setup->wLength == 0U))
586 {
587 /* reset BULK_IN/OUT endpoint and inform application */
588 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
589 if ((kStatus_USB_Success != USB_DevicePrinterEndpointsDeinit(printerHandle)) ||
590 (kStatus_USB_Success != USB_DevicePrinterEndpointsInit(printerHandle)))
591 {
592 return kStatus_USB_Error;
593 }
594 #else
595 (void)USB_DevicePrinterEndpointsDeinit(printerHandle);
596 (void)USB_DevicePrinterEndpointsInit(printerHandle);
597 #endif
598 /* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
599 it is from the second parameter of classInit */
600 status = printerHandle->classConfig->classCallback(
601 (class_handle_t)printerHandle, kUSB_DevicePrinterEventSoftReset, &classRequest);
602 }
603 break;
604
605 default:
606 /*no action*/
607 break;
608 }
609 break;
610 }
611 default:
612 /*no action*/
613 break;
614 }
615
616 return status;
617 }
618
USB_DevicePrinterSend(class_handle_t handle,uint8_t ep,uint8_t * buffer,uint32_t length)619 usb_status_t USB_DevicePrinterSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length)
620 {
621 usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)handle;
622 usb_status_t status;
623
624 if (NULL == handle)
625 {
626 return kStatus_USB_InvalidHandle;
627 }
628
629 if (1U == printerHandle->bulkInBusy)
630 {
631 return kStatus_USB_Busy;
632 }
633 printerHandle->bulkInBusy = 1U;
634
635 if (0U != printerHandle->bulkInPipeStall)
636 {
637 printerHandle->bulkInPipeDataBuffer = buffer;
638 printerHandle->bulkInPipeDataLen = length;
639 return kStatus_USB_Success;
640 }
641
642 status = USB_DeviceSendRequest(printerHandle->deviceHandle, ep, buffer, length);
643 if (kStatus_USB_Success != status)
644 {
645 printerHandle->bulkInBusy = 0U;
646 }
647 return status;
648 }
649
USB_DevicePrinterRecv(class_handle_t handle,uint8_t ep,uint8_t * buffer,uint32_t length)650 usb_status_t USB_DevicePrinterRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length)
651 {
652 usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)handle;
653 usb_status_t status = kStatus_USB_Error;
654
655 if (NULL == handle)
656 {
657 return kStatus_USB_InvalidHandle;
658 }
659
660 if (0U != printerHandle->bulkOutBusy)
661 {
662 return kStatus_USB_Busy;
663 }
664 printerHandle->bulkOutBusy = 1U;
665
666 if (0U != printerHandle->bulkOutPipeStall)
667 {
668 printerHandle->bulkOutPipeDataBuffer = buffer;
669 printerHandle->bulkOutPipeDataLen = length;
670 return kStatus_USB_Success;
671 }
672 status = USB_DeviceRecvRequest(printerHandle->deviceHandle, ep, buffer, length);
673 if (kStatus_USB_Success != status)
674 {
675 printerHandle->bulkOutBusy = 0U;
676 }
677
678 return status;
679 }
680 #endif
681