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