1 /*
2  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016 - 2017,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_dci.h"
14 
15 #include "fsl_device_registers.h"
16 
17 #if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U))
18 
19 #if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
20 #include "usb_device_khci.h"
21 #endif
22 
23 #if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
24 #include "usb_device_ehci.h"
25 #endif
26 
27 #if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
28      ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
29 #include "usb_device_lpcip3511.h"
30 #endif
31 
32 #if ((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U))
33 #include "usb_device_dwc3.h"
34 #endif
35 
36 /*******************************************************************************
37  * Definitions
38  ******************************************************************************/
39 
40 /* Component ID definition, used by tools. */
41 #ifndef FSL_COMPONENT_ID
42 #define FSL_COMPONENT_ID "middleware.usb.device_stack"
43 #endif
44 
45 /*******************************************************************************
46  * Prototypes
47  ******************************************************************************/
48 static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle);
49 static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle);
50 static usb_status_t USB_DeviceGetControllerInterface(
51     uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface);
52 static usb_status_t USB_DeviceTransfer(usb_device_handle handle,
53                                        uint8_t endpointAddress,
54                                        uint8_t *buffer,
55                                        uint32_t length);
56 static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param);
57 static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle,
58                                                 usb_device_callback_message_struct_t *message);
59 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
60 static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle,
61                                                   usb_device_callback_message_struct_t *message);
62 static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle,
63                                                  usb_device_callback_message_struct_t *message);
64 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
65 static usb_status_t USB_DeviceSleepNotification(usb_device_struct_t *handle,
66                                                 usb_device_callback_message_struct_t *message);
67 
68 #endif
69 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
70 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
71 static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle,
72                                                  usb_device_callback_message_struct_t *message);
73 static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle,
74                                                  usb_device_callback_message_struct_t *message);
75 #endif
76 static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message);
77 
78 /*******************************************************************************
79  * Variables
80  ******************************************************************************/
81 
82 USB_GLOBAL static usb_device_struct_t s_UsbDevice[USB_DEVICE_CONFIG_NUM];
83 
84 /*******************************************************************************
85  * Code
86  ******************************************************************************/
87 
88 /*!
89  * @brief Allocate a device handle.
90  *
91  * This function allocates a device handle.
92  *
93  * @param controllerId   The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
94  * @param handle          It is out parameter, is used to return pointer of the device handle to the caller.
95  *
96  * @retval kStatus_USB_Success              Get a device handle successfully.
97  * @retval kStatus_USB_Busy                 Cannot allocate a device handle.
98  * @retval kStatus_USB_Error                The device has been initialized.
99  */
USB_DeviceAllocateHandle(uint8_t controllerId,usb_device_struct_t ** handle)100 static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle)
101 {
102     uint32_t count;
103     OSA_SR_ALLOC();
104 
105     OSA_ENTER_CRITICAL();
106     /* Check the controller is initialized or not. */
107     for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
108     {
109         if ((NULL != s_UsbDevice[count].controllerHandle) && (controllerId == s_UsbDevice[count].controllerId))
110         {
111             OSA_EXIT_CRITICAL();
112             return kStatus_USB_Error;
113         }
114     }
115     /* Get a free device handle. */
116     for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
117     {
118         if (NULL == s_UsbDevice[count].controllerHandle)
119         {
120             s_UsbDevice[count].controllerId = controllerId;
121             *handle                         = &s_UsbDevice[count];
122             OSA_EXIT_CRITICAL();
123             return kStatus_USB_Success;
124         }
125     }
126     OSA_EXIT_CRITICAL();
127     return kStatus_USB_Busy;
128 }
129 
130 /*!
131  * @brief Free a device handle.
132  *
133  * This function frees a device handle.
134  *
135  * @param handle          The device handle.
136  *
137  * @retval kStatus_USB_Success              Free device handle successfully.
138  */
USB_DeviceFreeHandle(usb_device_struct_t * handle)139 static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle)
140 {
141     OSA_SR_ALLOC();
142 
143     OSA_ENTER_CRITICAL();
144     handle->controllerHandle = NULL;
145     handle->controllerId     = 0U;
146     OSA_EXIT_CRITICAL();
147     return kStatus_USB_Success;
148 }
149 
150 #if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
151 /* KHCI device driver interface */
152 static const usb_device_controller_interface_struct_t s_UsbDeviceKhciInterface = {
153     USB_DeviceKhciInit, USB_DeviceKhciDeinit, USB_DeviceKhciSend,
154     USB_DeviceKhciRecv, USB_DeviceKhciCancel, USB_DeviceKhciControl};
155 #endif
156 
157 #if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
158 /* EHCI device driver interface */
159 static const usb_device_controller_interface_struct_t s_UsbDeviceEhciInterface = {
160     USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend,
161     USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl};
162 #endif
163 
164 #if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
165      ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
166 /* EHCI device driver interface */
167 static const usb_device_controller_interface_struct_t s_UsbDeviceLpc3511IpInterface = {
168     USB_DeviceLpc3511IpInit, USB_DeviceLpc3511IpDeinit, USB_DeviceLpc3511IpSend,
169     USB_DeviceLpc3511IpRecv, USB_DeviceLpc3511IpCancel, USB_DeviceLpc3511IpControl};
170 #endif
171 
172 #if ((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U))
173 /* EHCI device driver interface */
174 static const usb_device_controller_interface_struct_t s_UsbDeviceDwc3Interface = {
175     USB_DeviceDwc3Init, USB_DeviceDwc3Deinit, USB_DeviceDwc3Send,
176     USB_DeviceDwc3Recv, USB_DeviceDwc3Cancel, USB_DeviceDwc3Control};
177 #endif
178 
179 /*!
180  * @brief Get the controller interface handle.
181  *
182  * This function is used to get the controller interface handle.
183  *
184  * @param controllerId          The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
185  * @param controllerInterface   It is out parameter, is used to return pointer of the device controller handle to the
186  * caller.
187  *
188  * @retval kStatus_USB_Success              Get a device handle successfully.
189  * @retval kStatus_USB_ControllerNotFound   The controller id is invalid.
190  */
USB_DeviceGetControllerInterface(uint8_t controllerId,const usb_device_controller_interface_struct_t ** controllerInterface)191 static usb_status_t USB_DeviceGetControllerInterface(
192     uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface)
193 {
194     usb_status_t error                    = kStatus_USB_ControllerNotFound;
195     usb_controller_index_t controlerIndex = (usb_controller_index_t)controllerId;
196 
197 #if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
198     /* Get the KHCI controller driver interface */
199     if ((kUSB_ControllerKhci0 == controlerIndex) || (kUSB_ControllerKhci1 == controlerIndex))
200     {
201         *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceKhciInterface;
202         error                = kStatus_USB_Success;
203     }
204 #endif
205 #if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
206     /* Get the EHCI controller driver interface */
207     if ((kUSB_ControllerEhci0 == controlerIndex) || (kUSB_ControllerEhci1 == controlerIndex))
208     {
209         *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceEhciInterface;
210         error                = kStatus_USB_Success;
211     }
212 #endif
213 #if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
214      ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
215     /* Get the EHCI controller driver interface */
216     if ((kUSB_ControllerLpcIp3511Fs0 == controlerIndex) || (kUSB_ControllerLpcIp3511Fs1 == controlerIndex) ||
217         (kUSB_ControllerLpcIp3511Hs0 == controlerIndex) || (kUSB_ControllerLpcIp3511Hs1 == controlerIndex))
218     {
219         *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceLpc3511IpInterface;
220         error                = kStatus_USB_Success;
221     }
222 #endif
223 #if ((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U))
224     /* Get the EHCI controller driver interface */
225     if ((kUSB_ControllerDwc30 == controlerIndex) || (kUSB_ControllerDwc31 == controlerIndex))
226     {
227         *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceDwc3Interface;
228         error                = kStatus_USB_Success;
229     }
230 #endif
231 
232     return error;
233 }
234 
235 /*!
236  * @brief Start a new transfer.
237  *
238  * This function is used to start a new transfer.
239  *
240  * @param handle                 The device handle. It equals the value returned from USB_DeviceInit.
241  * @param endpointAddress       Endpoint address. Bit7 is direction, 0U - USB_OUT, 1U - USB_IN.
242  * @param buffer                 The memory address to be transferred, or the memory address to hold the data need to be
243  * sent.
244  * @param length                 The length of the data.
245  *
246  * @retval kStatus_USB_Success              Get a device handle successfully.
247  * @retval kStatus_USB_InvalidHandle        The device handle is invalid.
248  * @retval kStatus_USB_ControllerNotFound   The controller interface is not found.
249  * @retval kStatus_USB_Error                The device is doing reset.
250  */
USB_DeviceTransfer(usb_device_handle handle,uint8_t endpointAddress,uint8_t * buffer,uint32_t length)251 static usb_status_t USB_DeviceTransfer(usb_device_handle handle,
252                                        uint8_t endpointAddress,
253                                        uint8_t *buffer,
254                                        uint32_t length)
255 {
256     usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
257     usb_status_t status               = kStatus_USB_Error;
258     uint8_t endpoint                  = endpointAddress & USB_ENDPOINT_NUMBER_MASK;
259     uint8_t direction                 = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
260                         USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
261     OSA_SR_ALLOC();
262 
263     if (NULL == deviceHandle)
264     {
265         return kStatus_USB_InvalidHandle;
266     }
267 
268     if (NULL != deviceHandle->controllerInterface)
269     {
270         if (endpoint >= USB_DEVICE_CONFIG_ENDPOINTS)
271         {
272             return kStatus_USB_InvalidParameter;
273         }
274         OSA_ENTER_CRITICAL();
275         if (0U != deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy)
276         {
277             OSA_EXIT_CRITICAL();
278             return kStatus_USB_Busy;
279         }
280         deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 1U;
281         OSA_EXIT_CRITICAL();
282         if (0U != (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK))
283         {
284             /* Call the controller send interface, the callbackFn is initialized in
285             USB_DeviceGetControllerInterface */
286             status = deviceHandle->controllerInterface->deviceSend(deviceHandle->controllerHandle, endpointAddress,
287                                                                    buffer, length);
288         }
289         else
290         {
291             /* Call the controller receive interface, the callbackFn is initialized in
292             USB_DeviceGetControllerInterface */
293             status = deviceHandle->controllerInterface->deviceRecv(deviceHandle->controllerHandle, endpointAddress,
294                                                                    buffer, length);
295         }
296         if (kStatus_USB_Success != status)
297         {
298             OSA_ENTER_CRITICAL();
299             deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U;
300             OSA_EXIT_CRITICAL();
301         }
302     }
303     else
304     {
305         status = kStatus_USB_ControllerNotFound;
306     }
307     return status;
308 }
309 
310 /*!
311  * @brief Control the status of the selected item.
312  *
313  * This function is used to control the status of the selected item..
314  *
315  * @param handle                 The device handle. It equals the value returned from USB_DeviceInit.
316  * @param type                   The control type, please refer to the enumeration usb_device_control_type_t.
317  * @param param                  The param type is determined by the selected item.
318  *
319  * @retval kStatus_USB_Success              Get a device handle successfully.
320  * @retval kStatus_USB_InvalidHandle        The device handle is invalid.
321  * @retval kStatus_USB_ControllerNotFound   The controller interface is not found.
322  * @retval kStatus_USB_Error                Unsupported type.
323  *                                          Or, the param is NULL pointer.
324  */
USB_DeviceControl(usb_device_handle handle,usb_device_control_type_t type,void * param)325 static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param)
326 {
327     usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
328     usb_status_t status               = kStatus_USB_InvalidHandle;
329 
330     if (NULL == deviceHandle)
331     {
332         return status;
333     }
334 
335     if (NULL != deviceHandle->controllerInterface)
336     {
337         /* Call the controller control interface. the controllerInterface is initialized in
338         USB_DeviceGetControllerInterface */
339         status = deviceHandle->controllerInterface->deviceControl(deviceHandle->controllerHandle, type, param);
340     }
341     else
342     {
343         status = kStatus_USB_ControllerNotFound;
344     }
345     return status;
346 }
347 
348 /*!
349  * @brief Handle the reset notification.
350  *
351  * This function is used to handle the reset notification.
352  *
353  * @param handle                 The device handle. It equals the value returned from USB_DeviceInit.
354  * @param message                The device callback message handle.
355  *
356  * @retval kStatus_USB_Success              Get a device handle successfully.
357  */
USB_DeviceResetNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)358 static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle,
359                                                 usb_device_callback_message_struct_t *message)
360 {
361     uint32_t count;
362 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
363     usb_status_t status = kStatus_USB_Error;
364 #endif
365 
366 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
367     OSA_SR_ALLOC();
368 #endif
369 
370     handle->isResetting = 1U;
371 
372 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
373     /* Clear remote wakeup feature */
374     handle->remotewakeup = 0U;
375 #endif
376 
377 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
378     OSA_ENTER_CRITICAL();
379     handle->epCallbackDirectly = 1U;
380     OSA_EXIT_CRITICAL();
381 #endif
382     /* Set the controller to default status. */
383 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
384     status = USB_DeviceControl(handle, kUSB_DeviceControlSetDefaultStatus, NULL);
385     if (kStatus_USB_Success != status)
386     {
387         return status;
388     }
389 #else
390     (void)USB_DeviceControl(handle, kUSB_DeviceControlSetDefaultStatus, NULL);
391 #endif
392 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
393     OSA_ENTER_CRITICAL();
394     handle->epCallbackDirectly = 0U;
395     OSA_EXIT_CRITICAL();
396 #endif
397 
398     handle->state         = (uint8_t)kUSB_DeviceStateDefault;
399     handle->deviceAddress = 0U;
400 
401     for (count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++)
402     {
403         handle->epCallback[count].callbackFn    = (usb_device_endpoint_callback_t)NULL;
404         handle->epCallback[count].callbackParam = NULL;
405         handle->epCallback[count].isBusy        = 0U;
406     }
407 
408     /* Call device callback to notify the application that the USB bus reset signal detected.
409     the deviceCallback is the second parameter of USB_DeviceInit */
410 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
411     status = handle->deviceCallback(handle, kUSB_DeviceEventBusReset, NULL);
412     if (kStatus_USB_Success != status)
413     {
414         return status;
415     }
416 #else
417     (void)handle->deviceCallback(handle, kUSB_DeviceEventBusReset, NULL);
418 #endif
419 
420     handle->isResetting = 0U;
421     return kStatus_USB_Success;
422 }
423 
424 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
425 /*!
426  * @brief Handle the suspend notification.
427  *
428  * This function is used to handle the suspend notification.
429  *
430  * @param handle                 The device handle. It equals the value returned from USB_DeviceInit.
431  * @param message                The device callback message handle.
432  *
433  * @return A USB error code or kStatus_USB_Success.
434  */
USB_DeviceSuspendNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)435 static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle,
436                                                   usb_device_callback_message_struct_t *message)
437 {
438     /* Call device callback to notify the application that the USB bus suspend signal detected.
439     the deviceCallback is the second parameter of USB_DeviceInit */
440 
441     return handle->deviceCallback(handle, kUSB_DeviceEventSuspend, NULL);
442 }
443 
444 /*!
445  * @brief Handle the resume notification.
446  *
447  * This function is used to handle the resume notification.
448  *
449  * @param handle                 The device handle. It equals the value returned from USB_DeviceInit.
450  * @param message                The device callback message handle.
451  *
452  * @return A USB error code or kStatus_USB_Success.
453  */
USB_DeviceResumeNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)454 static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle,
455                                                  usb_device_callback_message_struct_t *message)
456 {
457     /* Call device callback to notify the application that the USB bus resume signal detected.
458     the deviceCallback is the second parameter of USB_DeviceInit */
459     return handle->deviceCallback(handle, kUSB_DeviceEventResume, NULL);
460 }
461 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
462 /*!
463  * @brief Handle the suspend notification.
464  *
465  * This function is used to handle the suspend notification.
466  *
467  * @param handle                 The device handle. It equals the value returned from USB_DeviceInit.
468  * @param message                The device callback message handle.
469  *
470  * @return A USB error code or kStatus_USB_Success.
471  */
USB_DeviceSleepNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)472 static usb_status_t USB_DeviceSleepNotification(usb_device_struct_t *handle,
473                                                 usb_device_callback_message_struct_t *message)
474 {
475     /* Call device callback to notify the application that the USB bus suspend signal detected.
476     the deviceCallback is the second parameter of USB_DeviceInit */
477 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
478     if (kStatus_USB_Success != USB_DeviceSetStatus(handle, kUSB_DeviceStatusRemoteWakeup, message->buffer))
479     {
480         return kStatus_USB_Error;
481     }
482 #else
483     (void)USB_DeviceSetStatus(handle, kUSB_DeviceStatusRemoteWakeup, message->buffer);
484 #endif
485 
486     return handle->deviceCallback(handle, kUSB_DeviceEventSleeped, NULL);
487 }
488 #endif
489 
490 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
491 
492 #if (defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U))
USB_DeviceErrorNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)493 static usb_status_t USB_DeviceErrorNotification(usb_device_struct_t *handle,
494                                                 usb_device_callback_message_struct_t *message)
495 {
496     /* Call device callback to notify the application that the USB bus error signal detected.
497     the deviceCallback is the second parameter of USB_DeviceInit */
498     return handle->deviceCallback(handle, kUSB_DeviceEventError, NULL);
499 }
500 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
501 
502 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
503 /*!
504  * @brief Handle the detach notification.
505  *
506  * This function is used to handle the detach notification.
507  *
508  * @param handle                 The device handle. It equals the value returned from USB_DeviceInit.
509  * @param message                The device callback message handle.
510  *
511  * @return A USB error code or kStatus_USB_Success.
512  */
USB_DeviceDetachNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)513 static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle,
514                                                  usb_device_callback_message_struct_t *message)
515 {
516     /* Call device callback to notify the application that the device is disconnected from a host.
517     the deviceCallback is the second parameter of USB_DeviceInit */
518     return handle->deviceCallback(handle, kUSB_DeviceEventDetach, NULL);
519 }
520 
521 /*!
522  * @brief Handle the attach notification.
523  *
524  * This function is used to handle the attach notification.
525  *
526  * @param handle                 The device handle. It equals the value returned from USB_DeviceInit.
527  * @param message                The device callback message handle.
528  *
529  * @return A USB error code or kStatus_USB_Success.
530  */
USB_DeviceAttachNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)531 static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle,
532                                                  usb_device_callback_message_struct_t *message)
533 {
534     /* Call device callback to notify the application that the device is connected to a host.
535     the deviceCallback is the second parameter of USB_DeviceInit */
536     return handle->deviceCallback(handle, kUSB_DeviceEventAttach, NULL);
537 }
538 #endif
539 
540 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
541 
542 /*!
543  * @brief Handle the DCP detection finished notification.
544  *
545  * This function is used to notify detection notification.
546  *
547  * @param handle                 The device handle. It equals the value returned from USB_DeviceInit.
548  * @param message                The device callback message handle.
549  *
550  * @return A USB error code or kStatus_USB_Success.
551  */
552 
USB_DeviceDcdDetectFinihsedNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)553 static usb_status_t USB_DeviceDcdDetectFinihsedNotification(usb_device_struct_t *handle,
554                                                             usb_device_callback_message_struct_t *message)
555 {
556     /* Call device callback to notify the application that the DCP facility is detected.
557     the deviceCallback is the second parameter of USB_DeviceInit */
558     return handle->deviceCallback(handle, kUSB_DeviceEventDcdDetectionfinished, message->buffer);
559 }
560 #endif
561 
562 #if (defined(USB_DEVICE_CONFIG_SOF_NOTIFICATIONS) && (USB_DEVICE_CONFIG_SOF_NOTIFICATIONS > 0U))
563 /*!
564  * @brief Handle the SOF notification.
565  *
566  * This function is used to handle the SOF notification.
567  *
568  * @param handle                 The device handle. It equals the value returned from USB_DeviceInit.
569  * @param message                The device callback message handle.
570  *
571  * @return A USB error code or kStatus_USB_Success.
572  */
USB_DeviceSOFNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)573 static usb_status_t USB_DeviceSOFNotification(usb_device_struct_t *handle,
574                                                  usb_device_callback_message_struct_t *message)
575 {
576     /* Call device callback to notify the application that the SOF packet is received.
577     the deviceCallback is the second parameter of USB_DeviceInit */
578     return handle->deviceCallback(handle, kUSB_DeviceEventSOF, NULL);
579 }
580 #endif
581 
582 /*!
583  * @brief Handle the attach notification.
584  *
585  * This function is used to handle the attach notification.
586  *
587  * @param handle                 The device handle. It equals the value returned from USB_DeviceInit.
588  * @param message                The device callback message handle.
589  *
590  * @return A USB error code or kStatus_USB_Success.
591  */
USB_DeviceNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)592 static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message)
593 {
594     uint8_t endpoint  = message->code & USB_ENDPOINT_NUMBER_MASK;
595     uint8_t direction = (message->code & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
596                         USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
597     usb_status_t status                    = kStatus_USB_Error;
598     usb_device_notification_t deviceNotify = (usb_device_notification_t)message->code;
599     switch (deviceNotify)
600     {
601         case kUSB_DeviceNotifyBusReset:
602             status = USB_DeviceResetNotification(handle, message);
603             break;
604 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
605         case kUSB_DeviceNotifySuspend:
606             status = USB_DeviceSuspendNotification(handle, message);
607             break;
608         case kUSB_DeviceNotifyResume:
609             status = USB_DeviceResumeNotification(handle, message);
610             break;
611 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
612         case kUSB_DeviceNotifyLPMSleep:
613             status = USB_DeviceSleepNotification(handle, message);
614             break;
615 #endif
616 #endif
617 
618 #if (defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U))
619         case kUSB_DeviceNotifyError:
620             status = USB_DeviceErrorNotification(handle, message);
621             break;
622 #endif
623 
624 #if USB_DEVICE_CONFIG_DETACH_ENABLE
625         case kUSB_DeviceNotifyDetach:
626             status = USB_DeviceDetachNotification(handle, message);
627             break;
628         case kUSB_DeviceNotifyAttach:
629             status = USB_DeviceAttachNotification(handle, message);
630             break;
631 #endif
632 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
633         case kUSB_DeviceNotifyDcdDetectFinished:
634             status = USB_DeviceDcdDetectFinihsedNotification(handle, message);
635             break;
636 #endif
637 #if (defined(USB_DEVICE_CONFIG_SOF_NOTIFICATIONS) && (USB_DEVICE_CONFIG_SOF_NOTIFICATIONS > 0U))
638         case kUSB_DeviceNotifySOF:
639             status = USB_DeviceSOFNotification(handle, message);
640             break;
641 #endif
642 
643         default:
644             if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS)
645             {
646                 if (NULL != handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn)
647                 {
648                     usb_device_endpoint_callback_message_struct_t endpointCallbackMessage;
649                     endpointCallbackMessage.buffer  = message->buffer;
650                     endpointCallbackMessage.length  = message->length;
651                     endpointCallbackMessage.isSetup = message->isSetup;
652                     if (0U != message->isSetup)
653                     {
654                         handle->epCallback[0].isBusy = 0U;
655                         handle->epCallback[1].isBusy = 0U;
656                     }
657                     else
658                     {
659                         handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U;
660                     }
661                     /* Call endpoint callback, callbackFn is in the third parameter of USB_DeviceInitEndpoint */
662                     status = handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn(
663                         handle, &endpointCallbackMessage,
664                         handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam);
665                 }
666             }
667             break;
668     }
669     return status;
670 }
671 
672 /*!
673  * @brief Notify the device that the controller status changed.
674  *
675  * This function is used to notify the device that the controller status changed.
676  *
677  * @param handle                 The device handle. It equals the value returned from USB_DeviceInit.
678  * @param message                The device callback message handle.
679  *
680  * @return A USB error code or kStatus_USB_Success.
681  */
USB_DeviceNotificationTrigger(void * handle,void * msg)682 usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg)
683 {
684     usb_device_struct_t *deviceHandle             = (usb_device_struct_t *)handle;
685     usb_device_callback_message_struct_t *message = (usb_device_callback_message_struct_t *)msg;
686 
687     if ((NULL == msg) || (NULL == handle))
688     {
689         return kStatus_USB_InvalidHandle;
690     }
691 
692     /* The device callback is invalid or not. */
693     if (NULL == deviceHandle->deviceCallback)
694     {
695         return kStatus_USB_Error;
696     }
697 
698 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
699     if (0U != deviceHandle->epCallbackDirectly)
700     {
701         if ((0U != (message->code & USB_ENDPOINT_NUMBER_MASK)) && (0U == (message->code & 0x70U)))
702         {
703             return USB_DeviceNotification(deviceHandle, message);
704         }
705     }
706 
707     /* Add the message to message queue when the device task is enabled. */
708     if (KOSA_StatusSuccess != OSA_MsgQPut(deviceHandle->notificationQueue, (osa_msg_handle_t)message))
709     {
710         return kStatus_USB_Busy;
711     }
712     return kStatus_USB_Success;
713 #else
714     /* Handle the notification by calling USB_DeviceNotification. */
715     return USB_DeviceNotification(deviceHandle, message);
716 #endif
717 }
718 
719 /*!
720  * @brief Initialize the USB device stack.
721  *
722  * This function initializes the USB device module specified by the controllerId.
723  *
724  * @param controllerId   The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
725  * @param deviceCallback Function pointer of the device callback.
726  * @param handle          It is out parameter, is used to return pointer of the device handle to the caller.
727  *
728  * @retval kStatus_USB_Success              The device is initialized successfully.
729  * @retval kStatus_USB_InvalidHandle        The handle is a NULL pointer.
730  * @retval kStatus_USB_Busy                 Cannot allocate a device handle.
731  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller according to the controller id.
732  * @retval kStatus_USB_InvalidControllerInterface  The controller driver interfaces is invaild, There is an empty
733  * interface entity.
734  * @retval kStatus_USB_Error                The macro USB_DEVICE_CONFIG_ENDPOINTS is more than IP's endpoint number.
735  *                                          Or, the device has been initialized.
736  *                                          Or, the message queue is created failed.
737  */
USB_DeviceInit(uint8_t controllerId,usb_device_callback_t deviceCallback,usb_device_handle * handle)738 usb_status_t USB_DeviceInit(uint8_t controllerId, usb_device_callback_t deviceCallback, usb_device_handle *handle)
739 {
740     usb_device_struct_t *deviceHandle = NULL;
741     usb_status_t error;
742     uint32_t count;
743 
744     if (NULL == handle)
745     {
746         return kStatus_USB_InvalidHandle;
747     }
748 
749     /* Allocate a device handle by using the controller id. */
750     error = USB_DeviceAllocateHandle(controllerId, &deviceHandle);
751 
752     if (kStatus_USB_Success != error)
753     {
754         return error;
755     }
756 
757     /* Save the device callback */
758     deviceHandle->deviceCallback = deviceCallback;
759     /* Save the controller id */
760     deviceHandle->controllerId = controllerId;
761     /* Clear the device address */
762     deviceHandle->deviceAddress = 0U;
763     /* Clear the device reset state */
764     deviceHandle->isResetting = 0U;
765 
766     /* Initialize the endpoints */
767     for (count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++)
768     {
769         deviceHandle->epCallback[count].callbackFn    = (usb_device_endpoint_callback_t)NULL;
770         deviceHandle->epCallback[count].callbackParam = NULL;
771         deviceHandle->epCallback[count].isBusy        = 0U;
772     }
773 
774     /* Get the controller interface according to the controller id */
775     error = USB_DeviceGetControllerInterface(controllerId, &deviceHandle->controllerInterface);
776     if (kStatus_USB_Success != error)
777     {
778 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
779         if (kStatus_USB_Success != USB_DeviceFreeHandle(deviceHandle))
780         {
781             return kStatus_USB_Error;
782         }
783 #else
784         (void)USB_DeviceFreeHandle(deviceHandle);
785 #endif
786         return error;
787     }
788     if (NULL == deviceHandle->controllerInterface)
789     {
790 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
791         if (kStatus_USB_Success != USB_DeviceFreeHandle(deviceHandle))
792         {
793             return kStatus_USB_Error;
794         }
795 #else
796         (void)USB_DeviceFreeHandle(deviceHandle);
797 #endif
798         return kStatus_USB_ControllerNotFound;
799     }
800     if (((usb_device_controller_init_t)NULL == deviceHandle->controllerInterface->deviceInit) ||
801         ((usb_device_controller_deinit_t)NULL == deviceHandle->controllerInterface->deviceDeinit) ||
802         ((usb_device_controller_send_t)NULL == deviceHandle->controllerInterface->deviceSend) ||
803         ((usb_device_controller_recv_t)NULL == deviceHandle->controllerInterface->deviceRecv) ||
804         ((usb_device_controller_cancel_t)NULL == deviceHandle->controllerInterface->deviceCancel) ||
805         ((usb_device_controller_control_t)NULL == deviceHandle->controllerInterface->deviceControl))
806     {
807 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
808         if (kStatus_USB_Success != USB_DeviceFreeHandle(deviceHandle))
809         {
810             return kStatus_USB_Error;
811         }
812 #else
813         (void)USB_DeviceFreeHandle(deviceHandle);
814 #endif
815         return kStatus_USB_InvalidControllerInterface;
816     }
817 
818 #if USB_DEVICE_CONFIG_USE_TASK
819     /* Create a message queue when the device handle is enabled. */
820     deviceHandle->notificationQueue = (osa_msgq_handle_t)&deviceHandle->notificationQueueBuffer[0];
821     if (KOSA_StatusSuccess !=
822         OSA_MsgQCreate(deviceHandle->notificationQueue, USB_DEVICE_CONFIG_MAX_MESSAGES, USB_DEVICE_MESSAGES_SIZE))
823     {
824 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
825         error = USB_DeviceDeinit(deviceHandle);
826         if (kStatus_USB_Success != error)
827         {
828             return error;
829         }
830 #else
831         (void)USB_DeviceDeinit(deviceHandle);
832 #endif
833         return kStatus_USB_Error;
834     }
835 #endif
836 
837     *handle = deviceHandle;
838 
839     /* Initialize the controller, the callbackFn is initialized in USB_DeviceGetControllerInterface */
840     error = deviceHandle->controllerInterface->deviceInit(controllerId, deviceHandle, &deviceHandle->controllerHandle);
841     if (kStatus_USB_Success != error)
842     {
843 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
844         if (kStatus_USB_Success != USB_DeviceDeinit(deviceHandle))
845         {
846             return kStatus_USB_Error;
847         }
848 #else
849         (void)USB_DeviceDeinit(deviceHandle);
850 #endif
851         *handle = NULL;
852         return error;
853     }
854     /* Set the device to deafult state */
855     deviceHandle->state = (uint8_t)kUSB_DeviceStateDefault;
856 
857     return error;
858 }
859 
860 /*!
861  * @brief Enable the device functionality.
862  *
863  * The function enables the device functionality, so that the device can be recognized by the host when the device
864  * detects that it has been connected to a host.
865  *
866  * @param handle The device handle got from USB_DeviceInit.
867  *
868  * @retval kStatus_USB_Success              The device is run successfully.
869  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
870  * @retval kStatus_USB_InvalidHandle        The device handle is a NULL pointer. Or the controller handle is invalid.
871  *
872  */
USB_DeviceRun(usb_device_handle handle)873 usb_status_t USB_DeviceRun(usb_device_handle handle)
874 {
875     return USB_DeviceControl(handle, kUSB_DeviceControlRun, NULL);
876 }
877 /*!
878  * @brief Disable the device functionality.
879  *
880  * The function disables the device functionality, after this function called, even the device is detached to the host,
881  * and the device can't work.
882  *
883  * @param handle The device handle got from USB_DeviceInit.
884  *
885  * @retval kStatus_USB_Success              The device is stopped successfully.
886  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
887  * @retval kStatus_USB_InvalidHandle        The device handle is a NULL pointer. Or the controller handle is invalid.
888  */
USB_DeviceStop(usb_device_handle handle)889 usb_status_t USB_DeviceStop(usb_device_handle handle)
890 {
891     return USB_DeviceControl(handle, kUSB_DeviceControlStop, NULL);
892 }
893 /*!
894  * @brief De-initialize the device controller.
895  *
896  * The function de-initializes the device controller specified by the handle.
897  *
898  * @param handle The device handle got from USB_DeviceInit.
899  *
900  * @retval kStatus_USB_Success              The device is stopped successfully.
901  * @retval kStatus_USB_InvalidHandle        The device handle is a NULL pointer. Or the controller handle is invalid.
902  */
USB_DeviceDeinit(usb_device_handle handle)903 usb_status_t USB_DeviceDeinit(usb_device_handle handle)
904 {
905     usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
906 
907     if (NULL == deviceHandle)
908     {
909         return kStatus_USB_InvalidHandle;
910     }
911     /* De-initialize the controller */
912     if (NULL != deviceHandle->controllerInterface)
913     {
914         /* the callbackFn is initialized in USB_DeviceGetControllerInterface */
915 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
916         if (kStatus_USB_Success != deviceHandle->controllerInterface->deviceDeinit(deviceHandle->controllerHandle))
917         {
918             return kStatus_USB_Error;
919         }
920 #else
921         (void)deviceHandle->controllerInterface->deviceDeinit(deviceHandle->controllerHandle);
922 #endif
923         deviceHandle->controllerInterface = (usb_device_controller_interface_struct_t *)NULL;
924     }
925 
926 #if USB_DEVICE_CONFIG_USE_TASK
927     /* Destroy the message queue. */
928     if (NULL != deviceHandle->notificationQueue)
929     {
930 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
931         if (KOSA_StatusSuccess != OSA_MsgQDestroy(deviceHandle->notificationQueue))
932         {
933             return kStatus_USB_Error;
934         }
935 #else
936         (void)OSA_MsgQDestroy(deviceHandle->notificationQueue);
937 #endif
938         deviceHandle->notificationQueue = NULL;
939     }
940 #endif
941 
942     /* Free the device handle. */
943 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
944     if (kStatus_USB_Success != USB_DeviceFreeHandle(deviceHandle))
945     {
946         return kStatus_USB_Error;
947     }
948 #else
949     (void)USB_DeviceFreeHandle(deviceHandle);
950 #endif
951     return kStatus_USB_Success;
952 }
953 
954 /*!
955  * @brief Send data through a specified endpoint.
956  *
957  * The function is used to send data through a specified endpoint.
958  *
959  * @param handle The device handle got from USB_DeviceInit.
960  * @param endpointAddress Endpoint index.
961  * @param buffer The memory address to hold the data need to be sent.
962  * @param length The data length need to be sent.
963  *
964  * @retval kStatus_USB_Success              The send request is sent successfully.
965  * @retval kStatus_USB_InvalidHandle        The handle is a NULL pointer. Or the controller handle is invalid.
966  * @retval kStatus_USB_Busy                 Cannot allocate dtds for current transfer in EHCI driver.
967  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
968  * @retval kStatus_USB_Error                The device is doing reset.
969  *
970  * @note The return value just means if the sending request is successful or not; the transfer done is notified by the
971  * corresponding callback function.
972  * Currently, only one transfer request can be supported for one specific endpoint.
973  * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
974  * should implement a queue in the application level.
975  * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
976  * callback).
977  */
USB_DeviceSendRequest(usb_device_handle handle,uint8_t endpointAddress,uint8_t * buffer,uint32_t length)978 usb_status_t USB_DeviceSendRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length)
979 {
980     return USB_DeviceTransfer(
981         handle,
982         (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
983         buffer, length);
984 }
985 
986 /*!
987  * @brief Receive data through a specified endpoint.
988  *
989  * The function is used to receive data through a specified endpoint.
990  *
991  * @param handle The device handle got from USB_DeviceInit.
992  * @param endpointAddress Endpoint index.
993  * @param buffer The memory address to save the received data.
994  * @param length The data length want to be received.
995  *
996  * @retval kStatus_USB_Success              The receive request is sent successfully.
997  * @retval kStatus_USB_InvalidHandle        The handle is a NULL pointer. Or the controller handle is invalid.
998  * @retval kStatus_USB_Busy                 Cannot allocate dtds for current transfer in EHCI driver.
999  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
1000  * @retval kStatus_USB_Error                The device is doing reset.
1001  *
1002  * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the
1003  * corresponding callback function.
1004  * Currently, only one transfer request can be supported for one specific endpoint.
1005  * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1006  * should implement a queue in the application level.
1007  * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1008  * callback).
1009  */
USB_DeviceRecvRequest(usb_device_handle handle,uint8_t endpointAddress,uint8_t * buffer,uint32_t length)1010 usb_status_t USB_DeviceRecvRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length)
1011 {
1012     return USB_DeviceTransfer(
1013         handle,
1014         (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
1015         buffer, length);
1016 }
1017 
1018 /*!
1019  * @brief Cancel the pending transfer in a specified endpoint.
1020  *
1021  * The function is used to cancel the pending transfer in a specified endpoint.
1022  *
1023  * @param handle The device handle got from USB_DeviceInit.
1024  * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1025  *
1026  * @retval kStatus_USB_Success              The transfer is cancelled.
1027  * @retval kStatus_USB_InvalidHandle        The handle is a NULL pointer. Or the controller handle is invalid.
1028  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
1029  */
USB_DeviceCancel(usb_device_handle handle,uint8_t endpointAddress)1030 usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress)
1031 {
1032     usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
1033     usb_status_t status;
1034 
1035     if (NULL == deviceHandle)
1036     {
1037         return kStatus_USB_InvalidHandle;
1038     }
1039 
1040     if (NULL != deviceHandle->controllerInterface)
1041     {
1042         /* the callbackFn is initialized in USB_DeviceGetControllerInterface */
1043         status = deviceHandle->controllerInterface->deviceCancel(deviceHandle->controllerHandle, endpointAddress);
1044     }
1045     else
1046     {
1047         status = kStatus_USB_ControllerNotFound;
1048     }
1049     return status;
1050 }
1051 
1052 /*!
1053  * @brief Initialize a specified endpoint.
1054  *
1055  * The function is used to initialize a specified endpoint and the corresponding endpoint callback is also initialized.
1056  *
1057  * @param handle The device handle got from USB_DeviceInit.
1058  * @param epInit Endpoint initialization structure. Please refer to the structure usb_device_endpoint_init_struct_t.
1059  * @param epCallback Endpoint callback structure. Please refer to the structure
1060  * usb_device_endpoint_callback_struct_t.
1061  *
1062  * @retval kStatus_USB_Success              The endpoint is initialized successfully.
1063  * @retval kStatus_USB_InvalidHandle        The handle is a NULL pointer. Or the controller handle is invalid.
1064  * @retval kStatus_USB_InvalidParameter     The epInit or epCallback is NULL pointer. Or the endpoint number is
1065  * not less than USB_DEVICE_CONFIG_ENDPOINTS.
1066  * @retval kStatus_USB_Busy                 The endpoint is busy in EHCI driver.
1067  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
1068  */
USB_DeviceInitEndpoint(usb_device_handle handle,usb_device_endpoint_init_struct_t * epInit,usb_device_endpoint_callback_struct_t * epCallback)1069 usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle,
1070                                     usb_device_endpoint_init_struct_t *epInit,
1071                                     usb_device_endpoint_callback_struct_t *epCallback)
1072 {
1073     usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
1074     uint8_t endpoint;
1075     uint8_t direction;
1076 
1077     if (NULL == deviceHandle)
1078     {
1079         return kStatus_USB_InvalidHandle;
1080     }
1081 
1082     if ((NULL == epInit) || (NULL == epCallback))
1083     {
1084         return kStatus_USB_InvalidParameter;
1085     }
1086 
1087     endpoint  = epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK;
1088     direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1089                 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
1090 
1091     if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS)
1092     {
1093         deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn = epCallback->callbackFn;
1094         deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam =
1095             epCallback->callbackParam;
1096         deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U;
1097     }
1098     else
1099     {
1100         return kStatus_USB_InvalidParameter;
1101     }
1102     return USB_DeviceControl(handle, kUSB_DeviceControlEndpointInit, epInit);
1103 }
1104 
1105 /*!
1106  * @brief De-initizlize a specified endpoint.
1107  *
1108  * The function is used to de-initizlize a specified endpoint.
1109  *
1110  * @param handle The device handle got from USB_DeviceInit.
1111  * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1112  *
1113  * @retval kStatus_USB_Success              The endpoint is de-initialized successfully.
1114  * @retval kStatus_USB_InvalidHandle        The handle is a NULL pointer. Or the controller handle is invalid.
1115  * @retval kStatus_USB_InvalidParameter     The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
1116  * @retval kStatus_USB_Busy                 The endpoint is busy in EHCI driver.
1117  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
1118  */
USB_DeviceDeinitEndpoint(usb_device_handle handle,uint8_t endpointAddress)1119 usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress)
1120 {
1121     usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
1122     uint8_t endpoint                  = endpointAddress & USB_ENDPOINT_NUMBER_MASK;
1123     uint8_t direction                 = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1124                         USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
1125     usb_status_t status;
1126 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
1127     OSA_SR_ALLOC();
1128 #endif
1129 
1130     if (NULL == deviceHandle)
1131     {
1132         return kStatus_USB_InvalidHandle;
1133     }
1134 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
1135     OSA_ENTER_CRITICAL();
1136     deviceHandle->epCallbackDirectly = 1U;
1137     OSA_EXIT_CRITICAL();
1138 #endif
1139     status = USB_DeviceControl(handle, kUSB_DeviceControlEndpointDeinit, &endpointAddress);
1140 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
1141     OSA_ENTER_CRITICAL();
1142     deviceHandle->epCallbackDirectly = 0U;
1143     OSA_EXIT_CRITICAL();
1144 #endif
1145 
1146     if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS)
1147     {
1148         deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn =
1149             (usb_device_endpoint_callback_t)NULL;
1150         deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam = NULL;
1151         deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy        = 0U;
1152     }
1153     else
1154     {
1155         return kStatus_USB_InvalidParameter;
1156     }
1157     return status;
1158 }
1159 
1160 /*!
1161  * @brief Stall a specified endpoint.
1162  *
1163  * The function is used to stall a specified endpoint.
1164  *
1165  * @param handle The device handle got from USB_DeviceInit.
1166  * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1167  *
1168  * @retval kStatus_USB_Success              The endpoint is stalled successfully.
1169  * @retval kStatus_USB_InvalidHandle        The handle is a NULL pointer. Or the controller handle is invalid.
1170  * @retval kStatus_USB_InvalidParameter     The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
1171  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
1172  */
USB_DeviceStallEndpoint(usb_device_handle handle,uint8_t endpointAddress)1173 usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress)
1174 {
1175     if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS)
1176     {
1177         return USB_DeviceControl(handle, kUSB_DeviceControlEndpointStall, &endpointAddress);
1178     }
1179     else
1180     {
1181         return kStatus_USB_InvalidParameter;
1182     }
1183 }
1184 
1185 /*!
1186  * @brief Un-stall a specified endpoint.
1187  *
1188  * The function is used to un-stall a specified endpoint.
1189  *
1190  * @param handle The device handle got from USB_DeviceInit.
1191  * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1192  *
1193  * @retval kStatus_USB_Success              The endpoint is un-stalled successfully.
1194  * @retval kStatus_USB_InvalidHandle        The handle is a NULL pointer. Or the controller handle is invalid.
1195  * @retval kStatus_USB_InvalidParameter     The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
1196  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
1197  */
USB_DeviceUnstallEndpoint(usb_device_handle handle,uint8_t endpointAddress)1198 usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress)
1199 {
1200     if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS)
1201     {
1202         return USB_DeviceControl(handle, kUSB_DeviceControlEndpointUnstall, &endpointAddress);
1203     }
1204     else
1205     {
1206         return kStatus_USB_InvalidParameter;
1207     }
1208 }
1209 
1210 /*!
1211  * @brief Get the status of the selected item.
1212  *
1213  * The function is used to get the status of the selected item.
1214  *
1215  * @param handle The device handle got from USB_DeviceInit.
1216  * @param type   The selected item. Please refer to the structure usb_device_status_t.
1217  * @param param  The param type is determined by the selected item.
1218  *
1219  * @retval kStatus_USB_Success              Get status successfully.
1220  * @retval kStatus_USB_InvalidHandle        The handle is a NULL pointer. Or the controller handle is invalid.
1221  * @retval kStatus_USB_InvalidParameter     The param is NULL pointer.
1222  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
1223  * @retval kStatus_USB_Error                Unsupported type.
1224  */
USB_DeviceGetStatus(usb_device_handle handle,usb_device_status_t type,void * param)1225 usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param)
1226 {
1227     uint8_t *temp8;
1228     usb_status_t status = kStatus_USB_Error;
1229 
1230     if (NULL == param)
1231     {
1232         return kStatus_USB_InvalidParameter;
1233     }
1234     switch (type)
1235     {
1236 #if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
1237         case kUSB_DeviceStatusGetCurrentFrameCount:
1238             status = USB_DeviceControl(handle, kUSB_DeviceControlGetCurrentFrameCount, param);
1239             break;
1240 #endif
1241         case kUSB_DeviceStatusSpeed:
1242             status = USB_DeviceControl(handle, kUSB_DeviceControlGetSpeed, param);
1243             break;
1244         case kUSB_DeviceStatusOtg:
1245             status = USB_DeviceControl(handle, kUSB_DeviceControlGetOtgStatus, param);
1246             break;
1247         case kUSB_DeviceStatusDeviceState:
1248             temp8  = (uint8_t *)param;
1249             status = kStatus_USB_Success;
1250             *temp8 = ((usb_device_struct_t *)handle)->state;
1251             break;
1252         case kUSB_DeviceStatusAddress:
1253             temp8  = (uint8_t *)param;
1254             status = kStatus_USB_Success;
1255             *temp8 = ((usb_device_struct_t *)handle)->deviceAddress;
1256             break;
1257         case kUSB_DeviceStatusDevice:
1258             status = USB_DeviceControl(handle, kUSB_DeviceControlGetDeviceStatus, param);
1259             break;
1260         case kUSB_DeviceStatusEndpoint:
1261             status = USB_DeviceControl(handle, kUSB_DeviceControlGetEndpointStatus, param);
1262             break;
1263         case kUSB_DeviceStatusSynchFrame:
1264             status = USB_DeviceControl(handle, kUSB_DeviceControlGetSynchFrame, param);
1265             break;
1266 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1267         case kUSB_DeviceStatusRemoteWakeup:
1268             temp8  = (uint8_t *)param;
1269             status = kStatus_USB_Success;
1270             *temp8 = ((usb_device_struct_t *)handle)->remotewakeup;
1271             break;
1272 #endif
1273         default:
1274             /*no action*/
1275             break;
1276     }
1277     return status;
1278 }
1279 
1280 /*!
1281  * @brief Set the status of the selected item.
1282  *
1283  * The function is used to set the status of the selected item.
1284  *
1285  * @param handle The device handle got from USB_DeviceInit.
1286  * @param type The selected item. Please refer to the structure usb_device_status_t.
1287  * @param param The param type is determined by the selected item.
1288  *
1289  * @retval kStatus_USB_Success              Set status successfully.
1290  * @retval kStatus_USB_InvalidHandle        The handle is a NULL pointer. Or the controller handle is invalid.
1291  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
1292  * @retval kStatus_USB_Error                Unsupported type, or the param is NULL pointer.
1293  */
USB_DeviceSetStatus(usb_device_handle handle,usb_device_status_t type,void * param)1294 usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param)
1295 {
1296     usb_status_t status = kStatus_USB_Error;
1297     switch (type)
1298     {
1299 #if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) ||                  \
1300      (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \
1301     (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U))
1302         case kUSB_DeviceStatusTestMode:
1303             status = USB_DeviceControl(handle, kUSB_DeviceControlSetTestMode, param);
1304             break;
1305 #endif
1306         case kUSB_DeviceStatusOtg:
1307             status = USB_DeviceControl(handle, kUSB_DeviceControlSetOtgStatus, param);
1308             break;
1309         case kUSB_DeviceStatusDeviceState:
1310             if (NULL != param)
1311             {
1312                 status                                 = kStatus_USB_Success;
1313                 ((usb_device_struct_t *)handle)->state = (uint8_t)(*(uint8_t *)param);
1314             }
1315             break;
1316         case kUSB_DeviceStatusAddress:
1317             if ((uint8_t)kUSB_DeviceStateAddressing != ((usb_device_struct_t *)handle)->state)
1318             {
1319                 if (NULL != param)
1320                 {
1321                     status                                         = kStatus_USB_Success;
1322                     ((usb_device_struct_t *)handle)->deviceAddress = (uint8_t)(*(uint8_t *)param);
1323                     ((usb_device_struct_t *)handle)->state         = (uint8_t)kUSB_DeviceStateAddressing;
1324                     status = USB_DeviceControl(handle, kUSB_DeviceControlPreSetDeviceAddress,
1325                                                &((usb_device_struct_t *)handle)->deviceAddress);
1326                 }
1327             }
1328             else
1329             {
1330                 status = USB_DeviceControl(handle, kUSB_DeviceControlSetDeviceAddress,
1331                                            &((usb_device_struct_t *)handle)->deviceAddress);
1332             }
1333             break;
1334         case kUSB_DeviceStatusBusResume:
1335             status = USB_DeviceControl(handle, kUSB_DeviceControlResume, param);
1336             break;
1337         case kUSB_DeviceStatusBusSleepResume:
1338             status = USB_DeviceControl(handle, kUSB_DeviceControlSleepResume, param);
1339             break;
1340 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1341         case kUSB_DeviceStatusRemoteWakeup:
1342             if (NULL != param)
1343             {
1344                 status                                        = kStatus_USB_Success;
1345                 ((usb_device_struct_t *)handle)->remotewakeup = (uint8_t)(*(uint8_t *)param);
1346             }
1347             break;
1348 #endif
1349         case kUSB_DeviceStatusBusSuspend:
1350             status = USB_DeviceControl(handle, kUSB_DeviceControlSuspend, param);
1351             break;
1352         case kUSB_DeviceStatusBusSleep:
1353             status = USB_DeviceControl(handle, kUSB_DeviceControlSleep, param);
1354             break;
1355         default:
1356             /*no action*/
1357             break;
1358     }
1359     return status;
1360 }
1361 
1362 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
1363 /*!
1364  * @brief Enable the device dcd module.
1365  *
1366  * The function enable the device dcd module.
1367  *
1368  * @param[in] handle The device handle got from #USB_DeviceInit.
1369  *
1370  * @retval kStatus_USB_Success              The device could run.
1371  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
1372  * @retval kStatus_USB_InvalidHandle        The device handle is a NULL pointer. Or the controller handle is invalid.
1373  *
1374  */
USB_DeviceDcdEnable(usb_device_handle handle)1375 usb_status_t USB_DeviceDcdEnable(usb_device_handle handle)
1376 {
1377     return USB_DeviceControl(handle, kUSB_DeviceControlDcdEnable, NULL);
1378 }
1379 /*!
1380  * @brief Disable the device dcd module.
1381  *
1382  * The function disable the device dcd module.
1383  *
1384  * @param[in] handle The device handle got from #USB_DeviceInit.
1385  *
1386  * @retval kStatus_USB_Success              The dcd is reset and stopped.
1387  * @retval kStatus_USB_ControllerNotFound   Cannot find the controller.
1388  * @retval kStatus_USB_InvalidHandle        The device handle is a NULL pointer or the controller handle is invalid.
1389  *
1390  */
USB_DeviceDcdDisable(usb_device_handle handle)1391 usb_status_t USB_DeviceDcdDisable(usb_device_handle handle)
1392 {
1393     return USB_DeviceControl(handle, kUSB_DeviceControlDcdDisable, NULL);
1394 }
1395 #endif
1396 
1397 #if USB_DEVICE_CONFIG_USE_TASK
1398 /*!
1399  * @brief Device task function.
1400  *
1401  * The function is used to handle controller message.
1402  * This function should not be called in application directly.
1403  *
1404  * @param handle The device handle got from USB_DeviceInit.
1405  */
USB_DeviceTaskFunction(void * deviceHandle)1406 void USB_DeviceTaskFunction(void *deviceHandle)
1407 {
1408     usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
1409     usb_device_callback_message_struct_t message;
1410 
1411     if (NULL != deviceHandle)
1412     {
1413         message.buffer  = NULL;
1414         message.length  = 0U;
1415         message.code    = 0U;
1416         message.isSetup = 0U;
1417         /* Get the message from the queue */
1418         if (KOSA_StatusSuccess ==
1419             OSA_MsgQGet(handle->notificationQueue, (osa_msg_handle_t)&message, USB_OSA_WAIT_TIMEOUT))
1420         {
1421             /* Handle the message */
1422 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1423             if (kStatus_USB_Success != USB_DeviceNotification(handle, &message))
1424             {
1425 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
1426                 usb_echo("notification error\n");
1427 #endif
1428             }
1429 #else
1430             (void)USB_DeviceNotification(handle, &message);
1431 #endif
1432         }
1433     }
1434 }
1435 #endif
1436 
1437 /*!
1438  * @brief Get device stack version function.
1439  *
1440  * The function is used to get device stack version.
1441  *
1442  * @param[out] version The version structure pointer to keep the device stack version.
1443  *
1444  */
USB_DeviceGetVersion(uint32_t * version)1445 void USB_DeviceGetVersion(uint32_t *version)
1446 {
1447     if (NULL != version)
1448     {
1449         *version =
1450             (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX);
1451     }
1452 }
1453 
1454 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) ||   \
1455     (((defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1456       (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))))
1457 /*!
1458  * @brief Update the hardware tick.
1459  *
1460  * The function is used to update the hardware tick.
1461  *
1462  * @param[in] handle The device handle got from #USB_DeviceInit.
1463  * @param[in] tick Current hardware tick.
1464  *
1465  */
USB_DeviceUpdateHwTick(usb_device_handle handle,uint64_t tick)1466 usb_status_t USB_DeviceUpdateHwTick(usb_device_handle handle, uint64_t tick)
1467 {
1468     usb_device_struct_t *deviceHandle;
1469     usb_status_t status = kStatus_USB_Success;
1470 #if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) && \
1471     (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
1472 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1473     (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
1474     /* fix misra 11.8 */
1475     uint64_t tempValue;
1476 #endif
1477 
1478     if (handle == NULL)
1479     {
1480         return kStatus_USB_InvalidHandle;
1481     }
1482     deviceHandle = (usb_device_struct_t *)handle;
1483 
1484     deviceHandle->hwTick = tick;
1485 #if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) && \
1486     (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
1487 #ifndef USBHSDCD_IRQS
1488     status = USB_DeviceControl(handle, kUSB_DeviceControlUpdateHwTick, (void *)(&deviceHandle->hwTick));
1489 #endif
1490 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1491     (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
1492     tempValue = deviceHandle->hwTick;
1493     status = USB_DeviceControl(handle, kUSB_DeviceControlUpdateHwTick, (void *)(&tempValue));
1494 #endif
1495     return status;
1496 }
1497 #endif
1498 #endif /* USB_DEVICE_CONFIG_NUM */
1499