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