common: Add NXP's USB serial code.
[gps-watch.git] / src / common / usb_device_khci.c
1 /*
2  * The Clear BSD License
3  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
4  * Copyright 2016 - 2018 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
40 #include "fsl_device_registers.h"
41
42 #if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
43
44 #include "usb_khci.h"
45 #include "usb_device_dci.h"
46
47 #include "usb_device_khci.h"
48
49 /*******************************************************************************
50  * Definitions
51  ******************************************************************************/
52 #if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM > 0U)
53
54 /* USB_STACK_USE_DEDICATED_RAM */
55 #if defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
56
57 #if (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL)
58 #if (FSL_FEATURE_USB_KHCI_USB_RAM > 512U)
59 #else
60 #error The dedicated RAM length is not more than 512 Bytes, the SOC does not support this case.
61 #endif
62 #endif /* USB_STACK_USE_DEDICATED_RAM */
63
64 #else
65 #error The SOC does not suppoort dedicated RAM case.
66 #endif /* USB_STACK_USE_DEDICATED_RAM */
67
68 #endif
69
70 /*******************************************************************************
71  * Prototypes
72  ******************************************************************************/
73 static usb_status_t USB_DeviceKhciEndpointTransfer(
74     usb_device_khci_state_struct_t *khciState, uint8_t endpoint, uint8_t direction, uint8_t *buffer, uint32_t length);
75 static void USB_DeviceKhciPrimeNextSetup(usb_device_khci_state_struct_t *khciState);
76 static void USB_DeviceKhciSetDefaultState(usb_device_khci_state_struct_t *khciState);
77 static usb_status_t USB_DeviceKhciEndpointInit(usb_device_khci_state_struct_t *khciState,
78                                                usb_device_endpoint_init_struct_t *epInit);
79 static usb_status_t USB_DeviceKhciEndpointDeinit(usb_device_khci_state_struct_t *khciState, uint8_t ep);
80 static usb_status_t USB_DeviceKhciEndpointStall(usb_device_khci_state_struct_t *khciState, uint8_t ep);
81 static usb_status_t USB_DeviceKhciEndpointUnstall(usb_device_khci_state_struct_t *khciState, uint8_t ep);
82 static void USB_DeviceKhciInterruptTokenDone(usb_device_khci_state_struct_t *khciState);
83 static void USB_DeviceKhciInterruptReset(usb_device_khci_state_struct_t *khciState);
84 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
85 static void USB_DeviceKhciInterruptSleep(usb_device_khci_state_struct_t *khciState);
86 static void USB_DeviceKhciInterruptResume(usb_device_khci_state_struct_t *khciState);
87 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
88 static void USB_DeviceKhciInterruptStall(usb_device_khci_state_struct_t *khciState);
89 #if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)
90 static void USB_DeviceKhciInterruptError(usb_device_khci_state_struct_t *khciState);
91 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
92
93 extern usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg);
94
95 /*******************************************************************************
96  * Variables
97  ******************************************************************************/
98
99 /* Apply for BDT buffer, 512-byte alignment */
100 USB_BDT USB_RAM_ADDRESS_ALIGNMENT(512) static uint8_t s_UsbDeviceKhciBdtBuffer[USB_DEVICE_CONFIG_KHCI][512U];
101
102 /* Apply for khci device state structure */
103 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_khci_state_struct_t
104     s_UsbDeviceKhciState[USB_DEVICE_CONFIG_KHCI];
105
106 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
107     (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U))
108 /* Apply for device dcd state structure */
109 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_dcd_state_struct_t
110     s_UsbDeviceDcdState[USB_DEVICE_CONFIG_KHCI];
111 #endif
112
113 /* Apply for KHCI DMA aligned buffer when marco USB_DEVICE_CONFIG_KHCI_DMA_ALIGN enabled */
114 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint32_t s_UsbDeviceKhciDmaAlignBuffer
115     [USB_DEVICE_CONFIG_KHCI][((USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH - 1U) >> 2U) + 1U];
116
117 /*******************************************************************************
118  * Code
119  ******************************************************************************/
120
121 /*!
122  * @brief Write the BDT to start a transfer.
123  *
124  * The function is used to start a transfer by writing the BDT.
125  *
126  * @param khciState       Pointer of the device KHCI state structure.
127  * @param endpoint         Endpoint number.
128  * @param direction        The direction of the endpoint, 0U - USB_OUT, 1U - USB_IN.
129  * @param buffer           The memory address to save the received data, or the memory address to hold the data need to
130  * be sent.
131  * @param length           The length of the data.
132  *
133  * @return A USB error code or kStatus_USB_Success.
134  */
135 static usb_status_t USB_DeviceKhciEndpointTransfer(
136     usb_device_khci_state_struct_t *khciState, uint8_t endpoint, uint8_t direction, uint8_t *buffer, uint32_t length)
137 {
138     uint32_t index = ((uint32_t)endpoint << 1U) | (uint32_t)direction;
139     USB_OSA_SR_ALLOC();
140
141     /* Enter critical */
142     USB_OSA_ENTER_CRITICAL();
143
144     /* Flag the endpoint is busy. */
145     khciState->endpointState[index].stateUnion.stateBitField.transferring = 1U;
146
147     /* Add the data buffer address to the BDT. */
148     USB_KHCI_BDT_SET_ADDRESS((uint32_t)khciState->bdt, endpoint, direction,
149                              khciState->endpointState[index].stateUnion.stateBitField.bdtOdd, (uint32_t)buffer);
150
151     /* Change the BDT control field to start the transfer. */
152     USB_KHCI_BDT_SET_CONTROL(
153         (uint32_t)khciState->bdt, endpoint, direction, khciState->endpointState[index].stateUnion.stateBitField.bdtOdd,
154         USB_LONG_TO_LITTLE_ENDIAN(USB_KHCI_BDT_BC(length) | USB_KHCI_BDT_OWN | USB_KHCI_BDT_DTS |
155                                   USB_KHCI_BDT_DATA01(khciState->endpointState[index].stateUnion.stateBitField.data0)));
156
157     /* Exit critical */
158     USB_OSA_EXIT_CRITICAL();
159
160     /* Clear the token busy state */
161     khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
162     return kStatus_USB_Success;
163 }
164
165 /*!
166  * @brief Prime a next setup transfer.
167  *
168  * The function is used to prime a buffer in control out pipe to wait for receiving the host's setup packet.
169  *
170  * @param khciState       Pointer of the device KHCI state structure.
171  *
172  */
173 static void USB_DeviceKhciPrimeNextSetup(usb_device_khci_state_struct_t *khciState)
174 {
175 /* Update the endpoint state */
176 /* Save the buffer address used to receive the setup packet. */
177 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
178     defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) &&             \
179     defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
180     /* In case of lowpower mode enabled, it requires to put the setup packet buffer(16 bytes) into the USB RAM so
181      * that the setup packet would wake up the USB.
182      */
183     khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer =
184         (uint8_t *)(khciState->bdt + 0x200U - 0x10U) +
185         khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.bdtOdd *
186             USB_SETUP_PACKET_SIZE;
187 #else
188     khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer =
189         (uint8_t *)&khciState->setupPacketBuffer[0] +
190         khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.bdtOdd *
191             USB_SETUP_PACKET_SIZE;
192 #endif
193     /* Clear the transferred length. */
194     khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferDone = 0U;
195     /* Save the data length expected to get from a host. */
196     khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferLength = USB_SETUP_PACKET_SIZE;
197     /* Save the data buffer DMA align flag. */
198     khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.dmaAlign = 1U;
199     /* Set the DATA0/1 to DATA0. */
200     khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.data0 = 0U;
201
202     USB_DeviceKhciEndpointTransfer(khciState, USB_CONTROL_ENDPOINT, USB_OUT,
203                                    khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer,
204                                    USB_SETUP_PACKET_SIZE);
205 }
206
207 /*!
208  * @brief Set device controller state to default state.
209  *
210  * The function is used to set device controller state to default state.
211  * The function will be called when USB_DeviceKhciInit called or the control type kUSB_DeviceControlGetEndpointStatus
212  * received in USB_DeviceKhciControl.
213  *
214  * @param khciState       Pointer of the device KHCI state structure.
215  *
216  */
217 static void USB_DeviceKhciSetDefaultState(usb_device_khci_state_struct_t *khciState)
218 {
219     uint8_t interruptFlag;
220
221     /* Clear the error state register */
222     khciState->registerBase->ERRSTAT = 0xFFU;
223
224     /* Setting this bit to 1U resets all the BDT ODD ping/pong fields to 0U, which then specifies the EVEN BDT bank. */
225     khciState->registerBase->CTL |= USB_CTL_ODDRST_MASK;
226
227     /* Clear the device address */
228     khciState->registerBase->ADDR = 0U;
229
230     /* Clear the endpoint state and disable the endpoint */
231     for (uint8_t count = 0U; count < USB_DEVICE_CONFIG_ENDPOINTS; count++)
232     {
233         USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_OUT, 0U, 0U);
234         USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_OUT, 1U, 0U);
235         USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_IN, 0U, 0U);
236         USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_IN, 1U, 0U);
237
238         khciState->endpointState[((uint32_t)count << 1U) | USB_OUT].stateUnion.state = 0U;
239         khciState->endpointState[((uint32_t)count << 1U) | USB_IN].stateUnion.state = 0U;
240         khciState->registerBase->ENDPOINT[count].ENDPT = 0x00U;
241     }
242     khciState->isDmaAlignBufferInusing = 0U;
243
244     /* Clear the BDT odd reset flag */
245     khciState->registerBase->CTL &= ~USB_CTL_ODDRST_MASK;
246
247     /* Enable all error */
248     khciState->registerBase->ERREN = 0xFFU;
249
250     /* Enable reset, sof, token, stall interrupt */
251     interruptFlag = kUSB_KhciInterruptReset
252 #if 0U
253                     | kUSB_KhciInterruptSofToken
254 #endif
255                     | kUSB_KhciInterruptTokenDone | kUSB_KhciInterruptStall;
256
257 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
258     /* Enable suspend interruprt */
259     interruptFlag |= kUSB_KhciInterruptSleep;
260 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
261
262 #if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)
263     /* Enable error interruprt */
264     interruptFlag |= kUSB_KhciInterruptError;
265 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
266     /* Write the interrupt enable register */
267     khciState->registerBase->INTEN = interruptFlag;
268
269     /* Clear reset flag */
270     khciState->isResetting = 0U;
271
272     khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
273 }
274
275 /*!
276  * @brief Initialize a specified endpoint.
277  *
278  * The function is used to initialize a specified endpoint.
279  *
280  * @param khciState       Pointer of the device KHCI state structure.
281  * @param epInit          The endpoint initialization structure pointer.
282  *
283  * @return A USB error code or kStatus_USB_Success.
284  */
285 static usb_status_t USB_DeviceKhciEndpointInit(usb_device_khci_state_struct_t *khciState,
286                                                usb_device_endpoint_init_struct_t *epInit)
287 {
288     uint16_t maxPacketSize = epInit->maxPacketSize;
289     uint8_t endpoint = (epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK);
290     uint8_t direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
291                         USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
292     uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
293
294     /* Make the endpoint max packet size align with USB Specification 2.0. */
295     if (USB_ENDPOINT_ISOCHRONOUS == epInit->transferType)
296     {
297         if (maxPacketSize > USB_DEVICE_MAX_FS_ISO_MAX_PACKET_SIZE)
298         {
299             maxPacketSize = USB_DEVICE_MAX_FS_ISO_MAX_PACKET_SIZE;
300         }
301     }
302     else
303     {
304         if (maxPacketSize > USB_DEVICE_MAX_FS_NONE_ISO_MAX_PACKET_SIZE)
305         {
306             maxPacketSize = USB_DEVICE_MAX_FS_NONE_ISO_MAX_PACKET_SIZE;
307         }
308         /* Enable an endpoint to perform handshaking during a transaction to this endpoint. */
309         khciState->registerBase->ENDPOINT[endpoint].ENDPT |= USB_ENDPT_EPHSHK_MASK;
310     }
311     /* Set the endpoint idle */
312     khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
313     /* Save the max packet size of the endpoint */
314     khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize = maxPacketSize;
315     /* Set the data toggle to DATA0 */
316     khciState->endpointState[index].stateUnion.stateBitField.data0 = 0U;
317     /* Clear the endpoint stalled state */
318     khciState->endpointState[index].stateUnion.stateBitField.stalled = 0U;
319     /* Set the ZLT field */
320     khciState->endpointState[index].stateUnion.stateBitField.zlt = epInit->zlt;
321     /* Enable the endpoint. */
322     khciState->registerBase->ENDPOINT[endpoint].ENDPT |=
323         (USB_IN == direction) ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK;
324 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_LOW) && (FSL_FEATURE_USB_KHCI_HAS_STALL_LOW > 0U)
325     /*control endpoint bidirection stall default state shoule be enable, iso doesn't support stall*/
326     if ((USB_ENDPOINT_BULK == epInit->transferType) || (USB_ENDPOINT_INTERRUPT == epInit->transferType))
327     {
328         if(USB_IN == direction)
329         {
330             if (endpoint < 8)
331             {
332                 khciState->registerBase->STALL_IL_DIS |= (1<<endpoint);
333             }
334 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH) && (FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH > 0U)
335             else if ((endpoint >= 8) && (endpoint < 16))
336             {
337                 khciState->registerBase->STALL_IH_DIS |= (1<<(endpoint-8));
338             }
339 #endif
340         }
341         else
342         {
343             if (endpoint < 8)
344             {
345                 khciState->registerBase->STALL_OL_DIS |= (1<<endpoint);
346             }
347 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH) && (FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH > 0U)
348             else if ((endpoint >= 8) && (endpoint < 16))
349             {
350                 khciState->registerBase->STALL_OH_DIS |= (1<<(endpoint-8));
351             }
352 #endif
353         }
354     }
355     else if ((USB_ENDPOINT_CONTROL == epInit->transferType))
356     {
357        khciState->registerBase->STALL_IL_DIS &= ~(1<<endpoint);
358        khciState->registerBase->STALL_OL_DIS &= ~(1<<endpoint);
359     }
360     else
361     {
362     }
363 #endif
364
365     /* Prime a transfer to receive next setup packet when the endpoint is control out endpoint. */
366     if ((USB_CONTROL_ENDPOINT == endpoint) && (USB_OUT == direction))
367     {
368         USB_DeviceKhciPrimeNextSetup(khciState);
369     }
370
371     return kStatus_USB_Success;
372 }
373
374 /*!
375  * @brief De-initialize a specified endpoint.
376  *
377  * The function is used to de-initialize a specified endpoint.
378  * Current transfer of the endpoint will be canceled and the specified endpoint will be disabled.
379  *
380  * @param khciState       Pointer of the device KHCI state structure.
381  * @param ep               The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
382  *
383  * @return A USB error code or kStatus_USB_Success.
384  */
385 static usb_status_t USB_DeviceKhciEndpointDeinit(usb_device_khci_state_struct_t *khciState, uint8_t ep)
386 {
387     uint8_t endpoint = (ep & USB_ENDPOINT_NUMBER_MASK);
388     uint8_t direction =
389         (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
390     uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
391
392     /* Cancel the transfer of the endpoint */
393     USB_DeviceKhciCancel(khciState, ep);
394
395     /* Disable the endpoint */
396     khciState->registerBase->ENDPOINT[endpoint].ENDPT = 0x00U;
397     /* Clear the max packet size */
398     khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize = 0U;
399
400     return kStatus_USB_Success;
401 }
402
403 /*!
404  * @brief Stall a specified endpoint.
405  *
406  * The function is used to stall a specified endpoint.
407  * Current transfer of the endpoint will be canceled and the specified endpoint will be stalled.
408  *
409  * @param khciState       Pointer of the device KHCI state structure.
410  * @param ep               The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
411  *
412  * @return A USB error code or kStatus_USB_Success.
413  */
414 static usb_status_t USB_DeviceKhciEndpointStall(usb_device_khci_state_struct_t *khciState, uint8_t ep)
415 {
416     uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK;
417     uint8_t direction =
418         (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
419     uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
420
421     /* Cancel the transfer of the endpoint */
422     USB_DeviceKhciCancel(khciState, ep);
423
424     /* Set endpoint stall flag. */
425     khciState->endpointState[index].stateUnion.stateBitField.stalled = 1U;
426 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_LOW) && (FSL_FEATURE_USB_KHCI_HAS_STALL_LOW > 0U)
427     if (USB_CONTROL_ENDPOINT != endpoint)
428     {
429         if(USB_IN == direction)
430         {
431             if (endpoint < 8)
432             {
433                 khciState->registerBase->STALL_IL_DIS &= ~(1<<endpoint);
434             }
435 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH) && (FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH > 0U)
436             else if ((endpoint >= 8) && (endpoint < 16))
437             {
438                 khciState->registerBase->STALL_IH_DIS &= ~(1<<(endpoint-8));
439             }
440 #endif
441         }
442         else
443         {
444             if (endpoint < 8)
445             {
446                 khciState->registerBase->STALL_OL_DIS &= ~(1<<endpoint);
447             }
448 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH) && (FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH > 0U)
449             else if ((endpoint >= 8) && (endpoint < 16))
450             {
451                 khciState->registerBase->STALL_OH_DIS &= ~(1<<(endpoint-8));
452             }
453 #endif
454         }
455     }
456 #endif
457     /* Set endpoint stall in BDT. And then if the host send a IN/OUT tanscation, the device will response a STALL state.
458      */
459     USB_KHCI_BDT_SET_CONTROL(
460         (uint32_t)khciState->bdt, endpoint, direction, khciState->endpointState[index].stateUnion.stateBitField.bdtOdd,
461         USB_LONG_TO_LITTLE_ENDIAN(
462             (uint32_t)(USB_KHCI_BDT_BC(khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize) |
463                        USB_KHCI_BDT_DTS | USB_KHCI_BDT_STALL | USB_KHCI_BDT_OWN)));
464
465     khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
466
467     return kStatus_USB_Success;
468 }
469
470 /*!
471  * @brief Un-stall a specified endpoint.
472  *
473  * The function is used to un-stall a specified endpoint.
474  * Current transfer of the endpoint will be canceled and the specified endpoint will be un-stalled.
475  *
476  * @param khciState       Pointer of the device KHCI state structure.
477  * @param ep               The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
478  *
479  * @return A USB error code or kStatus_USB_Success.
480  */
481 static usb_status_t USB_DeviceKhciEndpointUnstall(usb_device_khci_state_struct_t *khciState, uint8_t ep)
482 {
483     uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK;
484     uint8_t direction =
485         (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
486     uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
487
488     /* Clear the endpoint stall state */
489     khciState->endpointState[index].stateUnion.stateBitField.stalled = 0U;
490     /* Reset the endpoint data toggle to DATA0 */
491     khciState->endpointState[index].stateUnion.stateBitField.data0 = 0U;
492
493     /* Clear stall state in BDT */
494     for (uint8_t i = 0U; i < 2U; i++)
495     {
496         USB_KHCI_BDT_SET_CONTROL(
497             (uint32_t)khciState->bdt, endpoint, direction, i,
498             USB_LONG_TO_LITTLE_ENDIAN(
499                 (uint32_t)(USB_KHCI_BDT_BC(khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize) |
500                            USB_KHCI_BDT_DTS | USB_KHCI_BDT_DATA01(0U))));
501     }
502
503     /* Clear stall state in endpoint control register */
504     khciState->registerBase->ENDPOINT[endpoint].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
505 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_LOW) && (FSL_FEATURE_USB_KHCI_HAS_STALL_LOW > 0U)
506     if (USB_CONTROL_ENDPOINT != endpoint)
507     {
508         if(USB_IN == direction)
509         {
510             if (endpoint < 8)
511             {
512                 khciState->registerBase->STALL_IL_DIS |= (1<<endpoint);
513             }
514 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH) && (FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH > 0U)
515             else if ((endpoint >= 8) && (endpoint < 16))
516             {
517                 khciState->registerBase->STALL_IH_DIS |= (1<<(endpoint-8));
518             }
519 #endif
520         }
521         else
522         {
523             if (endpoint < 8)
524             {
525                 khciState->registerBase->STALL_OL_DIS |= (1<<endpoint);
526             }
527 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH) && (FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH > 0U)
528             else if ((endpoint >= 8) && (endpoint < 16))
529             {
530                 khciState->registerBase->STALL_OH_DIS |= (1<<(endpoint-8));
531             }
532 #endif
533         }
534     }
535 #endif
536     if ((USB_CONTROL_ENDPOINT != endpoint))
537     {
538         /* Cancel the transfer of the endpoint */
539         USB_DeviceKhciCancel(khciState, ep);
540     }
541
542     /* Prime a transfer to receive next setup packet when the endpoint is a control out endpoint. */
543     if ((USB_CONTROL_ENDPOINT == endpoint) && (USB_OUT == direction))
544     {
545         USB_DeviceKhciPrimeNextSetup(khciState);
546     }
547
548     khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
549
550     return kStatus_USB_Success;
551 }
552
553 /*!
554  * @brief Handle the token done interrupt.
555  *
556  * The function is used to handle the token done interrupt.
557  *
558  * @param khciState       Pointer of the device KHCI state structure.
559  *
560  */
561 static void USB_DeviceKhciInterruptTokenDone(usb_device_khci_state_struct_t *khciState)
562 {
563     uint32_t control;
564     uint32_t length;
565     uint32_t remainingLength;
566     uint8_t *bdtBuffer;
567     usb_device_callback_message_struct_t message;
568     uint8_t endpoint;
569     uint8_t direction;
570     uint8_t bdtOdd;
571     uint8_t isSetup;
572     uint8_t index;
573     uint8_t stateRegister = khciState->registerBase->STAT;
574
575     /* Get the endpoint number to identify which one triggers the token done interrupt. */
576     endpoint = (stateRegister & USB_STAT_ENDP_MASK) >> USB_STAT_ENDP_SHIFT;
577
578     /* Get the direction of the endpoint number. */
579     direction = (stateRegister & USB_STAT_TX_MASK) >> USB_STAT_TX_SHIFT;
580
581     /* Get the finished BDT ODD. */
582     bdtOdd = (stateRegister & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT;
583
584     /* Clear token done interrupt flag. */
585     khciState->registerBase->ISTAT = kUSB_KhciInterruptTokenDone;
586
587     /* Get the Control field of the BDT element according to the endpoint number, the direction and finished BDT ODD. */
588     control = USB_KHCI_BDT_GET_CONTROL((uint32_t)khciState->bdt, endpoint, direction, bdtOdd);
589
590     /* Get the buffer field of the BDT element according to the endpoint number, the direction and finished BDT ODD. */
591     bdtBuffer = (uint8_t *)USB_KHCI_BDT_GET_ADDRESS((uint32_t)khciState->bdt, endpoint, direction, bdtOdd);
592
593     /* Get the transferred length. */
594     length = ((USB_LONG_FROM_LITTLE_ENDIAN(control)) >> 16U) & 0x3FFU;
595
596     /* Get the transferred length. */
597     isSetup = (USB_KHCI_BDT_DEVICE_SETUP_TOKEN == ((uint8_t)(((USB_LONG_FROM_LITTLE_ENDIAN(control)) >> 2U) & 0x0FU))) ?
598                   1U :
599                   0U;
600
601     index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
602
603     if (0U == khciState->endpointState[index].stateUnion.stateBitField.transferring)
604     {
605         return;
606     }
607
608     if (isSetup)
609     {
610         khciState->setupBufferIndex = bdtOdd;
611     }
612
613     /* USB_IN, Send completed */
614     if (direction == USB_IN)
615     {
616         /* The transferred length */
617         khciState->endpointState[index].transferDone += length;
618
619         /* Remaining length */
620         remainingLength = khciState->endpointState[index].transferLength - khciState->endpointState[index].transferDone;
621
622         /* Change the data toggle flag */
623         khciState->endpointState[index].stateUnion.stateBitField.data0 ^= 1U;
624         /* Change the BDT odd toggle flag */
625         khciState->endpointState[index].stateUnion.stateBitField.bdtOdd ^= 1U;
626
627         /* Whether the transfer is completed or not. */
628         /*
629          * The transfer is completed when one of the following conditions meet:
630          * 1. The remaining length is zero.
631          * 2. The length of current transcation is less than the max packet size of the current pipe.
632          */
633         if ((0U == remainingLength) ||
634             (khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize > length))
635         {
636             message.length = khciState->endpointState[index].transferDone;
637             message.buffer = khciState->endpointState[index].transferBuffer;
638             khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
639
640             /*
641              * Whether need to send ZLT when the pipe is control in pipe and the transferred length of current
642              * transaction equals to max packet size.
643              */
644             if ((length) && (!(length % khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize)))
645             {
646                 if (USB_CONTROL_ENDPOINT == endpoint)
647                 {
648                     usb_setup_struct_t *setup_packet =
649                         (usb_setup_struct_t
650                              *)(&khciState->setupPacketBuffer[(USB_SETUP_PACKET_SIZE * khciState->setupBufferIndex)]);
651                     /*
652                      * Send the ZLT and terminate the token done interrupt service when the tranferred length in data
653                      * phase
654                      * is less than the host request.
655                      */
656                     if (USB_SHORT_FROM_LITTLE_ENDIAN(setup_packet->wLength) >
657                         khciState->endpointState[index].transferLength)
658                     {
659                         (void)USB_DeviceKhciEndpointTransfer(khciState, endpoint, USB_IN, (uint8_t *)NULL, 0U);
660                         return;
661                     }
662                 }
663                 else if (khciState->endpointState[index].stateUnion.stateBitField.zlt)
664                 {
665                     (void)USB_DeviceKhciEndpointTransfer(khciState, endpoint, USB_IN, (uint8_t *)NULL, 0U);
666                     return;
667                 }
668                 else
669                 {
670                 }
671             }
672         }
673         else
674         {
675             /* Send remaining data and terminate the token done interrupt service. */
676             (void)USB_DeviceKhciSend(khciState, endpoint | (USB_IN << 0x07U),
677                                      khciState->endpointState[index].transferBuffer, remainingLength);
678             return;
679         }
680     }
681     else
682     {
683         if ((USB_CONTROL_ENDPOINT == endpoint) && (0U == length))
684         {
685             message.length = 0U;
686             message.buffer = (uint8_t *)NULL;
687         }
688         else
689         {
690             if (0U == khciState->endpointState[index].stateUnion.stateBitField.dmaAlign)
691             {
692                 uint8_t *buffer = (uint8_t *)USB_LONG_FROM_LITTLE_ENDIAN(
693                     USB_KHCI_BDT_GET_ADDRESS((uint32_t)khciState->bdt, endpoint, USB_OUT,
694                                              khciState->endpointState[index].stateUnion.stateBitField.bdtOdd));
695                 uint8_t *transferBuffer =
696                     khciState->endpointState[index].transferBuffer + khciState->endpointState[index].transferDone;
697                 if (buffer != transferBuffer)
698                 {
699                     for (uint32_t i = 0U; i < length; i++)
700                     {
701                         transferBuffer[i] = buffer[i];
702                     }
703                 }
704                 khciState->isDmaAlignBufferInusing = 0U;
705             }
706             /* The transferred length */
707             khciState->endpointState[index].transferDone += length;
708             /* Remaining length */
709             remainingLength =
710                 khciState->endpointState[index].transferLength - khciState->endpointState[index].transferDone;
711
712             if ((USB_CONTROL_ENDPOINT == endpoint) && isSetup)
713             {
714                 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.data0 = 1U;
715                 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_IN].stateUnion.stateBitField.data0 = 1U;
716             }
717             else
718             {
719                 khciState->endpointState[index].stateUnion.stateBitField.data0 ^= 1U;
720             }
721             khciState->endpointState[index].stateUnion.stateBitField.bdtOdd ^= 1U;
722             if ((!khciState->endpointState[index].transferLength) || (!remainingLength) ||
723                 (khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize > length))
724             {
725                 message.length = khciState->endpointState[index].transferDone;
726                 if (isSetup)
727                 {
728                     message.buffer = bdtBuffer;
729                 }
730                 else
731                 {
732                     message.buffer = khciState->endpointState[index].transferBuffer;
733                 }
734                 khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
735             }
736             else
737             {
738                 /* Receive remaining data and terminate the token done interrupt service. */
739                 USB_DeviceKhciRecv(khciState, (endpoint) | (USB_OUT << 0x07U),
740                                    khciState->endpointState[index].transferBuffer, remainingLength);
741                 return;
742             }
743         }
744     }
745
746     message.isSetup = isSetup;
747     message.code = (endpoint) | (uint8_t)(((uint32_t)direction << 0x07U));
748
749     /* Notify the up layer the KHCI status changed. */
750     USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
751
752     khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
753 }
754
755 /*!
756  * @brief Handle the USB bus reset interrupt.
757  *
758  * The function is used to handle the USB bus reset interrupt.
759  *
760  * @param khciState       Pointer of the device KHCI state structure.
761  *
762  */
763 static void USB_DeviceKhciInterruptReset(usb_device_khci_state_struct_t *khciState)
764 {
765     usb_device_callback_message_struct_t message;
766
767     /* Set KHCI reset flag */
768     khciState->isResetting = 1U;
769
770     /* Clear the reset interrupt */
771     khciState->registerBase->ISTAT = (kUSB_KhciInterruptReset);
772 #if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
773     /* Clear the suspend interrupt */
774     khciState->registerBase->ISTAT = (kUSB_KhciInterruptSleep);
775     khciState->registerBase->USBCTRL &= ~USB_USBCTRL_SUSP_MASK;
776 #endif
777
778     message.buffer = (uint8_t *)NULL;
779     message.code = kUSB_DeviceNotifyBusReset;
780     message.length = 0U;
781     message.isSetup = 0U;
782     /* Notify up layer the USB bus reset signal detected. */
783     USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
784 }
785
786 /* The USB suspend and resume signals need to be detected and handled when the low power or remote wakeup function
787  * enabled. */
788 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
789
790 /*!
791  * @brief Handle the suspend interrupt.
792  *
793  * The function is used to handle the suspend interrupt when the suspend signal detected.
794  *
795  * @param khciState       Pointer of the device KHCI state structure.
796  *
797  */
798 static void USB_DeviceKhciInterruptSleep(usb_device_khci_state_struct_t *khciState)
799 {
800     usb_device_callback_message_struct_t message;
801
802     /* Enable the resume interrupt */
803     khciState->registerBase->INTEN |= kUSB_KhciInterruptResume;
804     khciState->registerBase->USBTRC0 |= USB_USBTRC0_USBRESMEN_MASK;
805     khciState->registerBase->USBCTRL |= USB_USBCTRL_SUSP_MASK;
806     /* Disable the suspend interrupt */
807     khciState->registerBase->INTEN &= ~((uint32_t)kUSB_KhciInterruptSleep);
808
809     /* Clear the suspend interrupt */
810     khciState->registerBase->ISTAT = (kUSB_KhciInterruptSleep);
811     /* Clear the resume interrupt */
812     khciState->registerBase->ISTAT = (kUSB_KhciInterruptResume);
813
814     message.buffer = (uint8_t *)NULL;
815     message.code = kUSB_DeviceNotifySuspend;
816     message.length = 0U;
817     message.isSetup = 0U;
818
819     /* Notify up layer the USB suspend signal detected. */
820     USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
821 }
822
823 /*!
824  * @brief Handle the resume interrupt.
825  *
826  * The function is used to handle the resume interrupt when the resume signal detected.
827  *
828  * @param khciState       Pointer of the device KHCI state structure.
829  *
830  */
831 static void USB_DeviceKhciInterruptResume(usb_device_khci_state_struct_t *khciState)
832 {
833     usb_device_callback_message_struct_t message;
834
835     khciState->registerBase->USBCTRL &= ~USB_USBCTRL_SUSP_MASK;
836     /* Enable the suspend interrupt */
837     khciState->registerBase->INTEN |= kUSB_KhciInterruptSleep;
838     /* Disable the resume interrupt */
839     khciState->registerBase->INTEN &= ~((uint32_t)kUSB_KhciInterruptResume);
840     khciState->registerBase->USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK;
841
842     /* Clear the resume interrupt */
843     khciState->registerBase->ISTAT = (kUSB_KhciInterruptResume);
844     /* Clear the suspend interrupt */
845     khciState->registerBase->ISTAT = (kUSB_KhciInterruptSleep);
846
847     message.buffer = (uint8_t *)NULL;
848     message.code = kUSB_DeviceNotifyResume;
849     message.length = 0U;
850     message.isSetup = 0U;
851
852     /* Notify up layer the USB resume signal detected. */
853     USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
854 }
855 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
856
857 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) && \
858     (defined(FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED) && (FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED > 0U))
859 /*!
860  * @brief Handle the VBUS rising interrupt.
861  *
862  * The function is used to handle the VBUS rising interrupt when the VBUS rising signal detected.
863  *
864  * @param khciState       Pointer of the device KHCI state structure.
865  *
866  */
867 static void USB_DeviceKhciInterruptVbusRising(usb_device_khci_state_struct_t *khciState)
868 {
869     usb_device_callback_message_struct_t message;
870
871     /* Disable the VBUS rising interrupt */
872     khciState->registerBase->MISCCTRL &= ~USB_MISCCTRL_VREDG_EN_MASK;
873     /* Enable the VBUS rising interrupt */
874     khciState->registerBase->MISCCTRL |= USB_MISCCTRL_VREDG_EN_MASK;
875
876     message.buffer = (uint8_t *)NULL;
877     message.code = kUSB_DeviceNotifyAttach;
878     message.length = 0U;
879     message.isSetup = 0U;
880
881     /* Notify up layer the USB VBUS rising signal detected. */
882     USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
883 }
884
885 /*!
886  * @brief Handle the VBUS falling interrupt.
887  *
888  * The function is used to handle the VBUS falling interrupt when the VBUS falling signal detected.
889  *
890  * @param khciState       Pointer of the device KHCI state structure.
891  *
892  */
893 static void USB_DeviceKhciInterruptVbusFalling(usb_device_khci_state_struct_t *khciState)
894 {
895     usb_device_callback_message_struct_t message;
896
897     /* Disable the VBUS rising interrupt */
898     khciState->registerBase->MISCCTRL &= ~USB_MISCCTRL_VFEDG_EN_MASK;
899     /* Enable the VBUS rising interrupt */
900     khciState->registerBase->MISCCTRL |= USB_MISCCTRL_VFEDG_EN_MASK;
901
902     message.buffer = (uint8_t *)NULL;
903     message.code = kUSB_DeviceNotifyDetach;
904     message.length = 0U;
905     message.isSetup = 0U;
906
907     /* Notify up layer the USB VBUS falling signal detected. */
908     USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
909 }
910 #endif /* USB_DEVICE_CONFIG_DETACH_ENABLE || FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED */
911
912 #if 0U
913 /*!
914  * @brief Handle the sof interrupt.
915  *
916  * The function is used to handle the sof interrupt.
917  *
918  * @param khciState       Pointer of the device KHCI state structure.
919  *
920  */
921 void USB_DeviceKhciInterruptSof(usb_device_khci_state_struct_t *khciState)
922 {
923     khciState->registerBase->ISTAT = (kUSB_KhciInterruptSofToken);
924
925     khciState->registerBase->ISTAT = (kUSB_KhciInterruptResume);
926 }
927 #endif
928
929 /*!
930  * @brief Handle endpoint stalled interrupt.
931  *
932  * The function is used to handle  endpoint stalled interrupt.
933  *
934  * @param khciState       Pointer of the device KHCI state structure.
935  *
936  */
937 static void USB_DeviceKhciInterruptStall(usb_device_khci_state_struct_t *khciState)
938 {
939     /* Clear the endpoint stalled interrupt flag */
940     while (khciState->registerBase->ISTAT & (kUSB_KhciInterruptStall))
941     {
942         khciState->registerBase->ISTAT = (kUSB_KhciInterruptStall);
943     }
944
945     /* Un-stall the control in and out pipe when the control in or out pipe stalled. */
946     if ((khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_IN].stateUnion.stateBitField.stalled) ||
947         (khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.stalled))
948     {
949         USB_DeviceKhciEndpointUnstall(
950             khciState, (USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)));
951         USB_DeviceKhciEndpointUnstall(
952             khciState, (USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)));
953     }
954 }
955
956 #if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)
957 static void USB_DeviceKhciInterruptError(usb_device_khci_state_struct_t *khciState)
958 {
959     usb_device_callback_message_struct_t message;
960
961     khciState->registerBase->ISTAT = (kUSB_KhciInterruptError);
962
963     message.buffer = (uint8_t *)NULL;
964     message.code = kUSB_DeviceNotifyError;
965     message.length = 0U;
966     message.isSetup = 0U;
967
968     /* Notify up layer the USB error detected. */
969     USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
970 }
971 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
972
973 /*!
974  * @brief Initialize the USB device KHCI instance.
975  *
976  * This function initizlizes the USB device KHCI module specified by the controllerId.
977  *
978  * @param controllerId The controller id of the USB IP. Please refer to enumeration type usb_controller_index_t.
979  * @param handle        Pointer of the device handle, used to identify the device object is belonged to.
980  * @param khciHandle   It is out parameter, is used to return pointer of the device KHCI handle to the caller.
981  *
982  * @return A USB error code or kStatus_USB_Success.
983  */
984 usb_status_t USB_DeviceKhciInit(uint8_t controllerId,
985                                 usb_device_handle handle,
986                                 usb_device_controller_handle *khciHandle)
987 {
988     usb_device_khci_state_struct_t *khciState;
989     uint32_t khci_base[] = USB_BASE_ADDRS;
990 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
991     (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U))
992     usb_device_dcd_state_struct_t *dcdState;
993     uint32_t dcd_base[] = USBDCD_BASE_ADDRS;
994 #endif
995
996     if (((controllerId - kUSB_ControllerKhci0) >= (uint8_t)USB_DEVICE_CONFIG_KHCI) ||
997         ((controllerId - kUSB_ControllerKhci0) >= (sizeof(khci_base) / sizeof(uint32_t))))
998     {
999         return kStatus_USB_ControllerNotFound;
1000     }
1001     khciState = &s_UsbDeviceKhciState[controllerId - kUSB_ControllerKhci0];
1002
1003     khciState->controllerId = controllerId;
1004
1005     khciState->registerBase = (USB_Type *)khci_base[controllerId - kUSB_ControllerKhci0];
1006
1007     khciState->dmaAlignBuffer = (uint8_t *)&s_UsbDeviceKhciDmaAlignBuffer[controllerId - kUSB_ControllerKhci0][0];
1008
1009     /* Clear all interrupt flags. */
1010     khciState->registerBase->ISTAT = 0xFFU;
1011
1012 #if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
1013     khciState->otgStatus = 0U;
1014 #else
1015     /* Disable the device functionality. */
1016     USB_DeviceKhciControl(khciState, kUSB_DeviceControlStop, NULL);
1017 #endif
1018
1019     khciState->bdt = s_UsbDeviceKhciBdtBuffer[controllerId - kUSB_ControllerKhci0];
1020
1021     /* Set BDT buffer address */
1022     khciState->registerBase->BDTPAGE1 = (uint8_t)((((uint32_t)khciState->bdt) >> 8U) & 0xFFU);
1023     khciState->registerBase->BDTPAGE2 = (uint8_t)((((uint32_t)khciState->bdt) >> 16U) & 0xFFU);
1024     khciState->registerBase->BDTPAGE3 = (uint8_t)((((uint32_t)khciState->bdt) >> 24U) & 0xFFU);
1025
1026 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) && \
1027     (defined(FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED) && (FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED > 0U))
1028     khciState->registerBase->MISCCTRL |= USB_MISCCTRL_VREDG_EN_MASK | USB_MISCCTRL_VFEDG_EN_MASK;
1029 #endif
1030
1031 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
1032     defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) &&             \
1033     defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
1034     khciState->registerBase->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK;
1035     khciState->registerBase->KEEP_ALIVE_CTRL =
1036         USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_EN_MASK | USB_KEEP_ALIVE_CTRL_OWN_OVERRD_EN_MASK |
1037         USB_KEEP_ALIVE_CTRL_WAKE_INT_EN_MASK | FSL_FEATURE_USB_KHCI_KEEP_ALIVE_MODE_CONTROL;
1038     /* wake on out and setup transaction */
1039     khciState->registerBase->KEEP_ALIVE_WKCTRL = 0x1U;
1040 #if defined(FSL_FEATURE_SOC_MCGLITE_COUNT) && (FSL_FEATURE_SOC_MCGLITE_COUNT > 0U)
1041     MCG->MC |= MCG_MC_HIRCLPEN_MASK;
1042 #endif
1043
1044 #endif
1045 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_LOW) && (FSL_FEATURE_USB_KHCI_HAS_STALL_LOW > 0U)
1046     khciState->registerBase->MISCCTRL |= USB_MISCCTRL_STL_ADJ_EN_MASK;
1047 #endif
1048
1049     /* Set KHCI device state to default value. */
1050     USB_DeviceKhciSetDefaultState(khciState);
1051
1052     *khciHandle = khciState;
1053     khciState->deviceHandle = (usb_device_struct_t *)handle;
1054 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
1055     (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U))
1056     dcdState = &s_UsbDeviceDcdState[controllerId - kUSB_ControllerKhci0];
1057
1058     dcdState->controllerId = controllerId;
1059
1060     dcdState->dcdRegisterBase = (USBDCD_Type *)dcd_base[controllerId - kUSB_ControllerKhci0];
1061
1062     dcdState->deviceHandle = (usb_device_struct_t *)handle;
1063 #endif
1064
1065     return kStatus_USB_Success;
1066 }
1067
1068 /*!
1069  * @brief De-initialize the USB device KHCI instance.
1070  *
1071  * This function de-initizlizes the USB device KHCI module.
1072  *
1073  * @param khciHandle   Pointer of the device KHCI handle.
1074  *
1075  * @return A USB error code or kStatus_USB_Success.
1076  */
1077 usb_status_t USB_DeviceKhciDeinit(usb_device_controller_handle khciHandle)
1078 {
1079     usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
1080
1081     if (!khciHandle)
1082     {
1083         return kStatus_USB_InvalidHandle;
1084     }
1085     /* Clear all interrupt flags. */
1086     khciState->registerBase->ISTAT = 0xFFU;
1087     /* Disable all interrupts. */
1088     khciState->registerBase->INTEN &= ~(0xFFU);
1089     /* Clear device address. */
1090     khciState->registerBase->ADDR = (0U);
1091
1092     /* Clear USB_CTL register */
1093     khciState->registerBase->CTL = 0x00U;
1094     khciState->registerBase->USBCTRL |= USB_USBCTRL_PDE_MASK | USB_USBCTRL_SUSP_MASK;
1095
1096     return kStatus_USB_Success;
1097 }
1098
1099 /*!
1100  * @brief Send data through a specified endpoint.
1101  *
1102  * This function sends data through a specified endpoint.
1103  *
1104  * @param khciHandle      Pointer of the device KHCI handle.
1105  * @param endpointAddress Endpoint index.
1106  * @param buffer           The memory address to hold the data need to be sent.
1107  * @param length           The data length need to be sent.
1108  *
1109  * @return A USB error code or kStatus_USB_Success.
1110  *
1111  * @note The return value just means if the sending request is successful or not; the transfer done is notified by the
1112  * corresponding callback function.
1113  * Currently, only one transfer request can be supported for one specific endpoint.
1114  * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1115  * should implement a queue in the application level.
1116  * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1117  * callback).
1118  */
1119 usb_status_t USB_DeviceKhciSend(usb_device_controller_handle khciHandle,
1120                                 uint8_t endpointAddress,
1121                                 uint8_t *buffer,
1122                                 uint32_t length)
1123 {
1124     usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
1125     uint32_t index = ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) << 1U) | USB_IN;
1126     usb_status_t error = kStatus_USB_Error;
1127
1128     /* Save the tansfer information */
1129     if (0U == khciState->endpointState[index].stateUnion.stateBitField.transferring)
1130     {
1131         khciState->endpointState[index].transferDone = 0U;
1132         khciState->endpointState[index].transferBuffer = buffer;
1133         khciState->endpointState[index].transferLength = length;
1134         khciState->endpointState[index].stateUnion.stateBitField.dmaAlign = 1U;
1135     }
1136
1137     /* Data length needs to less than max packet size in each call. */
1138     if (length > khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize)
1139     {
1140         length = khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize;
1141     }
1142
1143     /* Send data when the device is not resetting. */
1144     if (0U == khciState->isResetting)
1145     {
1146         error = USB_DeviceKhciEndpointTransfer(khciState, endpointAddress & USB_ENDPOINT_NUMBER_MASK, USB_IN,
1147                                                (uint8_t *)((uint32_t)khciState->endpointState[index].transferBuffer +
1148                                                            (uint32_t)khciState->endpointState[index].transferDone),
1149                                                length);
1150     }
1151
1152     /* Prime a transfer to receive next setup packet if the dat length is zero in a control in endpoint. */
1153     if ((0U == khciState->endpointState[index].transferDone) && (0U == length) &&
1154         (USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK)))
1155     {
1156         USB_DeviceKhciPrimeNextSetup(khciState);
1157     }
1158     return error;
1159 }
1160
1161 /*!
1162  * @brief Receive data through a specified endpoint.
1163  *
1164  * This function Receives data through a specified endpoint.
1165  *
1166  * @param khciHandle      Pointer of the device KHCI handle.
1167  * @param endpointAddress Endpoint index.
1168  * @param buffer           The memory address to save the received data.
1169  * @param length           The data length want to be received.
1170  *
1171  * @return A USB error code or kStatus_USB_Success.
1172  *
1173  * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the
1174  * corresponding callback function.
1175  * Currently, only one transfer request can be supported for one specific endpoint.
1176  * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1177  * should implement a queue in the application level.
1178  * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1179  * callback).
1180  */
1181 usb_status_t USB_DeviceKhciRecv(usb_device_controller_handle khciHandle,
1182                                 uint8_t endpointAddress,
1183                                 uint8_t *buffer,
1184                                 uint32_t length)
1185 {
1186     usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
1187     uint32_t index = ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) << 1U) | USB_OUT;
1188     usb_status_t error = kStatus_USB_Error;
1189
1190     if ((0U == length) && (USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK)))
1191     {
1192         khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
1193         USB_DeviceKhciPrimeNextSetup(khciState);
1194     }
1195     else
1196     {
1197         /* Save the tansfer information */
1198         if (0U == khciState->endpointState[index].stateUnion.stateBitField.transferring)
1199         {
1200             khciState->endpointState[index].transferDone = 0U;
1201             khciState->endpointState[index].transferBuffer = buffer;
1202             khciState->endpointState[index].transferLength = length;
1203         }
1204         khciState->endpointState[index].stateUnion.stateBitField.dmaAlign = 1U;
1205
1206         /* Data length needs to less than max packet size in each call. */
1207         if (length > khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize)
1208         {
1209             length = khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize;
1210         }
1211
1212         buffer = (uint8_t *)((uint32_t)buffer + (uint32_t)khciState->endpointState[index].transferDone);
1213
1214         if ((khciState->dmaAlignBuffer) && (0U == khciState->isDmaAlignBufferInusing) &&
1215             (USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH >= length) &&
1216             ((length & 0x03U) || (((uint32_t)buffer) & 0x03U)))
1217         {
1218             khciState->endpointState[index].stateUnion.stateBitField.dmaAlign = 0U;
1219             buffer = khciState->dmaAlignBuffer;
1220             khciState->isDmaAlignBufferInusing = 1U;
1221         }
1222
1223         /* Receive data when the device is not resetting. */
1224         if (0U == khciState->isResetting)
1225         {
1226             error = USB_DeviceKhciEndpointTransfer(khciState, endpointAddress & USB_ENDPOINT_NUMBER_MASK, USB_OUT,
1227                                                    buffer, length);
1228         }
1229     }
1230     return error;
1231 }
1232
1233 /*!
1234  * @brief Cancel the pending transfer in a specified endpoint.
1235  *
1236  * The function is used to cancel the pending transfer in a specified endpoint.
1237  *
1238  * @param khciHandle      Pointer of the device KHCI handle.
1239  * @param ep               Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1240  *
1241  * @return A USB error code or kStatus_USB_Success.
1242  */
1243 usb_status_t USB_DeviceKhciCancel(usb_device_controller_handle khciHandle, uint8_t ep)
1244 {
1245     usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
1246     usb_device_callback_message_struct_t message;
1247     uint8_t index = ((ep & USB_ENDPOINT_NUMBER_MASK) << 1U) | ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1248                                                                USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
1249
1250     /* Cancel the transfer and notify the up layer when the endpoint is busy. */
1251     if (khciState->endpointState[index].stateUnion.stateBitField.transferring)
1252     {
1253         message.length = USB_UNINITIALIZED_VAL_32;
1254         message.buffer = khciState->endpointState[index].transferBuffer;
1255         message.code = ep;
1256         message.isSetup = 0U;
1257         khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
1258         USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
1259     }
1260     return kStatus_USB_Success;
1261 }
1262
1263 /*!
1264  * @brief Control the status of the selected item.
1265  *
1266  * The function is used to control the status of the selected item.
1267  *
1268  * @param khciHandle      Pointer of the device KHCI handle.
1269  * @param type             The selected item. Please refer to enumeration type usb_device_control_type_t.
1270  * @param param            The param type is determined by the selected item.
1271  *
1272  * @return A USB error code or kStatus_USB_Success.
1273  */
1274 usb_status_t USB_DeviceKhciControl(usb_device_controller_handle khciHandle, usb_device_control_type_t type, void *param)
1275 {
1276     usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
1277     uint16_t *temp16;
1278     uint8_t *temp8;
1279 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
1280     (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U))
1281     usb_device_dcd_state_struct_t *dcdState;
1282     dcdState = &s_UsbDeviceDcdState[khciState->controllerId - kUSB_ControllerKhci0];
1283     usb_device_dcd_charging_time_t *deviceDcdTimingConfig = (usb_device_dcd_charging_time_t *)param;
1284 #endif
1285 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1286     usb_device_struct_t *deviceHandle;
1287     uint64_t startTick;
1288 #endif
1289     usb_status_t error = kStatus_USB_Error;
1290
1291     if (!khciHandle)
1292     {
1293         return kStatus_USB_InvalidHandle;
1294     }
1295
1296 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1297     deviceHandle = (usb_device_struct_t *)khciState->deviceHandle;
1298 #endif
1299
1300     switch (type)
1301     {
1302         case kUSB_DeviceControlRun:
1303             khciState->registerBase->USBCTRL = 0U;
1304 #if defined(FSL_FEATURE_USB_KHCI_OTG_ENABLED) && (FSL_FEATURE_USB_KHCI_OTG_ENABLED > 0U)
1305             if (khciState->registerBase->OTGCTL & USB_OTGCTL_OTGEN_MASK)
1306             {
1307                 khciState->registerBase->OTGCTL |= USB_OTGCTL_DPHIGH_MASK;
1308             }
1309 #endif /* FSL_FEATURE_USB_KHCI_OTG_ENABLED */
1310             khciState->registerBase->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
1311             khciState->registerBase->CTL |= USB_CTL_USBENSOFEN_MASK;
1312
1313             error = kStatus_USB_Success;
1314             break;
1315         case kUSB_DeviceControlStop:
1316 #if defined(FSL_FEATURE_USB_KHCI_OTG_ENABLED) && (FSL_FEATURE_USB_KHCI_OTG_ENABLED > 0U)
1317             if (khciState->registerBase->OTGCTL & USB_OTGCTL_OTGEN_MASK)
1318             {
1319                 khciState->registerBase->OTGCTL &= ~USB_OTGCTL_DPHIGH_MASK;
1320             }
1321 #endif /* FSL_FEATURE_USB_KHCI_OTG_ENABLED */
1322             khciState->registerBase->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
1323             error = kStatus_USB_Success;
1324             break;
1325         case kUSB_DeviceControlEndpointInit:
1326             if (param)
1327             {
1328                 error = USB_DeviceKhciEndpointInit(khciState, (usb_device_endpoint_init_struct_t *)param);
1329             }
1330             break;
1331         case kUSB_DeviceControlEndpointDeinit:
1332             if (param)
1333             {
1334                 temp8 = (uint8_t *)param;
1335                 error = USB_DeviceKhciEndpointDeinit(khciState, *temp8);
1336             }
1337             break;
1338         case kUSB_DeviceControlEndpointStall:
1339             if (param)
1340             {
1341                 temp8 = (uint8_t *)param;
1342                 error = USB_DeviceKhciEndpointStall(khciState, *temp8);
1343             }
1344             break;
1345         case kUSB_DeviceControlEndpointUnstall:
1346             if (param)
1347             {
1348                 temp8 = (uint8_t *)param;
1349                 error = USB_DeviceKhciEndpointUnstall(khciState, *temp8);
1350             }
1351             break;
1352         case kUSB_DeviceControlGetDeviceStatus:
1353             if (param)
1354             {
1355                 temp16 = (uint16_t *)param;
1356                 *temp16 = (USB_DEVICE_CONFIG_SELF_POWER << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT))
1357 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1358                           | ((uint16_t)(((uint32_t)deviceHandle->remotewakeup)
1359                                         << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT)))
1360 #endif
1361                     ;
1362                 error = kStatus_USB_Success;
1363             }
1364             break;
1365         case kUSB_DeviceControlGetEndpointStatus:
1366             if (param)
1367             {
1368                 usb_device_endpoint_status_struct_t *endpointStatus = (usb_device_endpoint_status_struct_t *)param;
1369
1370                 if (((endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS)
1371                 {
1372                     endpointStatus->endpointStatus =
1373                         (uint16_t)(
1374                             khciState
1375                                 ->endpointState[(((endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK) << 1U) |
1376                                                 (((endpointStatus->endpointAddress) &
1377                                                   USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1378                                                  USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)]
1379                                 .stateUnion.stateBitField.stalled == 1U) ?
1380                             kUSB_DeviceEndpointStateStalled :
1381                             kUSB_DeviceEndpointStateIdle;
1382                     error = kStatus_USB_Success;
1383                 }
1384             }
1385             break;
1386         case kUSB_DeviceControlSetDeviceAddress:
1387             if (param)
1388             {
1389                 temp8 = (uint8_t *)param;
1390                 khciState->registerBase->ADDR = (*temp8);
1391                 error = kStatus_USB_Success;
1392             }
1393             break;
1394         case kUSB_DeviceControlGetSynchFrame:
1395             break;
1396 #if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1397 #if defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)
1398         case kUSB_DeviceControlResume:
1399             khciState->registerBase->CTL |= USB_CTL_RESUME_MASK;
1400             startTick = deviceHandle->hwTick;
1401             while ((deviceHandle->hwTick - startTick) < 10)
1402             {
1403                 __ASM("nop");
1404             }
1405             khciState->registerBase->CTL &= ~USB_CTL_RESUME_MASK;
1406             error = kStatus_USB_Success;
1407             break;
1408 #endif /* USB_DEVICE_CONFIG_REMOTE_WAKEUP */
1409         case kUSB_DeviceControlSuspend:
1410             error = kStatus_USB_Success;
1411             break;
1412 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
1413         case kUSB_DeviceControlSetDefaultStatus:
1414             for (uint8_t count = 0U; count < USB_DEVICE_CONFIG_ENDPOINTS; count++)
1415             {
1416                 USB_DeviceKhciEndpointDeinit(khciState, (count | (USB_IN << 0x07U)));
1417                 USB_DeviceKhciEndpointDeinit(khciState, (count | (USB_OUT << 0x07U)));
1418             }
1419             USB_DeviceKhciSetDefaultState(khciState);
1420             error = kStatus_USB_Success;
1421             break;
1422         case kUSB_DeviceControlGetSpeed:
1423             if (param)
1424             {
1425                 temp8 = (uint8_t *)param;
1426                 *temp8 = USB_SPEED_FULL;
1427                 error = kStatus_USB_Success;
1428             }
1429             break;
1430 #if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
1431         case kUSB_DeviceControlGetOtgStatus:
1432             *((uint8_t *)param) = khciState->otgStatus;
1433             break;
1434         case kUSB_DeviceControlSetOtgStatus:
1435             khciState->otgStatus = *((uint8_t *)param);
1436             break;
1437 #endif
1438         case kUSB_DeviceControlSetTestMode:
1439             break;
1440 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
1441     (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U))
1442         case kUSB_DeviceControlDcdInitModule:
1443             dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK;
1444             dcdState->dcdRegisterBase->TIMER0 = USBDCD_TIMER0_TSEQ_INIT(deviceDcdTimingConfig->dcdSeqInitTime);
1445             dcdState->dcdRegisterBase->TIMER1 = USBDCD_TIMER1_TDCD_DBNC(deviceDcdTimingConfig->dcdDbncTime);
1446             dcdState->dcdRegisterBase->TIMER1 |= USBDCD_TIMER1_TVDPSRC_ON(deviceDcdTimingConfig->dcdDpSrcOnTime);
1447             dcdState->dcdRegisterBase->TIMER2_BC12 =
1448                 USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD(deviceDcdTimingConfig->dcdTimeWaitAfterPrD);
1449             dcdState->dcdRegisterBase->TIMER2_BC12 |=
1450                 USBDCD_TIMER2_BC12_TVDMSRC_ON(deviceDcdTimingConfig->dcdTimeDMSrcOn);
1451             dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_IE_MASK;
1452             dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_BC12_MASK;
1453             dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_START_MASK;
1454             break;
1455         case kUSB_DeviceControlDcdDeinitModule:
1456             dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK;
1457             break;
1458 #endif
1459
1460         default:
1461             break;
1462     }
1463
1464     return error;
1465 }
1466
1467 /*!
1468  * @brief Handle the KHCI device interrupt.
1469  *
1470  * The function is used to handle the KHCI device interrupt.
1471  *
1472  * @param deviceHandle    The device handle got from USB_DeviceInit.
1473  *
1474  */
1475 void USB_DeviceKhciIsrFunction(void *deviceHandle)
1476 {
1477     usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
1478     usb_device_khci_state_struct_t *khciState;
1479     uint8_t status;
1480
1481     if (NULL == deviceHandle)
1482     {
1483         return;
1484     }
1485
1486     khciState = (usb_device_khci_state_struct_t *)(handle->controllerHandle);
1487
1488     status = khciState->registerBase->ISTAT;
1489 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
1490     defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) &&             \
1491     defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
1492     /* Clear EEP_ALIVE_CTRL_WAKE_INT interrupt state */
1493     if (khciState->registerBase->KEEP_ALIVE_CTRL & USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_MASK)
1494     {
1495         khciState->registerBase->KEEP_ALIVE_CTRL |= USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_MASK;
1496     }
1497     /* Clear SOFTOK interrupt state */
1498     if (khciState->registerBase->ISTAT & USB_ISTAT_SOFTOK_MASK)
1499     {
1500         khciState->registerBase->ISTAT = USB_ISTAT_SOFTOK_MASK;
1501     }
1502 #endif
1503 #if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)
1504     /* Error interrupt */
1505     if (status & kUSB_KhciInterruptError)
1506     {
1507         USB_DeviceKhciInterruptError(khciState);
1508     }
1509 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
1510     /* Token done interrupt */
1511     if (status & kUSB_KhciInterruptTokenDone)
1512     {
1513         USB_DeviceKhciInterruptTokenDone(khciState);
1514     }
1515
1516     /* Reset interrupt */
1517     if (status & kUSB_KhciInterruptReset)
1518     {
1519         USB_DeviceKhciInterruptReset(khciState);
1520     }
1521
1522 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1523     /* Suspend interrupt */
1524     if (status & kUSB_KhciInterruptSleep)
1525     {
1526         USB_DeviceKhciInterruptSleep(khciState);
1527     }
1528
1529     /* Resume interrupt */
1530     if (status & kUSB_KhciInterruptResume)
1531     {
1532         USB_DeviceKhciInterruptResume(khciState);
1533     }
1534
1535     if (khciState->registerBase->USBTRC0 & USB_USBTRC0_USB_RESUME_INT_MASK)
1536     {
1537         USB_DeviceKhciInterruptResume(khciState);
1538     }
1539 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
1540
1541     /* Endpoint stalled interrupt */
1542     if (status & kUSB_KhciInterruptStall)
1543     {
1544         USB_DeviceKhciInterruptStall(khciState);
1545     }
1546
1547 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) && \
1548     (defined(FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED) && (FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED > 0U))
1549     if (khciState->registerBase->USBTRC0 & USB_USBTRC0_VREDG_DET_MASK)
1550     {
1551         USB_DeviceKhciInterruptVbusRising(khciState);
1552     }
1553
1554     if (khciState->registerBase->USBTRC0 & USB_USBTRC0_VFEDG_DET_MASK)
1555     {
1556         USB_DeviceKhciInterruptVbusFalling(khciState);
1557     }
1558 #endif /* USB_DEVICE_CONFIG_DETACH_ENABLE && FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED */
1559
1560 #if 0U
1561     /* Sof token interrupt */
1562     if (status & kUSB_KhciInterruptSofToken)
1563     {
1564         USB_DeviceKhciInterruptSof(khciState);
1565     }
1566 #endif
1567
1568 #if ((defined FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && \
1569      (FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED > 0U))
1570     status = khciState->registerBase->CLK_RECOVER_INT_STATUS;
1571     if (status)
1572     {
1573         /* USB RECOVER interrupt is happenned */
1574         if (USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_MASK & status)
1575         {
1576             /* Indicates that the USB clock recovery algorithm has detected that the frequency trim adjustment needed
1577              * for the IRC48M output clock is outside the available TRIM_FINE adjustment range for the IRC48M
1578              * module.
1579              */
1580         }
1581         khciState->registerBase->CLK_RECOVER_INT_STATUS = status;
1582     }
1583 #endif
1584 }
1585
1586 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
1587     (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U))
1588 /*!
1589  * @brief Handle the device DCD module interrupt.
1590  *
1591  * The function is used to handle the device DCD module interrupt.
1592  *
1593  * @param deviceHandle    The device handle got from USB_DeviceInit.
1594  *
1595  */
1596 void USB_DeviceDcdIsrFunction(void *deviceHandle)
1597 {
1598     usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
1599     usb_device_khci_state_struct_t *khciState;
1600     usb_device_dcd_state_struct_t *dcdState;
1601     uint32_t status;
1602     uint32_t chargerType;
1603     usb_device_callback_message_struct_t message;
1604
1605     if (NULL == deviceHandle)
1606     {
1607         return;
1608     }
1609
1610     khciState = (usb_device_khci_state_struct_t *)(handle->controllerHandle);
1611
1612     dcdState = &s_UsbDeviceDcdState[khciState->controllerId - kUSB_ControllerKhci0];
1613
1614     /* Read the STATUS register in the interrupt routine. */
1615     status = dcdState->dcdRegisterBase->STATUS;
1616
1617     /* Clear the interrupt flag bit. */
1618     dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_IACK_MASK;
1619
1620     message.buffer = (uint8_t *)NULL;
1621     message.length = 0U;
1622     message.isSetup = 0U;
1623
1624     if (status & USBDCD_STATUS_ERR_MASK)
1625     {
1626         if (status & USBDCD_STATUS_TO_MASK)
1627         {
1628             dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK;
1629             message.code = kUSB_DeviceNotifyDcdTimeOut;
1630             USB_DeviceNotificationTrigger(dcdState->deviceHandle, &message);
1631         }
1632         else
1633         {
1634             dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK;
1635             message.code = kUSB_DeviceNotifyDcdUnknownPortType;
1636             USB_DeviceNotificationTrigger(dcdState->deviceHandle, &message);
1637         }
1638     }
1639     else
1640     {
1641         switch (status & USBDCD_STATUS_SEQ_STAT_MASK)
1642         {
1643             case USBDCD_STATUS_SEQ_STAT(kUSB_DcdChargingPortDetectionCompleted):
1644                 chargerType = status & USBDCD_STATUS_SEQ_RES_MASK;
1645                 if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionStandardHost))
1646                 {
1647                     dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK;
1648                     message.code = kUSB_DeviceNotifySDPDetected;
1649                     USB_DeviceNotificationTrigger(dcdState->deviceHandle, &message);
1650                 }
1651                 else if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionChargingPort))
1652                 {
1653                     message.code = kUSB_DeviceNotifyChargingPortDetected;
1654                     USB_DeviceNotificationTrigger(dcdState->deviceHandle, &message);
1655                 }
1656                 break;
1657             case USBDCD_STATUS_SEQ_STAT(kUSB_DcdChargerTypeDetectionCompleted):
1658                 chargerType = status & USBDCD_STATUS_SEQ_RES_MASK;
1659                 if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionChargingPort))
1660                 {
1661                     dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK;
1662                     message.code = kUSB_DeviceNotifyChargingHostDetected;
1663                     USB_DeviceNotificationTrigger(dcdState->deviceHandle, &message);
1664                 }
1665                 else if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionDedicatedCharger))
1666                 {
1667                     dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK;
1668                     message.code = kUSB_DeviceNotifyDedicatedChargerDetected;
1669                     USB_DeviceNotificationTrigger(dcdState->deviceHandle, &message);
1670                 }
1671                 break;
1672
1673             default:
1674                 break;
1675         }
1676     }
1677 }
1678 #endif
1679 #endif /* USB_DEVICE_CONFIG_KHCI */