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