1 /*
2 * Copyright (c) 2015 - 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_device_config.h"
10 #include "usb.h"
11
12 #include "usb_device.h"
13 #include "usb_device_ch9.h"
14 #include "usb_device_class.h"
15
16 #if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U))
17 /* Include the class drivers according to the usb_device_config.h. */
18 #if ((defined(USB_DEVICE_CONFIG_HID)) && (USB_DEVICE_CONFIG_HID > 0U))
19 #include "usb_device_hid.h"
20 #endif
21
22 #if ((defined(USB_DEVICE_CONFIG_CDC_ACM)) && (USB_DEVICE_CONFIG_CDC_ACM > 0U))
23 #include "usb_device_cdc_acm.h"
24 #endif
25
26 #if ((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U))
27 #include "usb_device_msc.h"
28 #endif
29
30 #if ((defined(USB_DEVICE_CONFIG_MTP)) && (USB_DEVICE_CONFIG_MTP > 0U))
31 #include "usb_device_mtp.h"
32 #endif
33
34 #if ((defined(USB_DEVICE_CONFIG_AUDIO)) && (USB_DEVICE_CONFIG_AUDIO > 0U))
35 #include "usb_device_audio.h"
36 #endif
37
38 #if ((defined(USB_DEVICE_CONFIG_PHDC)) && (USB_DEVICE_CONFIG_PHDC > 0U))
39 #include "usb_device_phdc.h"
40 #endif
41
42 #if ((defined(USB_DEVICE_CONFIG_VIDEO)) && (USB_DEVICE_CONFIG_VIDEO > 0U))
43 #include "usb_device_video.h"
44 #endif
45
46 #if ((defined(USB_DEVICE_CONFIG_PRINTER)) && (USB_DEVICE_CONFIG_PRINTER > 0U))
47 #include "usb_device_printer.h"
48 #endif
49
50 #if ((defined(USB_DEVICE_CONFIG_DFU)) && (USB_DEVICE_CONFIG_DFU > 0U))
51 #include "usb_device_dfu.h"
52 #endif
53
54 #if ((defined(USB_DEVICE_CONFIG_CCID)) && (USB_DEVICE_CONFIG_CCID > 0U))
55 #include "usb_device_ccid.h"
56 #endif
57
58 /*******************************************************************************
59 * Definitions
60 ******************************************************************************/
61
62 /*******************************************************************************
63 * Prototypes
64 ******************************************************************************/
65 static usb_status_t USB_DeviceClassAllocateHandle(uint8_t controllerId, usb_device_common_class_struct_t **handle);
66 static usb_status_t USB_DeviceClassFreeHandle(uint8_t controllerId);
67 static usb_status_t USB_DeviceClassGetHandleByControllerId(uint8_t controllerId,
68 usb_device_common_class_struct_t **handle);
69 static usb_status_t USB_DeviceClassGetHandleByDeviceHandle(usb_device_handle deviceHandle,
70 usb_device_common_class_struct_t **handle);
71
72 /*******************************************************************************
73 * Variables
74 ******************************************************************************/
75
76 /* The device class driver list. */
77 static const usb_device_class_map_t s_UsbDeviceClassInterfaceMap[] = {
78 #if ((defined(USB_DEVICE_CONFIG_HID)) && (USB_DEVICE_CONFIG_HID > 0U))
79 {USB_DeviceHidInit, USB_DeviceHidDeinit, USB_DeviceHidEvent, kUSB_DeviceClassTypeHid},
80 #endif
81
82 #if ((defined(USB_DEVICE_CONFIG_CDC_ACM)) && (USB_DEVICE_CONFIG_CDC_ACM > 0U))
83 {USB_DeviceCdcAcmInit, USB_DeviceCdcAcmDeinit, USB_DeviceCdcAcmEvent, kUSB_DeviceClassTypeCdc},
84 #endif
85
86 #if ((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U))
87 {USB_DeviceMscInit, USB_DeviceMscDeinit, USB_DeviceMscEvent, kUSB_DeviceClassTypeMsc},
88 #endif
89
90 #if ((defined(USB_DEVICE_CONFIG_MTP)) && (USB_DEVICE_CONFIG_MTP > 0U))
91 {USB_DeviceMtpInit, USB_DeviceMtpDeinit, USB_DeviceMtpEvent, kUSB_DeviceClassTypeMtp},
92 #endif
93
94 #if ((defined USB_DEVICE_CONFIG_AUDIO) && (USB_DEVICE_CONFIG_AUDIO > 0U))
95 {USB_DeviceAudioInit, USB_DeviceAudioDeinit, USB_DeviceAudioEvent, kUSB_DeviceClassTypeAudio},
96 #endif
97
98 #if ((defined USB_DEVICE_CONFIG_PHDC) && (USB_DEVICE_CONFIG_PHDC > 0U))
99 {USB_DevicePhdcInit, USB_DevicePhdcDeinit, USB_DevicePhdcEvent, kUSB_DeviceClassTypePhdc},
100 #endif
101
102 #if ((defined USB_DEVICE_CONFIG_VIDEO) && (USB_DEVICE_CONFIG_VIDEO > 0U))
103 {USB_DeviceVideoInit, USB_DeviceVideoDeinit, USB_DeviceVideoEvent, kUSB_DeviceClassTypeVideo},
104 #endif
105
106 #if ((defined USB_DEVICE_CONFIG_PRINTER) && (USB_DEVICE_CONFIG_PRINTER > 0U))
107 {USB_DevicePrinterInit, USB_DevicePrinterDeinit, USB_DevicePrinterEvent, kUSB_DeviceClassTypePrinter},
108 #endif
109
110 #if ((defined USB_DEVICE_CONFIG_DFU) && (USB_DEVICE_CONFIG_DFU > 0U))
111 {USB_DeviceDfuInit, USB_DeviceDfuDeinit, USB_DeviceDfuEvent, kUSB_DeviceClassTypeDfu},
112 #endif
113
114 #if ((defined USB_DEVICE_CONFIG_CCID) && (USB_DEVICE_CONFIG_CCID > 0U))
115 {USB_DeviceCcidInit, USB_DeviceCcidDeinit, USB_DeviceCcidEvent, kUSB_DeviceClassTypeCcid},
116 #endif
117
118 /* please make sure the following member is in the end of s_UsbDeviceClassInterfaceMap*/
119 {(usb_device_class_init_call_t)NULL, (usb_device_class_deinit_call_t)NULL, (usb_device_class_event_callback_t)NULL,
120 (usb_device_class_type_t)0},
121 };
122
123 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_common_class_struct_t
124 s_UsbDeviceCommonClassStruct[USB_DEVICE_CONFIG_NUM];
125 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t
126 s_UsbDeviceSetupBuffer[USB_DEVICE_CONFIG_NUM][USB_DATA_ALIGN_SIZE_MULTIPLE(USB_SETUP_PACKET_SIZE)];
127
128 /*******************************************************************************
129 * Code
130 ******************************************************************************/
131
132 /*!
133 * @brief Allocate a device common class handle.
134 *
135 * This function allocates a a device common class handle.
136 *
137 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
138 * @param handle It is out parameter, is used to return pointer of the device common class handle to the
139 * caller.
140 *
141 * @retval kStatus_USB_Success Get a device handle successfully.
142 * @retval kStatus_USB_Busy Cannot allocate a common class handle.
143 * @retval kStatus_USB_Error The common class has been initialized.
144 */
USB_DeviceClassAllocateHandle(uint8_t controllerId,usb_device_common_class_struct_t ** handle)145 static usb_status_t USB_DeviceClassAllocateHandle(uint8_t controllerId, usb_device_common_class_struct_t **handle)
146 {
147 uint32_t count;
148 OSA_SR_ALLOC();
149
150 OSA_ENTER_CRITICAL();
151 /* Check the controller is initialized or not. */
152 for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
153 {
154 if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) &&
155 (controllerId == s_UsbDeviceCommonClassStruct[count].controllerId))
156 {
157 OSA_EXIT_CRITICAL();
158 return kStatus_USB_Error;
159 }
160 }
161 /* Get a free common class handle. */
162 for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
163 {
164 if (NULL == s_UsbDeviceCommonClassStruct[count].handle)
165 {
166 s_UsbDeviceCommonClassStruct[count].controllerId = controllerId;
167 s_UsbDeviceCommonClassStruct[count].setupBuffer = s_UsbDeviceSetupBuffer[count];
168 *handle = &s_UsbDeviceCommonClassStruct[count];
169 OSA_EXIT_CRITICAL();
170 return kStatus_USB_Success;
171 }
172 }
173
174 OSA_EXIT_CRITICAL();
175 return kStatus_USB_Busy;
176 }
177
178 /*!
179 * @brief Free a device common class handle.
180 *
181 * This function frees a device common class handle.
182 *
183 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
184 *
185 * @retval kStatus_USB_Success Free device handle successfully.
186 * @retval kStatus_USB_InvalidParameter The common class can not be found.
187 */
USB_DeviceClassFreeHandle(uint8_t controllerId)188 static usb_status_t USB_DeviceClassFreeHandle(uint8_t controllerId)
189 {
190 uint32_t count = 0U;
191 OSA_SR_ALLOC();
192
193 OSA_ENTER_CRITICAL();
194 for (; count < USB_DEVICE_CONFIG_NUM; count++)
195 {
196 if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) &&
197 (controllerId == s_UsbDeviceCommonClassStruct[count].controllerId))
198 {
199 s_UsbDeviceCommonClassStruct[count].handle = NULL;
200 s_UsbDeviceCommonClassStruct[count].configList = (usb_device_class_config_list_struct_t *)NULL;
201 s_UsbDeviceCommonClassStruct[count].controllerId = 0U;
202 OSA_EXIT_CRITICAL();
203 return kStatus_USB_Success;
204 }
205 }
206 OSA_EXIT_CRITICAL();
207
208 return kStatus_USB_InvalidParameter;
209 }
210
211 /*!
212 * @brief Get the device common class handle according to the controller id.
213 *
214 * This function gets the device common class handle according to the controller id.
215 *
216 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
217 * @param handle It is out parameter, is used to return pointer of the device common class handle to the
218 * caller.
219 *
220 * @retval kStatus_USB_Success Free device handle successfully.
221 * @retval kStatus_USB_InvalidParameter The common class can not be found.
222 */
USB_DeviceClassGetHandleByControllerId(uint8_t controllerId,usb_device_common_class_struct_t ** handle)223 static usb_status_t USB_DeviceClassGetHandleByControllerId(uint8_t controllerId,
224 usb_device_common_class_struct_t **handle)
225 {
226 uint32_t count = 0U;
227 OSA_SR_ALLOC();
228
229 OSA_ENTER_CRITICAL();
230 for (; count < USB_DEVICE_CONFIG_NUM; count++)
231 {
232 if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) &&
233 (controllerId == s_UsbDeviceCommonClassStruct[count].controllerId))
234 {
235 *handle = &s_UsbDeviceCommonClassStruct[count];
236 OSA_EXIT_CRITICAL();
237 return kStatus_USB_Success;
238 }
239 }
240 OSA_EXIT_CRITICAL();
241 return kStatus_USB_InvalidParameter;
242 }
243
244 /*!
245 * @brief Get the device common class handle according to the device handle.
246 *
247 * This function gets the device common class handle according to the device handle.
248 *
249 * @param deviceHandle The device handle, got from the USB_DeviceInit.
250 * @param handle It is out parameter, is used to return pointer of the device common class handle to the
251 * caller.
252 *
253 * @retval kStatus_USB_Success Free device handle successfully.
254 * @retval kStatus_USB_InvalidParameter The common class can not be found.
255 */
USB_DeviceClassGetHandleByDeviceHandle(usb_device_handle deviceHandle,usb_device_common_class_struct_t ** handle)256 static usb_status_t USB_DeviceClassGetHandleByDeviceHandle(usb_device_handle deviceHandle,
257 usb_device_common_class_struct_t **handle)
258 {
259 uint32_t count = 0U;
260 OSA_SR_ALLOC();
261
262 OSA_ENTER_CRITICAL();
263 for (; count < USB_DEVICE_CONFIG_NUM; count++)
264 {
265 if (deviceHandle == s_UsbDeviceCommonClassStruct[count].handle)
266 {
267 *handle = &s_UsbDeviceCommonClassStruct[count];
268 OSA_EXIT_CRITICAL();
269 return kStatus_USB_Success;
270 }
271 }
272 OSA_EXIT_CRITICAL();
273 return kStatus_USB_InvalidParameter;
274 }
275
276 /*!
277 * @brief Get the device handle according to the controller id.
278 *
279 * This function gets the device handle according to the controller id.
280 *
281 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
282 * @param handle It is out parameter, is used to return pointer of the device handle to the caller.
283 *
284 * @retval kStatus_USB_Success Free device handle successfully.
285 * @retval kStatus_USB_InvalidParameter The device handle not be found.
286 */
USB_DeviceClassGetDeviceHandle(uint8_t controllerId,usb_device_handle * handle)287 usb_status_t USB_DeviceClassGetDeviceHandle(uint8_t controllerId, usb_device_handle *handle)
288 {
289 uint32_t count = 0U;
290 OSA_SR_ALLOC();
291
292 OSA_ENTER_CRITICAL();
293 for (; count < USB_DEVICE_CONFIG_NUM; count++)
294 {
295 if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) &&
296 (controllerId == s_UsbDeviceCommonClassStruct[count].controllerId))
297 {
298 *handle = s_UsbDeviceCommonClassStruct[count].handle;
299 OSA_EXIT_CRITICAL();
300 return kStatus_USB_Success;
301 }
302 }
303 OSA_EXIT_CRITICAL();
304 return kStatus_USB_InvalidParameter;
305 }
306
307 /*!
308 * @brief Handle the event passed to the class drivers.
309 *
310 * This function handles the event passed to the class drivers.
311 *
312 * @param handle The device handle, got from the USB_DeviceInit.
313 * @param event The event codes. Please refer to the enumeration usb_device_class_event_t.
314 * @param param The param type is determined by the event code.
315 *
316 * @return A USB error code or kStatus_USB_Success.
317 * @retval kStatus_USB_Success A valid request has been handled.
318 * @retval kStatus_USB_InvalidParameter The device handle not be found.
319 * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller.
320 */
USB_DeviceClassEvent(usb_device_handle handle,usb_device_class_event_t event,void * param)321 usb_status_t USB_DeviceClassEvent(usb_device_handle handle, usb_device_class_event_t event, void *param)
322 {
323 usb_device_common_class_struct_t *classHandle;
324 uint8_t mapIndex;
325 uint8_t classIndex;
326 usb_status_t errorReturn;
327 usb_status_t status = kStatus_USB_Error;
328
329 if (NULL == param)
330 {
331 return kStatus_USB_InvalidParameter;
332 }
333
334 /* Get the common class handle according to the device handle. */
335 errorReturn = USB_DeviceClassGetHandleByDeviceHandle(handle, &classHandle);
336 if (kStatus_USB_Success != errorReturn)
337 {
338 return kStatus_USB_InvalidParameter;
339 }
340
341 for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++)
342 {
343 for (mapIndex = 0U; mapIndex < (ARRAY_SIZE(s_UsbDeviceClassInterfaceMap) - 1U); mapIndex++)
344 {
345 if (s_UsbDeviceClassInterfaceMap[mapIndex].type ==
346 classHandle->configList->config[classIndex].classInfomation->type)
347 {
348 /* Call class event callback of supported class */
349 errorReturn = s_UsbDeviceClassInterfaceMap[mapIndex].classEventCallback(
350 (void *)classHandle->configList->config[classIndex].classHandle, event, param);
351 /* Return the error code kStatus_USB_InvalidRequest immediately, when a class returns
352 * kStatus_USB_InvalidRequest. */
353 if (kStatus_USB_InvalidRequest == errorReturn)
354 {
355 /* For composite device, it should return kStatus_USB_Success once a valid request has been handled
356 */
357 if (kStatus_USB_Success == status)
358 {
359 return kStatus_USB_Success;
360 }
361 return kStatus_USB_InvalidRequest;
362 }
363 /* For composite device, save kStatus_USB_Success status once a valid request has been handled */
364 if (kStatus_USB_Success == errorReturn)
365 {
366 status = kStatus_USB_Success;
367 }
368 break;
369 }
370 }
371 }
372
373 return status;
374 }
375
376 /*!
377 * @brief Handle the common class callback.
378 *
379 * This function handles the common class callback.
380 *
381 * @param handle The device handle, got from the USB_DeviceInit.
382 * @param event The event codes. Please refer to the enumeration usb_device_event_t.
383 * @param param The param type is determined by the event code.
384 *
385 * @return A USB error code or kStatus_USB_Success.
386 */
USB_DeviceClassCallback(usb_device_handle handle,uint32_t event,void * param)387 usb_status_t USB_DeviceClassCallback(usb_device_handle handle, uint32_t event, void *param)
388 {
389 usb_device_common_class_struct_t *classHandle;
390 usb_status_t status;
391
392 /* Get the common class handle according to the device handle. */
393 status = USB_DeviceClassGetHandleByDeviceHandle(handle, &classHandle);
394 if (kStatus_USB_Success != status)
395 {
396 return status;
397 }
398
399 if ((uint32_t)kUSB_DeviceEventBusReset == event)
400 {
401 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
402 if ((kStatus_USB_Success != USB_DeviceControlPipeInit(handle, classHandle)) ||
403 (kStatus_USB_Success != USB_DeviceClassEvent(handle, kUSB_DeviceClassEventDeviceReset, classHandle)))
404 {
405 return kStatus_USB_Error;
406 }
407 #else
408 /* Initialize the control pipes */
409 (void)USB_DeviceControlPipeInit(handle, classHandle);
410
411 /* Notify the classes the USB bus reset signal detected. */
412 (void)USB_DeviceClassEvent(handle, kUSB_DeviceClassEventDeviceReset, classHandle);
413 #endif
414 }
415
416 /* Call the application device callback function. deviceCallback is from the second parameter of
417 USB_DeviceClassInit */
418 status = classHandle->configList->deviceCallback(handle, event, param);
419 return status;
420 }
421
422 /*!
423 * @brief Initialize the common class and the supported classes.
424 *
425 * This function is used to initialize the common class and the supported classes.
426 *
427 * @param[in] controllerId The controller id of the USB IP. Please refer to the enumeration #usb_controller_index_t.
428 * @param[in] configList The class configurations. The pointer must point to the global variable.
429 * Please refer to the structure #usb_device_class_config_list_struct_t.
430 * @param[out] handle It is out parameter, is used to return pointer of the device handle to the caller.
431 * The value of parameter is a pointer points the device handle, and this design is used to
432 * make simple device align with composite device. For composite device, there are many
433 * kinds of class handle, but there is only one device handle. So the handle points to
434 * a device instead of a class. And the class handle can be got from the
435 * #usb_device_class_config_struct_t::classHandle after the function successfully.
436 *
437 * @return A USB error code or kStatus_USB_Success.
438 */
USB_DeviceClassInit(uint8_t controllerId,usb_device_class_config_list_struct_t * configList,usb_device_handle * handle)439 usb_status_t USB_DeviceClassInit(
440 uint8_t controllerId, /*!< [IN] Controller ID */
441 usb_device_class_config_list_struct_t *configList, /*!< [IN] Pointer to class configuration list */
442 usb_device_handle *handle /*!< [OUT] Pointer to the device handle */
443 )
444 {
445 usb_device_common_class_struct_t *classHandle;
446 usb_status_t error;
447 uint8_t mapIndex;
448 uint8_t classIndex;
449
450 if ((NULL == handle) || (NULL == configList) || ((usb_device_callback_t)NULL == configList->deviceCallback))
451 {
452 return kStatus_USB_InvalidParameter;
453 }
454
455 /* Allocate a common class driver handle. */
456 error = USB_DeviceClassAllocateHandle(controllerId, &classHandle);
457 if (kStatus_USB_Success != error)
458 {
459 return error;
460 }
461 /* Save the configuration list */
462 classHandle->configList = configList;
463
464 /* Initialize the device stack. */
465 error = USB_DeviceInit(controllerId, USB_DeviceClassCallback, &classHandle->handle);
466
467 if (kStatus_USB_Success != error)
468 {
469 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
470 if (((kStatus_USB_Success != USB_DeviceDeinit(classHandle->handle))) ||
471 (kStatus_USB_Success != USB_DeviceClassFreeHandle(controllerId)))
472 {
473 return kStatus_USB_Error;
474 }
475 #else
476 (void)USB_DeviceDeinit(classHandle->handle);
477 (void)USB_DeviceClassFreeHandle(controllerId);
478 #endif
479 return error;
480 }
481
482 /* Initialize the all supported classes according to the configuration list. */
483 for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++)
484 {
485 for (mapIndex = 0U; mapIndex < (sizeof(s_UsbDeviceClassInterfaceMap) / sizeof(usb_device_class_map_t));
486 mapIndex++)
487 {
488 if (classHandle->configList->config[classIndex].classInfomation->type ==
489 s_UsbDeviceClassInterfaceMap[mapIndex].type)
490 {
491 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
492 error = s_UsbDeviceClassInterfaceMap[mapIndex].classInit(
493 controllerId, &classHandle->configList->config[classIndex],
494 &classHandle->configList->config[classIndex].classHandle);
495 if (kStatus_USB_Success != error)
496 {
497 return error;
498 }
499 #else
500 (void)s_UsbDeviceClassInterfaceMap[mapIndex].classInit(
501 controllerId, &classHandle->configList->config[classIndex],
502 &classHandle->configList->config[classIndex].classHandle);
503 #endif
504 }
505 }
506 }
507
508 *handle = classHandle->handle;
509 return error;
510 }
511
512 /*!
513 * @brief De-initialize the common class and the supported classes.
514 *
515 * This function is used to de-initialize the common class and the supported classes.
516 *
517 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
518 *
519 * @return A USB error code or kStatus_USB_Success.
520 */
USB_DeviceClassDeinit(uint8_t controllerId)521 usb_status_t USB_DeviceClassDeinit(uint8_t controllerId /*!< [IN] Controller ID */
522 )
523 {
524 usb_device_common_class_struct_t *classHandle;
525 usb_status_t error;
526 uint8_t mapIndex;
527 uint8_t classIndex;
528
529 /* Get the common class handle according to the controller id. */
530 error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle);
531
532 if (kStatus_USB_Success != error)
533 {
534 return error;
535 }
536
537 /* De-initialize the all supported classes according to the configuration list. */
538 for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++)
539 {
540 for (mapIndex = 0U; mapIndex < (sizeof(s_UsbDeviceClassInterfaceMap) / sizeof(usb_device_class_map_t));
541 mapIndex++)
542 {
543 if (classHandle->configList->config[classIndex].classInfomation->type ==
544 s_UsbDeviceClassInterfaceMap[mapIndex].type)
545 {
546 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
547 error = s_UsbDeviceClassInterfaceMap[mapIndex].classDeinit(
548 classHandle->configList->config[classIndex].classHandle);
549 if (kStatus_USB_Success != error)
550 {
551 return error;
552 }
553 #else
554 (void)s_UsbDeviceClassInterfaceMap[mapIndex].classDeinit(
555 classHandle->configList->config[classIndex].classHandle);
556 #endif
557 }
558 }
559 }
560
561 /* De-initialize the USB device stack. */
562 error = USB_DeviceDeinit(classHandle->handle);
563 if (kStatus_USB_Success == error)
564 {
565 /* Free the common class handle. */
566 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
567 if (kStatus_USB_Success != USB_DeviceClassFreeHandle(controllerId))
568 {
569 return kStatus_USB_Error;
570 }
571 #else
572 (void)USB_DeviceClassFreeHandle(controllerId);
573 #endif
574 }
575 return error;
576 }
577
578 /*!
579 * @brief Get the USB bus speed.
580 *
581 * This function is used to get the USB bus speed.
582 *
583 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
584 * @param speed It is an OUT parameter, return current speed of the controller.
585 *
586 * @return A USB error code or kStatus_USB_Success.
587 */
USB_DeviceClassGetSpeed(uint8_t controllerId,uint8_t * speed)588 usb_status_t USB_DeviceClassGetSpeed(uint8_t controllerId, /*!< [IN] Controller ID */
589 uint8_t *speed /*!< [OUT] Current speed */
590 )
591 {
592 usb_device_common_class_struct_t *classHandle;
593 usb_status_t error;
594
595 /* Get the common class handle according to the controller id. */
596 error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle);
597
598 if (kStatus_USB_Success != error)
599 {
600 return error;
601 }
602
603 /* Get the current speed. */
604 error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusSpeed, speed);
605
606 return error;
607 }
608
609 #if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
610 /*!
611 * @brief Get the USB SOF count.
612 *
613 * This function is used to get the USB SOF count.
614 *
615 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
616 * @param currentFrameCount It is an OUT parameter, return current sof count of the controller.
617 * HS: micro frame count, FS: frame count
618 *
619 * @return A USB error code or kStatus_USB_Success.
620 */
USB_DeviceClassGetCurrentFrameCount(uint8_t controllerId,uint32_t * currentFrameCount)621 usb_status_t USB_DeviceClassGetCurrentFrameCount(uint8_t controllerId, /*!< [IN] Controller ID */
622 uint32_t *currentFrameCount /*!< [OUT] Current frame count */
623 )
624 {
625 usb_device_common_class_struct_t *classHandle;
626 usb_status_t error;
627
628 /* Get the common class handle according to the controller id. */
629 error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle);
630
631 if (kStatus_USB_Success != error)
632 {
633 return error;
634 }
635
636 /* Get the current frame count. */
637 error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusGetCurrentFrameCount, currentFrameCount);
638
639 return error;
640 }
641 #endif /* USB_DEVICE_CONFIG_GET_SOF_COUNT */
642
643 #endif /* USB_DEVICE_CONFIG_NUM */
644