1 /*
2  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016 - 2017,2019 - 2020 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "usb_device_config.h"
10 #include "fsl_device_registers.h"
11 #include "usb.h"
12 /* CONFIG_UDC_DRIVER is for Zephyr, it will not be defined in NXP MCUXpresso SDK */
13 #if !((defined CONFIG_UDC_DRIVER) && (CONFIG_UDC_DRIVER))
14 #include "usb_device.h"
15 #endif
16 #if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
17 
18 /* CONFIG_UDC_DRIVER is for Zephyr, it will not be defined in NXP MCUXpresso SDK */
19 #if ((defined CONFIG_UDC_DRIVER) && (CONFIG_UDC_DRIVER))
20 #include "usb_device_mcux_drv_port.h"
21 #include "usb_device_ehci.h"
22 #else
23 #include "usb_device_dci.h"
24 
25 #include "usb_device_ehci.h"
26 #endif
27 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
28 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
29 #include "usb_phy.h"
30 #endif
31 #endif
32 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
33     (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
34 #include "usb_hsdcd.h"
35 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
36     (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
37 #include "usb_phydcd.h"
38 #endif
39 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
40 #include "fsl_memory.h"
41 #endif
42 #if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
43 #include "fsl_cache.h"
44 #endif
45 
46 /*******************************************************************************
47  * Definitions
48  ******************************************************************************/
49 #if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM > 0U)
50 
51 #error The SOC does not suppoort dedicated RAM case.
52 
53 #endif
54 
55 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
56 #define USB_DEV_MEMORY_CPU_2_DMA(x) MEMORY_ConvertMemoryMapAddress((uint32_t)(x), kMEMORY_Local2DMA)
57 #define USB_DEV_MEMORY_DMA_2_CPU(x) MEMORY_ConvertMemoryMapAddress((uint32_t)(x), kMEMORY_DMA2Local)
58 #endif
59 
60 /*******************************************************************************
61  * Prototypes
62  ******************************************************************************/
63 
64 static void USB_DeviceEhciSetDefaultState(usb_device_ehci_state_struct_t *ehciState);
65 static usb_status_t USB_DeviceEhciEndpointInit(usb_device_ehci_state_struct_t *ehciState,
66                                                usb_device_endpoint_init_struct_t *epInit);
67 static usb_status_t USB_DeviceEhciEndpointDeinit(usb_device_ehci_state_struct_t *ehciState, uint8_t ep);
68 static usb_status_t USB_DeviceEhciEndpointStall(usb_device_ehci_state_struct_t *ehciState, uint8_t ep);
69 static usb_status_t USB_DeviceEhciEndpointUnstall(usb_device_ehci_state_struct_t *ehciState, uint8_t ep);
70 static void USB_DeviceEhciFillSetupBuffer(usb_device_ehci_state_struct_t *ehciState, uint8_t ep);
71 static void USB_DeviceEhciCancelControlPipe(usb_device_ehci_state_struct_t *ehciState,
72                                             uint8_t endpoint,
73                                             uint8_t direction);
74 static void USB_DeviceEhciInterruptTokenDone(usb_device_ehci_state_struct_t *ehciState);
75 static void USB_DeviceEhciInterruptPortChange(usb_device_ehci_state_struct_t *ehciState);
76 static void USB_DeviceEhciInterruptReset(usb_device_ehci_state_struct_t *ehciState);
77 #if (defined(USB_DEVICE_CONFIG_SOF_NOTIFICATIONS) && (USB_DEVICE_CONFIG_SOF_NOTIFICATIONS > 0U))
78 static void USB_DeviceEhciInterruptSOF(usb_device_ehci_state_struct_t *ehciState);
79 #endif /* USB_DEVICE_CONFIG_SOF_NOTIFICATIONS */
80 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
81 static void USB_DeviceEhciInterruptSuspend(usb_device_ehci_state_struct_t *ehciState);
82 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
83 static usb_status_t USB_DeviceEhciTransfer(usb_device_ehci_state_struct_t *ehciState,
84                                            uint8_t endpointAddress,
85                                            uint8_t *buffer,
86                                            uint32_t length);
87 static usb_status_t USB_DeviceEhciNotification(usb_device_ehci_state_struct_t *ehciState,
88                                                usb_device_callback_message_struct_t *message);
89 
90 /*******************************************************************************
91  * Variables
92  ******************************************************************************/
93 
94 /* Apply for QH buffer, 2048-byte alignment */
95 USB_RAM_ADDRESS_ALIGNMENT(2048)
96 USB_CONTROLLER_DATA static uint8_t qh_buffer[(USB_DEVICE_CONFIG_EHCI - 1) * 2048 +
97                                              2 * USB_DEVICE_CONFIG_ENDPOINTS * 2 * sizeof(usb_device_ehci_qh_struct_t)];
98 
99 /* Apply for DTD buffer, 32-byte alignment */
100 USB_RAM_ADDRESS_ALIGNMENT(32)
101 USB_CONTROLLER_DATA static usb_device_ehci_dtd_struct_t s_UsbDeviceEhciDtd[USB_DEVICE_CONFIG_EHCI]
102                                                                           [USB_DEVICE_CONFIG_EHCI_MAX_DTD];
103 
104 /* Apply for ehci device state structure */
105 static usb_device_ehci_state_struct_t g_UsbDeviceEhciState[USB_DEVICE_CONFIG_EHCI];
106 
107 /* Apply for whether the corresponding g_UsbDeviceEhciState is used or not, if used, it is set to 1, if not used, it is
108  * set to 0 */
109 static uint8_t g_UsbDeviceEhciStateStatus[USB_DEVICE_CONFIG_EHCI] = {0};
110 
111 /*******************************************************************************
112  * Code
113  ******************************************************************************/
114 /*!
115  * @brief EHCI get USB base address.
116  *
117  * This function is used to get USB base address according to EHCI controller ID.
118  *
119  * @param[in] controllerId    EHCI controller ID; See the #usb_controller_index_t.
120  * @param[in] baseArray       USB base address array.
121  * @param[in] baseCount       The number of elements of baseArray.
122  *
123  * @retval USB base address.
124  */
125 #if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) && \
126      (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))) ||          \
127     ((defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
128      (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
USB_EhciGetBase(uint8_t controllerId,uint32_t * baseArray,uint8_t baseCount)129 static void *USB_EhciGetBase(uint8_t controllerId, uint32_t *baseArray, uint8_t baseCount)
130 {
131     if (controllerId < (uint8_t)kUSB_ControllerEhci0)
132     {
133         return NULL;
134     }
135 
136     controllerId = controllerId - (uint8_t)kUSB_ControllerEhci0;
137     if (controllerId >= baseCount)
138     {
139         return NULL;
140     }
141 
142     return (void *)(uint8_t *)baseArray[controllerId];
143 }
144 #endif
145 
146 /*!
147  * @brief Set device controller state to default state.
148  *
149  * The function is used to set device controller state to default state.
150  * The function will be called when USB_DeviceEhciInit called or the control type kUSB_DeviceControlGetEndpointStatus
151  * received in USB_DeviceEhciControl.
152  *
153  * @param ehciState       Pointer of the device EHCI state structure.
154  *
155  */
USB_DeviceEhciSetDefaultState(usb_device_ehci_state_struct_t * ehciState)156 static void USB_DeviceEhciSetDefaultState(usb_device_ehci_state_struct_t *ehciState)
157 {
158     usb_device_ehci_dtd_struct_t *p;
159 
160     /* Initialize the dtd free queue */
161     ehciState->dtdFree = ehciState->dtd;
162     p                  = ehciState->dtdFree;
163     for (uint32_t i = 1U; i < USB_DEVICE_CONFIG_EHCI_MAX_DTD; i++)
164     {
165         p->nextDtdPointer = (uint32_t)&ehciState->dtd[i];
166         p                 = (usb_device_ehci_dtd_struct_t *)p->nextDtdPointer;
167     }
168     p->nextDtdPointer   = 0U;
169     ehciState->dtdCount = USB_DEVICE_CONFIG_EHCI_MAX_DTD;
170 
171     /* Not use interrupt threshold. */
172     ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_ITC_MASK;
173     ehciState->registerBase->USBCMD |= USBHS_USBCMD_ITC(0U);
174 
175     /* Disable setup lockout, please refer to "Control Endpoint Operation" section in RM. */
176     ehciState->registerBase->USBMODE |= USBHS_USBMODE_SLOM_MASK;
177 
178 /* Set the endian by using CPU's endian */
179 #if (ENDIANNESS == USB_BIG_ENDIAN)
180     ehciState->registerBase->USBMODE |= USBHS_USBMODE_ES_MASK;
181 #else
182     ehciState->registerBase->USBMODE &= ~USBHS_USBMODE_ES_MASK;
183 #endif
184     /* Initialize the QHs of endpoint. */
185     for (uint32_t i = 0U; i < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); i++)
186     {
187         ehciState->qh[i].nextDtdPointer = USB_DEVICE_ECHI_DTD_TERMINATE_MASK;
188         ehciState->qh[i].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.maxPacketSize =
189             USB_CONTROL_MAX_PACKET_SIZE;
190         ehciState->dtdHard[i]                                              = NULL;
191         ehciState->dtdTail[i]                                              = NULL;
192         ehciState->qh[i].endpointStatusUnion.endpointStatusBitmap.isOpened = 0U;
193     }
194 
195 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
196     /* Add QH buffer address to USBHS_EPLISTADDR_REG */
197     ehciState->registerBase->EPLISTADDR = (uint32_t)USB_DEV_MEMORY_CPU_2_DMA(ehciState->qh);
198 #else
199     /* Add QH buffer address to USBHS_EPLISTADDR_REG */
200     ehciState->registerBase->EPLISTADDR = (uint32_t)ehciState->qh;
201 #endif
202 
203     /* Clear device address */
204     ehciState->registerBase->DEVICEADDR = 0U;
205 
206 #if defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)
207     ehciState->registerBase->OTGSC = ehciState->registerBase->OTGSC & 0x0000FFFFU;
208     ehciState->registerBase->OTGSC |= USBHS_OTGSC_BSVIE_MASK;
209 #endif /* USB_DEVICE_CONFIG_DETACH_ENABLE */
210 
211     /* Enable USB Interrupt, USB Error Interrupt, Port Change detect Interrupt, USB-Reset Interrupt*/
212     ehciState->registerBase->USBINTR =
213         (USBHS_USBINTR_UE_MASK | USBHS_USBINTR_UEE_MASK | USBHS_USBINTR_PCE_MASK | USBHS_USBINTR_URE_MASK
214 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
215          | USBHS_USBINTR_SLE_MASK
216 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
217 #if (defined(USB_DEVICE_CONFIG_SOF_NOTIFICATIONS) && (USB_DEVICE_CONFIG_SOF_NOTIFICATIONS > 0U))
218          | USBHS_USBINTR_SRE_MASK
219 #endif /* USB_DEVICE_CONFIG_SOF_NOTIFICATIONS */
220         );
221 
222     /* Enable USB LPM L1 entry interrupt and exit interrupt */
223 #if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
224 #if ((defined(USB_DEVICE_CONFIG_LPM_L1)) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
225     ehciState->registerBase->USBINTR |= USB_USBINTR_LPM_L1_ENTRYIE_MASK;
226     ehciState->registerNcBase->LPM_CSR0 |= USBNC_LPM_CSR0_LPM_EN_MASK;
227     ehciState->registerNcBase->LPM_CSR1 |= USBNC_LPM_CSR1_LPM_DEV_RES_MASK;
228 #endif
229 #endif
230     /* Clear reset flag */
231     ehciState->isResetting = 0U;
232 }
233 
234 /*!
235  * @brief Initialize a specified endpoint.
236  *
237  * The function is used to initialize a specified endpoint.
238  *
239  * @param ehciState       Pointer of the device EHCI state structure.
240  * @param epInit          The endpoint initialization structure pointer.
241  *
242  * @return A USB error code or kStatus_USB_Success.
243  */
USB_DeviceEhciEndpointInit(usb_device_ehci_state_struct_t * ehciState,usb_device_endpoint_init_struct_t * epInit)244 static usb_status_t USB_DeviceEhciEndpointInit(usb_device_ehci_state_struct_t *ehciState,
245                                                usb_device_endpoint_init_struct_t *epInit)
246 {
247     uint32_t primeBit      = 1UL << ((epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK) +
248                                 ((epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U));
249     uint16_t maxPacketSize = epInit->maxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK;
250     uint8_t endpoint       = (epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK);
251     uint8_t direction      = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
252                         USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
253     uint8_t index        = ((uint8_t)((uint32_t)endpoint << 1U)) | direction;
254     uint8_t transferType = epInit->transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK;
255 
256     /* Cancel pending transfer of the endpoint */
257 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
258     if (kStatus_USB_Success != USB_DeviceEhciCancel(ehciState, epInit->endpointAddress))
259     {
260         return kStatus_USB_Error;
261     }
262 #else
263     (void)USB_DeviceEhciCancel(ehciState, epInit->endpointAddress);
264 #endif
265 
266     if ((0U != (ehciState->registerBase->EPPRIME & primeBit)) || (0U != (ehciState->registerBase->EPSR & primeBit)))
267     {
268         return kStatus_USB_Busy;
269     }
270 
271     /* Make the endpoint max packet size align with USB Specification 2.0. */
272     if (USB_ENDPOINT_ISOCHRONOUS == transferType)
273     {
274         if (maxPacketSize > USB_DEVICE_MAX_HS_ISO_MAX_PACKET_SIZE)
275         {
276             maxPacketSize = USB_DEVICE_MAX_HS_ISO_MAX_PACKET_SIZE;
277         }
278         ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.mult =
279             1UL + ((((uint32_t)epInit->maxPacketSize) & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK) >>
280                    USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_SHFIT);
281     }
282     else
283     {
284         ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.mult = 0U;
285     }
286 
287     /* Save the max packet size of the endpoint */
288     ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.maxPacketSize =
289         maxPacketSize;
290     ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.zlt = epInit->zlt;
291     if ((USB_CONTROL_ENDPOINT == endpoint))
292     {
293         /* Set ZLT bit. disable control endpoint automatic zlt by default,only send zlt when it is needed*/
294         ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.zlt = 1U;
295     }
296     else
297     {
298         /* Set ZLT bit. */
299         ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.zlt =
300             ((0U == epInit->zlt) ? 1U : 0U);
301     }
302 
303     /* Enable the endpoint. */
304     if ((USB_CONTROL_ENDPOINT == endpoint))
305     {
306         ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.ios = 1U;
307         ehciState->registerBase->EPCR0 |=
308             ((0U != direction) ?
309                  (USBHS_EPCR_TXE_MASK | USBHS_EPCR_TXR_MASK | ((uint32_t)transferType << USBHS_EPCR_TXT_SHIFT)) :
310                  (USBHS_EPCR_RXE_MASK | USBHS_EPCR_RXR_MASK | ((uint32_t)transferType << USBHS_EPCR_RXT_SHIFT)));
311     }
312     else
313     {
314         ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.ios = 0U;
315         ehciState->registerBase->EPCR[endpoint - 1U] |=
316             ((0U != direction) ?
317                  (USBHS_EPCR_TXE_MASK | USBHS_EPCR_TXR_MASK | ((uint32_t)transferType << USBHS_EPCR_TXT_SHIFT)) :
318                  (USBHS_EPCR_RXE_MASK | USBHS_EPCR_RXR_MASK | ((uint32_t)transferType << USBHS_EPCR_RXT_SHIFT)));
319     }
320 
321     ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.isOpened = 1U;
322     return kStatus_USB_Success;
323 }
324 
325 /*!
326  * @brief De-initialize a specified endpoint.
327  *
328  * The function is used to de-initialize a specified endpoint.
329  * Current transfer of the endpoint will be cancelled and the specified endpoint will be disabled.
330  *
331  * @param ehciState       Pointer of the device EHCI state structure.
332  * @param ep               The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
333  *
334  * @return A USB error code or kStatus_USB_Success.
335  */
USB_DeviceEhciEndpointDeinit(usb_device_ehci_state_struct_t * ehciState,uint8_t ep)336 static usb_status_t USB_DeviceEhciEndpointDeinit(usb_device_ehci_state_struct_t *ehciState, uint8_t ep)
337 {
338     uint32_t primeBit =
339         1UL << ((ep & USB_ENDPOINT_NUMBER_MASK) + ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U));
340     uint8_t endpoint = (ep & USB_ENDPOINT_NUMBER_MASK);
341     uint8_t direction =
342         (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
343     uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | direction;
344 
345     ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.isOpened = 0U;
346 
347     /* Cancel the transfer of the endpoint */
348 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
349     if (kStatus_USB_Success != USB_DeviceEhciCancel(ehciState, ep))
350     {
351         return kStatus_USB_Error;
352     }
353 #else
354     (void)USB_DeviceEhciCancel(ehciState, ep);
355 #endif
356 
357     if ((0U != (ehciState->registerBase->EPPRIME & primeBit)) || (0U != (ehciState->registerBase->EPSR & primeBit)))
358     {
359         return kStatus_USB_Busy;
360     }
361 
362     /* Clear endpoint state */
363     ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristics = 0U;
364     /* Disable the endpoint */
365     if (0U == endpoint)
366     {
367         ehciState->registerBase->EPCR0 &=
368             ~((0U != direction) ? (USBHS_EPCR_TXE_MASK | USBHS_EPCR_TXT_MASK | USBHS_EPCR_TXS_MASK) :
369                                   (USBHS_EPCR_RXE_MASK | USBHS_EPCR_RXT_MASK | USBHS_EPCR_RXS_MASK));
370     }
371     else
372     {
373         ehciState->registerBase->EPCR[endpoint - 1U] &=
374             ~((0U != direction) ? (USBHS_EPCR_TXE_MASK | USBHS_EPCR_TXT_MASK | USBHS_EPCR_TXS_MASK) :
375                                   (USBHS_EPCR_RXE_MASK | USBHS_EPCR_RXT_MASK | USBHS_EPCR_RXS_MASK));
376     }
377 
378     return kStatus_USB_Success;
379 }
380 
381 /*!
382  * @brief Stall a specified endpoint.
383  *
384  * The function is used to stall a specified endpoint.
385  * Current transfer of the endpoint will be cancelled and the specified endpoint will be stalled.
386  *
387  * @param ehciState       Pointer of the device EHCI state structure.
388  * @param ep               The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
389  *
390  * @return A USB error code or kStatus_USB_Success.
391  */
USB_DeviceEhciEndpointStall(usb_device_ehci_state_struct_t * ehciState,uint8_t ep)392 static usb_status_t USB_DeviceEhciEndpointStall(usb_device_ehci_state_struct_t *ehciState, uint8_t ep)
393 {
394     uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK;
395     uint8_t direction =
396         (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
397 
398     if (0U == endpoint)
399     {
400         /* Cancel the transfer of the endpoint */
401 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
402         if ((kStatus_USB_Success != USB_DeviceEhciCancel(ehciState, 0x00)) ||
403             (kStatus_USB_Success != USB_DeviceEhciCancel(ehciState, 0x80)))
404         {
405             return kStatus_USB_Error;
406         }
407 #else
408         (void)USB_DeviceEhciCancel(ehciState, 0x00);
409         (void)USB_DeviceEhciCancel(ehciState, 0x80);
410 #endif
411         ehciState->registerBase->EPCR0 |= (USBHS_EPCR_TXS_MASK | USBHS_EPCR_RXS_MASK);
412     }
413     else
414     {
415         /* Cancel the transfer of the endpoint */
416 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
417         if (kStatus_USB_Success != USB_DeviceEhciCancel(ehciState, ep))
418         {
419             return kStatus_USB_Error;
420         }
421 #else
422         (void)USB_DeviceEhciCancel(ehciState, ep);
423 #endif
424 
425         ehciState->registerBase->EPCR[endpoint - 1U] |= ((0U != direction) ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK);
426     }
427 
428     return kStatus_USB_Success;
429 }
430 
431 /*!
432  * @brief Un-stall a specified endpoint.
433  *
434  * The function is used to un-stall a specified endpoint.
435  * Current transfer of the endpoint will be cancelled and the specified endpoint will be un-stalled.
436  *
437  * @param ehciState       Pointer of the device EHCI state structure.
438  * @param ep               The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
439  *
440  * @return A USB error code or kStatus_USB_Success.
441  */
USB_DeviceEhciEndpointUnstall(usb_device_ehci_state_struct_t * ehciState,uint8_t ep)442 static usb_status_t USB_DeviceEhciEndpointUnstall(usb_device_ehci_state_struct_t *ehciState, uint8_t ep)
443 {
444     uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK;
445     uint8_t direction =
446         (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
447 
448     /* Clear the endpoint stall state */
449     if (0U == endpoint)
450     {
451         ehciState->registerBase->EPCR0 &= ~((0U != direction) ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK);
452     }
453     else
454     {
455         ehciState->registerBase->EPCR[endpoint - 1U] &=
456             ~((0U != direction) ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK);
457         ehciState->registerBase->EPCR[endpoint - 1U] |= ((0U != direction) ? USBHS_EPCR_TXR_MASK : USBHS_EPCR_RXR_MASK);
458     }
459     /* Cancel the transfer of the endpoint */
460 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
461     if (kStatus_USB_Success != USB_DeviceEhciCancel(ehciState, ep))
462     {
463         return kStatus_USB_Error;
464     }
465 #else
466     (void)USB_DeviceEhciCancel(ehciState, ep);
467 #endif
468 
469     return kStatus_USB_Success;
470 }
471 
472 /*!
473  * @brief Get setup packet data.
474  *
475  * The function is used to get setup packet data and copy to a backup buffer.
476  *
477  * @param ehciState       Pointer of the device EHCI state structure.
478  * @param ep               The endpoint number.
479  *
480  */
USB_DeviceEhciFillSetupBuffer(usb_device_ehci_state_struct_t * ehciState,uint8_t ep)481 static void USB_DeviceEhciFillSetupBuffer(usb_device_ehci_state_struct_t *ehciState, uint8_t ep)
482 {
483     uint8_t waitingSafelyAccess = 1U;
484     uint8_t index               = ((uint8_t)((uint32_t)ep << 1U)) | USB_OUT;
485 
486     /* Write 1U to clear corresponding bit in EPSETUPSR. */
487     ehciState->registerBase->EPSETUPSR = 1UL << ep;
488 
489     while (0U != waitingSafelyAccess)
490     {
491         /* Set the setup tripwire bit. */
492         ehciState->registerBase->USBCMD |= USBHS_USBCMD_SUTW_MASK;
493 
494         /* Copy setup packet data to backup buffer */
495         ehciState->qh[index].setupBufferBack[0] = ehciState->qh[index].setupBuffer[0];
496         ehciState->qh[index].setupBufferBack[1] = ehciState->qh[index].setupBuffer[1];
497 
498         /* Read the USBCMD[SUTW] bit. If set, jump out from the while loop; if cleared continue */
499         if (0U != (ehciState->registerBase->USBCMD & USBHS_USBCMD_SUTW_MASK))
500         {
501             waitingSafelyAccess = 0U;
502         }
503     }
504     /* Clear the setup tripwire bit */
505     ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_SUTW_MASK;
506 }
507 
508 /*!
509  * @brief Cancel the transfer of the control pipe.
510  *
511  * The function is used to cancel the transfer of the control pipe.
512  *
513  * @param ehciState       Pointer of the device EHCI state structure.
514  * @param endpoint         The endpoint number.
515  * @param direction        The direction of the endpoint.
516  *
517  */
USB_DeviceEhciCancelControlPipe(usb_device_ehci_state_struct_t * ehciState,uint8_t endpoint,uint8_t direction)518 static void USB_DeviceEhciCancelControlPipe(usb_device_ehci_state_struct_t *ehciState,
519                                             uint8_t endpoint,
520                                             uint8_t direction)
521 {
522     usb_device_ehci_dtd_struct_t *currentDtd;
523     uint32_t index    = ((uint32_t)endpoint << 1U) + (uint32_t)direction;
524     uint32_t primeBit = 1UL << (endpoint + 16U * direction);
525     usb_device_callback_message_struct_t message;
526 
527     message.buffer = NULL;
528     message.length = 0U;
529     /* Get the dtd of the control pipe */
530     currentDtd =
531         (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK);
532     while (NULL != currentDtd)
533     {
534         /* Pass the transfer buffer address */
535         if (NULL == message.buffer)
536         {
537 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
538             uint32_t bufferAddress = (uint32_t)USB_DEV_MEMORY_DMA_2_CPU(currentDtd->bufferPointerPage[0]);
539 #else
540             uint32_t bufferAddress    = currentDtd->bufferPointerPage[0];
541 #endif
542             message.buffer = (uint8_t *)((bufferAddress & USB_DEVICE_ECHI_DTD_PAGE_MASK) |
543                                          (currentDtd->reservedUnion.originalBufferInfo.originalBufferOffest));
544         }
545         /* If the dtd is active, set the message length to USB_CANCELLED_TRANSFER_LENGTH. Or set the length by using
546          * finished length. */
547         if (0U != (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE))
548         {
549             message.length = USB_CANCELLED_TRANSFER_LENGTH;
550             /* Flush the endpoint to stop a transfer. */
551             do
552             {
553                 /* Set the corresponding bit(s) in the EPFLUSH register */
554                 ehciState->registerBase->EPFLUSH |= primeBit;
555 
556                 /* Wait until all bits in the EPFLUSH register are cleared. */
557                 while (0U != (ehciState->registerBase->EPFLUSH & primeBit))
558                 {
559                 }
560                 /*
561                  * Read the EPSR register to ensure that for all endpoints
562                  * commanded to be flushed, that the corresponding bits
563                  * are now cleared.
564                  */
565             } while (0U != (ehciState->registerBase->EPSR & primeBit));
566         }
567         else
568         {
569             message.length += (currentDtd->reservedUnion.originalBufferInfo.originalBufferLength -
570                                currentDtd->dtdTokenUnion.dtdTokenBitmap.totalBytes);
571         }
572         /* Clear the endpoint transfer done status */
573         ehciState->registerBase->EPCOMPLETE = primeBit;
574 
575         /* Move the dtd head pointer to next. */
576         /* If the pointer of the head equals to the tail, set the dtd queue to null. */
577         if (ehciState->dtdHard[index] == ehciState->dtdTail[index])
578         {
579             ehciState->dtdHard[index]                   = NULL;
580             ehciState->dtdTail[index]                   = NULL;
581             ehciState->qh[index].nextDtdPointer         = USB_DEVICE_ECHI_DTD_TERMINATE_MASK;
582             ehciState->qh[index].dtdTokenUnion.dtdToken = 0U;
583         }
584         else
585         {
586 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
587             ehciState->dtdHard[index] =
588                 (usb_device_ehci_dtd_struct_t *)USB_DEV_MEMORY_DMA_2_CPU(ehciState->dtdHard[index]->nextDtdPointer);
589 #else
590             ehciState->dtdHard[index] = (usb_device_ehci_dtd_struct_t *)ehciState->dtdHard[index]->nextDtdPointer;
591 #endif
592         }
593 
594         /* When the ioc is set or the dtd queue is empty, the up layer will be notified. */
595         if ((0U != currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc) ||
596             (0U == ((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK)))
597         {
598             message.code    = endpoint | (uint8_t)((uint32_t)direction << 0x07U);
599             message.isSetup = 0U;
600             (void)USB_DeviceEhciNotification(ehciState, &message);
601             message.buffer = NULL;
602             message.length = 0U;
603         }
604 
605         /* Clear the token field of the dtd. */
606         currentDtd->dtdTokenUnion.dtdToken = 0U;
607         /* Add the dtd to the free dtd queue. */
608         currentDtd->nextDtdPointer = (uint32_t)ehciState->dtdFree;
609         ehciState->dtdFree         = currentDtd;
610         ehciState->dtdCount++;
611 
612         /* Get the next in-used dtd. */
613         currentDtd =
614             (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK);
615     }
616 }
617 
618 /*!
619  * @brief Handle the endpoint token done interrupt.
620  *
621  * The function is used to handle the endpoint token done interrupt.
622  *
623  * @param ehciState       Pointer of the device EHCI state structure.
624  *
625  */
USB_DeviceEhciInterruptTokenDone(usb_device_ehci_state_struct_t * ehciState)626 static void USB_DeviceEhciInterruptTokenDone(usb_device_ehci_state_struct_t *ehciState)
627 {
628     uint32_t status;
629     uint32_t primeBit;
630     usb_device_ehci_dtd_struct_t *currentDtd;
631     void *temp;
632     usb_device_callback_message_struct_t message;
633     uint8_t endpoint;
634     uint8_t direction;
635     uint8_t count;
636     uint8_t index;
637 
638     /* Get the EPSETUPSR to check the setup packect received in which one endpoint. */
639     status = ehciState->registerBase->EPSETUPSR;
640 
641     if (0U != status)
642     {
643         for (endpoint = 0U; endpoint < USB_DEVICE_CONFIG_ENDPOINTS; endpoint++)
644         {
645             /* Check the endpoint receive the setup packet. */
646             if (0U != (status & (1UL << endpoint)))
647             {
648                 /* Get last setup packet */
649                 temp = (void *)&ehciState->qh[(uint8_t)((uint32_t)endpoint << 1U) + USB_OUT].setupBufferBack;
650                 usb_setup_struct_t *deviceSetup = (usb_setup_struct_t *)temp;
651 
652                 /* Check the direction of the data phase. */
653                 direction = (deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_IN) >> USB_REQUEST_TYPE_DIR_SHIFT;
654                 /* Cancel the data phase transfer */
655                 USB_DeviceEhciCancelControlPipe(ehciState, endpoint, direction);
656                 /* Cancel the status phase transfer */
657                 USB_DeviceEhciCancelControlPipe(ehciState, endpoint, 1U ^ direction);
658                 message.code    = (endpoint) | (USB_OUT << 0x07U);
659                 message.buffer  = (uint8_t *)deviceSetup;
660                 message.length  = USB_SETUP_PACKET_SIZE;
661                 message.isSetup = 1U;
662                 /* Fill the setup packet to the backup buffer */
663                 USB_DeviceEhciFillSetupBuffer(ehciState, endpoint);
664                 /* Notify the up layer the EHCI status changed. */
665                 (void)USB_DeviceEhciNotification(ehciState, &message);
666             }
667         }
668     }
669     /* Read the USBHS_EPCOMPLETE_REG to get the endpoint transfer done status */
670     status = ehciState->registerBase->EPCOMPLETE;
671     /* Clear the endpoint transfer done status */
672     ehciState->registerBase->EPCOMPLETE = status;
673 
674     if (0U != status)
675     {
676         for (count = 0U; count < 32U; count++)
677         {
678             /* Check the transfer is done or not in the specified endpoint. */
679             if (0U != (status & (1UL << count)))
680             {
681                 if (count > 15U)
682                 {
683                     endpoint  = count - 16U;
684                     direction = USB_IN;
685                 }
686                 else
687                 {
688                     endpoint  = count;
689                     direction = USB_OUT;
690                 }
691                 if (endpoint >= USB_DEVICE_CONFIG_ENDPOINTS)
692                 {
693                     continue;
694                 }
695                 index          = (endpoint << 1U) + direction;
696                 message.buffer = NULL;
697                 message.length = 0U;
698                 if ((USB_CONTROL_ENDPOINT == endpoint) && (USB_IN == direction))
699                 {
700                     if (1U == ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.zlt)
701                     {
702                         if (0U ==
703                             ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.zlt)
704                         {
705                             /*disable zlt after send zlt*/
706                             ehciState->qh[index]
707                                 .capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.zlt = 1U;
708                         }
709                     }
710                 }
711                 /* Get the in-used dtd of the specified endpoint. */
712                 currentDtd = (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] &
713                                                               USB_DEVICE_ECHI_DTD_POINTER_MASK);
714                 while (NULL != currentDtd)
715                 {
716                     uint8_t isTokenDone = 0;
717                     /* Get the in-used dtd of the specified endpoint. */
718                     currentDtd = (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] &
719                                                                   USB_DEVICE_ECHI_DTD_POINTER_MASK);
720 
721                     while (NULL != currentDtd)
722                     {
723 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
724                         currentDtd = (usb_device_ehci_dtd_struct_t *)USB_DEV_MEMORY_DMA_2_CPU((uint8_t *)currentDtd);
725 #endif
726                         /* Don't handle the active dtd. */
727                         if ((0U !=
728                              (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE)) ||
729                             (0U != currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc))
730                         {
731                             if ((0U == (currentDtd->dtdTokenUnion.dtdTokenBitmap.status &
732                                         USB_DEVICE_ECHI_DTD_STATUS_ACTIVE)) &&
733                                 (0U != currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc))
734                             {
735                                 isTokenDone = 1U;
736                             }
737                             break;
738                         }
739                         currentDtd = (usb_device_ehci_dtd_struct_t *)(currentDtd->nextDtdPointer &
740                                                                       USB_DEVICE_ECHI_DTD_POINTER_MASK);
741                     }
742 
743                     if ((0U == isTokenDone) && (NULL != currentDtd))
744                     {
745                         break;
746                     }
747 
748                     /* Get the in-used dtd of the specified endpoint. */
749                     currentDtd = (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] &
750                                                                   USB_DEVICE_ECHI_DTD_POINTER_MASK);
751                     while (NULL != currentDtd)
752                     {
753 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
754                         currentDtd = (usb_device_ehci_dtd_struct_t *)USB_DEV_MEMORY_DMA_2_CPU((uint8_t *)currentDtd);
755 #endif
756                         /* Don't handle the active dtd. */
757                         if (0U != (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE))
758                         {
759                             break;
760                         }
761 
762                         /* Save the transfer buffer address */
763                         if (NULL == message.buffer)
764                         {
765                             message.buffer =
766                                 (uint8_t *)((currentDtd->bufferPointerPage[0] & USB_DEVICE_ECHI_DTD_PAGE_MASK) |
767                                             (currentDtd->reservedUnion.originalBufferInfo.originalBufferOffest));
768 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
769                             message.buffer = (uint8_t *)USB_DEV_MEMORY_DMA_2_CPU(message.buffer);
770 #endif
771                         }
772                         /* Save the transferred data length */
773                         message.length += (currentDtd->reservedUnion.originalBufferInfo.originalBufferLength -
774                                            currentDtd->dtdTokenUnion.dtdTokenBitmap.totalBytes);
775 
776                         /* Move the dtd queue head pointer to next */
777                         if (ehciState->dtdHard[index] == ehciState->dtdTail[index])
778                         {
779                             ehciState->dtdHard[index]                   = NULL;
780                             ehciState->dtdTail[index]                   = NULL;
781                             ehciState->qh[index].nextDtdPointer         = USB_DEVICE_ECHI_DTD_TERMINATE_MASK;
782                             ehciState->qh[index].dtdTokenUnion.dtdToken = 0U;
783                         }
784                         else
785                         {
786 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
787                             ehciState->dtdHard[index] = (usb_device_ehci_dtd_struct_t *)USB_DEV_MEMORY_DMA_2_CPU(
788                                 (uint8_t *)ehciState->dtdHard[index]->nextDtdPointer);
789 #else
790                             ehciState->dtdHard[index] =
791                                 (usb_device_ehci_dtd_struct_t *)ehciState->dtdHard[index]->nextDtdPointer;
792 #endif
793                         }
794 
795                         /* When the ioc is set or the dtd queue is empty, the up layer will be notified. */
796                         if ((0U != currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc) ||
797                             (0U == ((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK)))
798                         {
799                             message.code    = endpoint | (uint8_t)((uint32_t)direction << 0x07U);
800                             message.isSetup = 0U;
801                             (void)USB_DeviceEhciNotification(ehciState, &message);
802                             message.buffer = NULL;
803                             message.length = 0U;
804                         }
805                         /* Clear the token field of the dtd */
806                         currentDtd->dtdTokenUnion.dtdToken = 0U;
807                         currentDtd->nextDtdPointer         = (uint32_t)ehciState->dtdFree;
808                         ehciState->dtdFree                 = currentDtd;
809                         ehciState->dtdCount++;
810                         /* Get the next in-used dtd */
811                         currentDtd = (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] &
812                                                                       USB_DEVICE_ECHI_DTD_POINTER_MASK);
813 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
814                         currentDtd = (usb_device_ehci_dtd_struct_t *)USB_DEV_MEMORY_DMA_2_CPU((uint8_t *)currentDtd);
815 #endif
816                         if ((NULL != currentDtd) && (0U != (currentDtd->dtdTokenUnion.dtdTokenBitmap.status &
817                                                             USB_DEVICE_ECHI_DTD_STATUS_ACTIVE)))
818                         {
819                             primeBit = 1UL << (endpoint + 16U * direction);
820 
821                             /* Try to prime the next dtd. */
822                             ehciState->registerBase->EPPRIME = primeBit;
823 
824                             /* Whether the endpoint transmit/receive buffer is ready or not. If not, wait for prime bit
825                              * cleared and prime the next dtd. */
826                             if (0U == (ehciState->registerBase->EPSR & primeBit))
827                             {
828                                 /* Wait for the endpoint prime bit cleared by HW */
829                                 while (0U != (ehciState->registerBase->EPPRIME & primeBit))
830                                 {
831                                 }
832 
833                                 /* If the endpoint transmit/receive buffer is not ready */
834                                 if (0U == (ehciState->registerBase->EPSR & primeBit))
835                                 {
836 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
837                                     currentDtd =
838                                         (usb_device_ehci_dtd_struct_t *)USB_DEV_MEMORY_CPU_2_DMA((uint8_t *)currentDtd);
839 #endif
840                                     /* Prime next dtd and prime the transfer */
841                                     ehciState->qh[index].nextDtdPointer         = (uint32_t)currentDtd;
842                                     ehciState->qh[index].dtdTokenUnion.dtdToken = 0U;
843                                     ehciState->registerBase->EPPRIME            = primeBit;
844                                 }
845                             }
846                         }
847                     }
848                 }
849             }
850         }
851     }
852 }
853 
854 /*!
855  * @brief Handle the port status change interrupt.
856  *
857  * The function is used to handle the port status change interrupt.
858  *
859  * @param ehciState       Pointer of the device EHCI state structure.
860  *
861  */
USB_DeviceEhciInterruptPortChange(usb_device_ehci_state_struct_t * ehciState)862 static void USB_DeviceEhciInterruptPortChange(usb_device_ehci_state_struct_t *ehciState)
863 {
864     usb_device_callback_message_struct_t message;
865 
866     message.buffer  = (uint8_t *)NULL;
867     message.length  = 0U;
868     message.isSetup = 0U;
869 
870     /* Whether the port is doing reset. */
871     if (0U == (ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_PR_MASK))
872     {
873         /* If not, update the USB speed. */
874         if (0U != (ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_HSP_MASK))
875         {
876             ehciState->speed = USB_SPEED_HIGH;
877         }
878         else
879         {
880             ehciState->speed = USB_SPEED_FULL;
881         }
882 
883         /* If the device reset flag is non-zero, notify the up layer the device reset finished. */
884         if (0U != ehciState->isResetting)
885         {
886             message.code = (uint8_t)kUSB_DeviceNotifyBusReset;
887             (void)USB_DeviceEhciNotification(ehciState, &message);
888             ehciState->isResetting = 0U;
889         }
890     }
891 
892 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
893     if ((0U != ehciState->isSuspending) && (0U == (ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_SUSP_MASK)))
894     {
895 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
896         /* pollinng if the device exits the L1 state */
897         while (!(ehciState->registerBase->USBSTS & USB_USBSTS_LPM_L1_EXITI_MASK))
898         {
899             __NOP();
900         }
901         ehciState->registerBase->USBSTS |= USB_USBSTS_LPM_L1_EXITI_MASK;
902 #endif
903         /* Set the resume flag */
904         ehciState->isSuspending = 0U;
905 
906         message.code = (uint8_t)kUSB_DeviceNotifyResume;
907         (void)USB_DeviceEhciNotification(ehciState, &message);
908     }
909 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
910 }
911 
912 /*!
913  * @brief Handle the reset interrupt.
914  *
915  * The function is used to handle the reset interrupt.
916  *
917  * @param ehciState       Pointer of the device EHCI state structure.
918  *
919  */
USB_DeviceEhciInterruptReset(usb_device_ehci_state_struct_t * ehciState)920 static void USB_DeviceEhciInterruptReset(usb_device_ehci_state_struct_t *ehciState)
921 {
922     uint32_t status = 0U;
923 
924     /* Clear the setup flag */
925     status                             = ehciState->registerBase->EPSETUPSR;
926     ehciState->registerBase->EPSETUPSR = status;
927     /* Clear the endpoint complete flag */
928     status                              = ehciState->registerBase->EPCOMPLETE;
929     ehciState->registerBase->EPCOMPLETE = status;
930 
931     do
932     {
933         /* Flush the pending transfers */
934         ehciState->registerBase->EPFLUSH = USBHS_EPFLUSH_FERB_MASK | USBHS_EPFLUSH_FETB_MASK;
935     } while (0U != (ehciState->registerBase->EPPRIME & (USBHS_EPPRIME_PERB_MASK | USBHS_EPPRIME_PETB_MASK)));
936 
937     /* Whether is the port reset. If yes, set the isResetting flag. Or, notify the up layer. */
938     if (0U != (ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_PR_MASK))
939     {
940         ehciState->isResetting = 1U;
941     }
942     else
943     {
944         usb_device_callback_message_struct_t message;
945         message.buffer  = (uint8_t *)NULL;
946         message.code    = (uint8_t)kUSB_DeviceNotifyBusReset;
947         message.length  = 0U;
948         message.isSetup = 0U;
949         (void)USB_DeviceEhciNotification(ehciState, &message);
950     }
951 }
952 
953 #if (defined(USB_DEVICE_CONFIG_SOF_NOTIFICATIONS) && (USB_DEVICE_CONFIG_SOF_NOTIFICATIONS > 0U))
954 /*!
955  * @brief Handle Start of Frame (SOF) Interrupt.
956  *
957  * The function is used to handle the SOF interrupt.
958  *
959  * @param ehciState       Pointer of the device EHCI state structure.
960  *
961  */
USB_DeviceEhciInterruptSOF(usb_device_ehci_state_struct_t * ehciState)962 static void USB_DeviceEhciInterruptSOF(usb_device_ehci_state_struct_t *ehciState)
963 {
964     usb_device_callback_message_struct_t message;
965 
966     message.buffer  = (uint8_t *)NULL;
967     message.code    = (uint8_t)kUSB_DeviceNotifySOF;
968     message.length  = 0U;
969     message.isSetup = 0U;
970 
971     /* Notify upper layer */
972     (void)USB_DeviceEhciNotification(ehciState, &message);
973 }
974 #endif /* USB_DEVICE_CONFIG_SOF_NOTIFICATIONS */
975 
976 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
977 /*!
978  * @brief Handle the suspend interrupt.
979  *
980  * The function is used to handle the suspend interrupt.
981  *
982  * @param ehciState       Pointer of the device EHCI state structure.
983  *
984  */
USB_DeviceEhciInterruptSuspend(usb_device_ehci_state_struct_t * ehciState)985 static void USB_DeviceEhciInterruptSuspend(usb_device_ehci_state_struct_t *ehciState)
986 {
987     /* If the port is in suspend state, notify the up layer */
988     if (0U != (ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_SUSP_MASK))
989     {
990 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
991 #else
992 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
993 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
994         if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
995         {
996 #endif
997             if (0U != (ehciState->registerPhyBase->USB1_VBUS_DET_STAT & USBPHY_USB1_VBUS_DET_STAT_VBUS_VALID_3V_MASK))
998 #endif
999 #endif
1000         {
1001             usb_device_callback_message_struct_t message;
1002             message.buffer  = (uint8_t *)NULL;
1003             message.length  = 0U;
1004             message.isSetup = 0U;
1005             message.code    = (uint8_t)kUSB_DeviceNotifySuspend;
1006             (void)USB_DeviceEhciNotification(ehciState, &message);
1007         }
1008 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
1009 #else
1010 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
1011 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
1012         }
1013 #endif
1014 #endif
1015 #endif
1016     }
1017 }
1018 
1019 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
1020 static usb_status_t USB_DeviceEhciInterruptLPMSleep(usb_device_ehci_state_struct_t *ehciState)
1021 {
1022     usb_device_callback_message_struct_t message;
1023 
1024     message.buffer  = &ehciState->lpmRemoteWakeUp;
1025     message.code    = (uint8_t)kUSB_DeviceNotifyLPMSleep;
1026     message.length  = 0U;
1027     message.isSetup = 0U;
1028 
1029     /*TODO: maybe need 3us delay */
1030 
1031     ehciState->lpmRemoteWakeUp =
1032         (uint8_t)((ehciState->registerNcBase->LPM_CSR1 & USBNC_LPM_CSR1_LPM_DEV_RWKENRCVD_MASK) >>
1033                   USBNC_LPM_CSR1_LPM_DEV_RWKENRCVD_SHIFT);
1034 
1035     /* Notify up layer the USB suspend signal detected. */
1036     return USB_DeviceEhciNotification(ehciState, &message);
1037 }
1038 #endif
1039 
1040 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
1041 
1042 /*!
1043  * @brief Get dtds and link to QH.
1044  *
1045  * The function is used to get dtds and link to QH.
1046  *
1047  * @param ehciState       Pointer of the device EHCI state structure.
1048  * @param endpointAddress The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
1049  * @param buffer           The memory address needed to be transferred.
1050  * @param length           Data length.
1051  *
1052  * @return A USB error code or kStatus_USB_Success.
1053  */
1054 static usb_status_t USB_DeviceEhciTransfer(usb_device_ehci_state_struct_t *ehciState,
1055                                            uint8_t endpointAddress,
1056                                            uint8_t *buffer,
1057                                            uint32_t length)
1058 {
1059     usb_device_ehci_dtd_struct_t *dtd;
1060     usb_device_ehci_dtd_struct_t *dtdHard;
1061     uint32_t index = (((uint32_t)endpointAddress & USB_ENDPOINT_NUMBER_MASK) << 1U) |
1062                      (((uint32_t)endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1063                       USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
1064     uint32_t primeBit = 1UL << ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) +
1065                                 ((endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U));
1066     uint32_t epStatus = primeBit;
1067     uint32_t sendLength;
1068     uint32_t currentIndex       = 0U;
1069     uint32_t dtdRequestCount    = (length + USB_DEVICE_ECHI_DTD_TOTAL_BYTES - 1U) / USB_DEVICE_ECHI_DTD_TOTAL_BYTES;
1070     uint8_t qhIdle              = 0U;
1071     uint8_t waitingSafelyAccess = 1U;
1072     uint32_t primeTimesCount    = 0U;
1073     void *temp;
1074     OSA_SR_ALLOC();
1075 
1076     if (NULL == ehciState)
1077     {
1078         return kStatus_USB_InvalidHandle;
1079     }
1080 
1081     if (0U == ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.isOpened)
1082     {
1083         return kStatus_USB_Error;
1084     }
1085     /* Return error when ehci is doing reset */
1086     if (0U != ehciState->isResetting)
1087     {
1088         return kStatus_USB_Error;
1089     }
1090 
1091 #if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
1092     if (0U != length)
1093     {
1094         DCACHE_CleanByRange((uint32_t)buffer, length);
1095     }
1096 #endif
1097 
1098     if (0U == dtdRequestCount)
1099     {
1100         dtdRequestCount = 1U;
1101     }
1102 
1103     OSA_ENTER_CRITICAL();
1104     /* The free dtd count need to not less than the transfer requests. */
1105     if (dtdRequestCount > (uint32_t)ehciState->dtdCount)
1106     {
1107         OSA_EXIT_CRITICAL();
1108         return kStatus_USB_Busy;
1109     }
1110 
1111     do
1112     {
1113         /* The transfer length need to not more than USB_DEVICE_ECHI_DTD_TOTAL_BYTES for each dtd. */
1114         if (length > USB_DEVICE_ECHI_DTD_TOTAL_BYTES)
1115         {
1116             sendLength = USB_DEVICE_ECHI_DTD_TOTAL_BYTES;
1117         }
1118         else
1119         {
1120             sendLength = length;
1121         }
1122         length -= sendLength;
1123 
1124         /* Get a free dtd */
1125         dtd = ehciState->dtdFree;
1126 
1127         ehciState->dtdFree = (usb_device_ehci_dtd_struct_t *)dtd->nextDtdPointer;
1128         ehciState->dtdCount--;
1129 
1130         /* Save the dtd head when current active buffer offset is zero. */
1131         if (0U == currentIndex)
1132         {
1133             dtdHard = dtd;
1134         }
1135 
1136         /* Set the dtd field */
1137         dtd->nextDtdPointer         = USB_DEVICE_ECHI_DTD_TERMINATE_MASK;
1138         dtd->dtdTokenUnion.dtdToken = 0U;
1139 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1140         dtd->bufferPointerPage[0] = (uint32_t)USB_DEV_MEMORY_CPU_2_DMA((buffer + currentIndex));
1141 #else
1142         dtd->bufferPointerPage[0] = (uint32_t)(buffer + currentIndex);
1143 #endif
1144         dtd->bufferPointerPage[1] =
1145             (dtd->bufferPointerPage[0] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK) & USB_DEVICE_ECHI_DTD_PAGE_MASK;
1146         dtd->bufferPointerPage[2] = dtd->bufferPointerPage[1] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK;
1147         dtd->bufferPointerPage[3] = dtd->bufferPointerPage[2] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK;
1148         dtd->bufferPointerPage[4] = dtd->bufferPointerPage[3] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK;
1149 
1150         dtd->dtdTokenUnion.dtdTokenBitmap.totalBytes = sendLength;
1151 
1152         /* Save the data length needed to be transferred. */
1153         dtd->reservedUnion.originalBufferInfo.originalBufferLength = sendLength;
1154         /* Save the original buffer address */
1155 
1156         dtd->reservedUnion.originalBufferInfo.originalBufferOffest =
1157 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1158             ((uint32_t)(buffer + currentIndex)) & USB_DEVICE_ECHI_DTD_PAGE_OFFSET_MASK;
1159 #else
1160             dtd->bufferPointerPage[0] & USB_DEVICE_ECHI_DTD_PAGE_OFFSET_MASK;
1161 #endif
1162         dtd->reservedUnion.originalBufferInfo.dtdInvalid = 0U;
1163 
1164         /* Set the IOC field in last dtd. */
1165         if (0U == length)
1166         {
1167             dtd->dtdTokenUnion.dtdTokenBitmap.ioc = 1U;
1168         }
1169 
1170         /* Set dtd active */
1171         dtd->dtdTokenUnion.dtdTokenBitmap.status = USB_DEVICE_ECHI_DTD_STATUS_ACTIVE;
1172 
1173         /* Move the buffer offset index */
1174         currentIndex += sendLength;
1175 
1176         /* Add dtd to the in-used dtd queue */
1177         if (NULL != (ehciState->dtdTail[index]))
1178         {
1179 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1180             ehciState->dtdTail[index]->nextDtdPointer = (uint32_t)USB_DEV_MEMORY_CPU_2_DMA(dtd);
1181 #else
1182             ehciState->dtdTail[index]->nextDtdPointer = (uint32_t)dtd;
1183 #endif
1184             ehciState->dtdTail[index] = dtd;
1185         }
1186         else
1187         {
1188             ehciState->dtdHard[index] = dtd;
1189             ehciState->dtdTail[index] = dtd;
1190             qhIdle                    = 1U;
1191         }
1192     } while (0U != length);
1193     if ((USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
1194         (USB_IN == ((endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1195                     USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)))
1196     {
1197         uint8_t setupindex = ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) * 2U);
1198         /* Get last setup packet */
1199         temp                            = (void *)&ehciState->qh[setupindex].setupBufferBack[0];
1200         usb_setup_struct_t *deviceSetup = (usb_setup_struct_t *)temp;
1201         if (1U == ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.zlt)
1202         {
1203             if ((0U != sendLength) && (sendLength < deviceSetup->wLength) &&
1204                 (0U ==
1205                  (sendLength % ehciState->qh[index]
1206                                    .capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.maxPacketSize)))
1207             {
1208                 /* enable ZLT. */
1209                 ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.zlt = 0U;
1210             }
1211         }
1212     }
1213     /* If the QH is not empty */
1214     if (0U == qhIdle)
1215     {
1216         /* If the prime bit is set, nothing need to do. */
1217         if (0U != (ehciState->registerBase->EPPRIME & primeBit))
1218         {
1219             OSA_EXIT_CRITICAL();
1220             return kStatus_USB_Success;
1221         }
1222 
1223         /* To safely a dtd */
1224         while (0U != waitingSafelyAccess)
1225         {
1226             /* set the ATDTW flag to USBHS_USBCMD_REG. */
1227             ehciState->registerBase->USBCMD |= USBHS_USBCMD_ATDTW_MASK;
1228             /* Read EPSR */
1229             epStatus = ehciState->registerBase->EPSR;
1230             /* Wait the ATDTW bit set */
1231             if (0U != (ehciState->registerBase->USBCMD & USBHS_USBCMD_ATDTW_MASK))
1232             {
1233                 waitingSafelyAccess = 0U;
1234             }
1235         }
1236         /* Clear the ATDTW bit */
1237         ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_ATDTW_MASK;
1238     }
1239 
1240     /* If QH is empty or the endpoint is not primed, need to link current dtd head to the QH. */
1241     /* When the endpoint is not primed if qhIdle is zero, it means the QH is empty. */
1242     if ((0U != qhIdle) || (0U == (epStatus & primeBit)))
1243     {
1244 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1245         ehciState->qh[index].nextDtdPointer = (uint32_t)USB_DEV_MEMORY_CPU_2_DMA(dtdHard);
1246 #else
1247         ehciState->qh[index].nextDtdPointer = (uint32_t)dtdHard;
1248 #endif
1249         ehciState->qh[index].dtdTokenUnion.dtdToken = 0U;
1250         /*make sure dtd is linked to dqh*/
1251         __DSB();
1252         ehciState->registerBase->EPPRIME = primeBit;
1253         while (0U == (ehciState->registerBase->EPSR & primeBit))
1254         {
1255             primeTimesCount++;
1256             if (primeTimesCount == USB_DEVICE_MAX_TRANSFER_PRIME_TIMES)
1257             {
1258                 OSA_EXIT_CRITICAL();
1259                 return kStatus_USB_Error;
1260             }
1261             if (0U != (ehciState->registerBase->EPCOMPLETE & primeBit))
1262             {
1263                 break;
1264             }
1265             else
1266             {
1267                 ehciState->registerBase->EPPRIME = primeBit;
1268             }
1269         }
1270     }
1271 
1272     OSA_EXIT_CRITICAL();
1273     return kStatus_USB_Success;
1274 }
1275 
1276 /*!
1277  * @brief Get a valid device EHCI state for the device EHCI instance.
1278  *
1279  * This function gets a valid device EHCI state for the USB device EHCI module specified by the controllerId.
1280  *
1281  * @param instanceIndex The instanceIndex is used for other EHCI device structure to identify their instance index.
1282  *
1283  * @return A valid EHCI state or NULL.
1284  */
1285 static void *USB_EhciGetValidEhciState(uint8_t *instanceIndex)
1286 {
1287     for (uint8_t instance = 0; instance < USB_DEVICE_CONFIG_EHCI; instance++)
1288     {
1289         if (0U == g_UsbDeviceEhciStateStatus[instance])
1290         {
1291             g_UsbDeviceEhciStateStatus[instance] = 1U;
1292             *instanceIndex                       = instance;
1293             return (void *)(&g_UsbDeviceEhciState[instance]);
1294         }
1295     }
1296     return NULL;
1297 }
1298 
1299 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1300     (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
1301 /* The device dcd callback */
1302 static usb_hsdcd_status_t USB_DeviceEhciIsrHSDCDCallback(void *handle, uint32_t event, void *param)
1303 {
1304     usb_hsdcd_status_t error = kStatus_hsdcd_Success;
1305     usb_device_callback_message_struct_t message;
1306     usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)handle;
1307 
1308     if (ehciState == NULL)
1309     {
1310         return kStatus_hsdcd_Error;
1311     }
1312 
1313     /*messsgae buffer contain event information*/
1314     message.buffer  = (uint8_t *)param;
1315     message.length  = 0U;
1316     message.isSetup = 0U;
1317     message.code    = (uint8_t)kUSB_DeviceNotifyDcdDetectFinished;
1318 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1319     if (kStatus_USB_Success != USB_DeviceEhciNotification(ehciState, &message))
1320     {
1321         return kStatus_hsdcd_Error;
1322     }
1323 #else
1324     (void)USB_DeviceEhciNotification(ehciState, &message);
1325 #endif
1326 
1327     return error;
1328 }
1329 
1330 void USB_DeviceEhciIsrHSDCDFunction(void *deviceHandle)
1331 {
1332     usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
1333     usb_device_ehci_state_struct_t *ehciState;
1334     if (NULL == deviceHandle)
1335     {
1336         return;
1337     }
1338     ehciState = (usb_device_ehci_state_struct_t *)(handle->controllerHandle);
1339     USB_HSDcdIsrFunction(ehciState->dcdHandle);
1340 }
1341 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1342     (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
1343 /* The device dcd callback */
1344 static usb_phydcd_status_t USB_DeviceEhciIsrPHYDCDCallback(void *handle, uint32_t event, void *param)
1345 {
1346     usb_phydcd_status_t error = kStatus_phydcd_Success;
1347     usb_device_callback_message_struct_t message;
1348     usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)handle;
1349 
1350     if (ehciState == NULL)
1351     {
1352         return kStatus_phydcd_Error;
1353     }
1354 
1355     /*messsgae buffer contain event information*/
1356     message.buffer  = (uint8_t *)param;
1357     message.length  = 0U;
1358     message.isSetup = 0U;
1359     message.code    = (uint8_t)kUSB_DeviceNotifyDcdDetectFinished;
1360 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1361     if (kStatus_USB_Success != USB_DeviceEhciNotification(ehciState, &message))
1362     {
1363         return kStatus_phydcd_Error;
1364     }
1365 #else
1366     (void)USB_DeviceEhciNotification(ehciState, &message);
1367 #endif
1368 
1369     return error;
1370 }
1371 #endif
1372 
1373 /*!
1374  * @brief Notify the device that the controller status changed.
1375  *
1376  * This function is used to notify the device that the controller status changed.
1377  *
1378  * @param ehciState              Pointer of the device EHCI state structure.
1379  * @param message                The device callback message handle.
1380  *
1381  * @return A USB error code or kStatus_USB_Success.
1382  */
1383 static usb_status_t USB_DeviceEhciNotification(usb_device_ehci_state_struct_t *ehciState,
1384                                                usb_device_callback_message_struct_t *message)
1385 {
1386     usb_status_t error;
1387 
1388 #if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
1389     /* If valid OUT packet, invalidate data in cache */
1390     if ((message->code < kUSB_DeviceNotifyBusReset) && (message->buffer != NULL) && (message->length != 0U) &&
1391         (message->length != USB_CANCELLED_TRANSFER_LENGTH))
1392     {
1393         DCACHE_InvalidateByRange((uint32_t)message->buffer, message->length);
1394     }
1395 #endif
1396 
1397     error = USB_DeviceNotificationTrigger(ehciState->deviceHandle, message);
1398 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1399     if (kStatus_USB_Success != error)
1400     {
1401 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
1402         usb_echo("notification error\n");
1403 #endif
1404     }
1405 #else
1406     error                = kStatus_USB_Success;
1407 #endif
1408 
1409     return error;
1410 }
1411 
1412 /*!
1413  * @brief Initialize the USB device EHCI instance.
1414  *
1415  * This function initializes the USB device EHCI module specified by the controllerId.
1416  *
1417  * @param controllerId The controller id of the USB IP. Please refer to enumeration type usb_controller_index_t.
1418  * @param handle        Pointer of the device handle, used to identify the device object is belonged to.
1419  * @param ehciHandle   It is out parameter, is used to return pointer of the device EHCI handle to the caller.
1420  *
1421  * @return A USB error code or kStatus_USB_Success.
1422  */
1423 usb_status_t USB_DeviceEhciInit(uint8_t controllerId,
1424                                 usb_device_handle handle,
1425                                 usb_device_controller_handle *ehciHandle)
1426 {
1427     usb_device_ehci_state_struct_t *ehciState = NULL;
1428 #if defined(USBHS_STACK_BASE_ADDRS)
1429     uint32_t ehci_base[] = USBHS_STACK_BASE_ADDRS;
1430 #else
1431     uint32_t ehci_base[] = USBHS_BASE_ADDRS;
1432 #endif
1433 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1434 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
1435 #if defined(USBNC_STACK_BASE_ADDRS)
1436     uint32_t usbnc_base[] = USBNC_STACK_BASE_ADDRS;
1437 #else
1438     uint32_t usbnc_base[] = USBNC_BASE_ADDRS;
1439 #endif
1440 #endif
1441 #endif
1442     uint8_t intanceIndex;
1443     void *temp;
1444 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1445     ((defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) ||    \
1446      (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U)))
1447 
1448     usb_device_callback_message_struct_t message;
1449 #endif
1450 
1451 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1452     (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
1453 #if defined(USBHSDCD_STACK_BASE_ADDRS)
1454     uint32_t hsdcd_base[] = USBHSDCD_STACK_BASE_ADDRS;
1455 #else
1456     uint32_t hsdcd_base[] = USBHSDCD_BASE_ADDRS;
1457 #endif
1458     USBHSDCD_Type *base;
1459     usb_hsdcd_config_struct_t dcdParamConfig;
1460     usb_hsdcd_status_t dcdError = kStatus_hsdcd_Success;
1461 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1462     ((defined FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
1463 
1464     uint8_t index;
1465     usb_phydcd_config_struct_t phyDcdParamConfig;
1466     usb_phydcd_status_t phyDcdError = kStatus_phydcd_Success;
1467 #endif
1468 
1469     if ((controllerId < (uint8_t)kUSB_ControllerEhci0) ||
1470         ((uint32_t)((uint32_t)controllerId - (uint32_t)kUSB_ControllerEhci0) >= (sizeof(ehci_base) / sizeof(uint32_t))))
1471     {
1472         return kStatus_USB_ControllerNotFound;
1473     }
1474 
1475     ehciState = USB_EhciGetValidEhciState(&intanceIndex);
1476     if (NULL == ehciState)
1477     {
1478         return kStatus_USB_InvalidHandle;
1479     }
1480     ehciState->dtd = s_UsbDeviceEhciDtd[intanceIndex];
1481     temp           = (void *)&qh_buffer[intanceIndex * 2048U];
1482     ehciState->qh  = (usb_device_ehci_qh_struct_t *)temp;
1483 
1484     ehciState->controllerId = controllerId;
1485 
1486     ehciState->registerBase = (USBHS_Type *)ehci_base[controllerId - (uint8_t)kUSB_ControllerEhci0];
1487 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1488 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
1489 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
1490     if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
1491 #endif
1492     {
1493         ehciState->registerPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
1494     }
1495 #endif
1496 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
1497     ehciState->registerNcBase =
1498         (USBNC_Type *)USB_EhciGetBase(controllerId, &usbnc_base[0], sizeof(usbnc_base) / sizeof(uint32_t));
1499 #endif
1500 
1501 #endif
1502     /* For eUSB, do not need to reset controller. */
1503 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
1504     if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
1505 #endif
1506     {
1507         /* Reset the controller. */
1508         ehciState->registerBase->USBCMD |= USBHS_USBCMD_RST_MASK;
1509         while (0U != (ehciState->registerBase->USBCMD & USBHS_USBCMD_RST_MASK))
1510         {
1511         }
1512     }
1513 
1514     /* Get the HW's endpoint count */
1515     ehciState->endpointCount =
1516         (uint8_t)((ehciState->registerBase->DCCPARAMS & USBHS_DCCPARAMS_DEN_MASK) >> USBHS_DCCPARAMS_DEN_SHIFT);
1517 
1518     if (ehciState->endpointCount < USB_DEVICE_CONFIG_ENDPOINTS)
1519     {
1520         return kStatus_USB_Error;
1521     }
1522     ehciState->deviceHandle = (usb_device_struct_t *)handle;
1523 
1524     /* Clear the controller mode field and set to device mode. */
1525     ehciState->registerBase->USBMODE &= ~USBHS_USBMODE_CM_MASK;
1526     ehciState->registerBase->USBMODE |= USBHS_USBMODE_CM(0x02U);
1527 
1528     /* Set the EHCI to default status. */
1529     USB_DeviceEhciSetDefaultState(ehciState);
1530     *ehciHandle = (usb_device_controller_handle)ehciState;
1531 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1532     (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
1533     base = (USBHSDCD_Type *)USB_EhciGetBase(controllerId, &hsdcd_base[0], sizeof(hsdcd_base) / sizeof(uint32_t));
1534     dcdParamConfig.dcdCallback      = USB_DeviceEhciIsrHSDCDCallback;
1535     dcdParamConfig.dcdCallbackParam = (void *)ehciState;
1536     dcdError                        = USB_HSDCD_Init(base, &dcdParamConfig, &ehciState->dcdHandle);
1537     if (kStatus_hsdcd_Success != dcdError)
1538     {
1539         return kStatus_USB_Error;
1540     }
1541 
1542     if (0U != (ehciState->registerBase->OTGSC & USBHS_OTGSC_BSV_MASK))
1543     {
1544         /* Device is connected to a host. */
1545         message.code = (uint8_t)kUSB_DeviceNotifyAttach;
1546 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1547         if ((kStatus_USB_Success != USB_DeviceEhciNotification(ehciState, &message)) ||
1548             (kStatus_hsdcd_Success != USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DeviceHSDcdRun, NULL)))
1549         {
1550             return kStatus_USB_Error;
1551         }
1552 #else
1553         (void)USB_DeviceEhciNotification(ehciState, &message);
1554         (void)USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DeviceHSDcdRun, NULL);
1555 #endif
1556     }
1557 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1558     (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
1559 
1560     index = controllerId - (uint8_t)kUSB_ControllerEhci0;
1561 
1562     phyDcdParamConfig.dcdCallback      = USB_DeviceEhciIsrPHYDCDCallback;
1563     phyDcdParamConfig.dcdCallbackParam = (void *)ehciState;
1564 
1565     phyDcdError =
1566         USB_PHYDCD_Init(index, (usb_phydcd_config_struct_t *)&phyDcdParamConfig, (void *)&ehciState->dcdHandle);
1567     if (kStatus_phydcd_Success != phyDcdError)
1568     {
1569         return kStatus_USB_Error;
1570     }
1571 
1572     if (0U != (ehciState->registerBase->OTGSC & USBHS_OTGSC_BSV_MASK))
1573     {
1574         /* Device is connected to a host. */
1575         message.code = (uint8_t)kUSB_DeviceNotifyAttach;
1576 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1577         if ((kStatus_USB_Success != USB_DeviceEhciNotification(ehciState, &message)) ||
1578             (kStatus_USB_Success != USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DevicePHYDcdRun, NULL)))
1579         {
1580             return kStatus_USB_Error;
1581         }
1582 #else
1583         (void)USB_DeviceEhciNotification(ehciState, &message);
1584         (void)USB_PHYDCD_Control(ehciState->dcdHandle, kUSB_DevicePHYDcdRun, NULL);
1585 #endif
1586     }
1587 #endif
1588 
1589     return kStatus_USB_Success;
1590 }
1591 
1592 /*!
1593  * @brief De-initialize the USB device EHCI instance.
1594  *
1595  * This function de-initializes the USB device EHCI module.
1596  *
1597  * @param ehciHandle   Pointer of the device EHCI handle.
1598  *
1599  * @return A USB error code or kStatus_USB_Success.
1600  */
1601 usb_status_t USB_DeviceEhciDeinit(usb_device_controller_handle ehciHandle)
1602 {
1603     usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)ehciHandle;
1604 
1605     if (NULL == ehciHandle)
1606     {
1607         return kStatus_USB_InvalidHandle;
1608     }
1609     for (uint8_t instance = 0; instance < USB_DEVICE_CONFIG_EHCI; instance++)
1610     {
1611         if (ehciState == &g_UsbDeviceEhciState[instance])
1612         {
1613             g_UsbDeviceEhciStateStatus[instance] = 0;
1614         }
1615     }
1616 
1617     /* Disable all interrupt. */
1618     ehciState->registerBase->USBINTR = 0U;
1619     /* Stop the device functionality. */
1620     ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_RS_MASK;
1621     /* Reset the controller. */
1622     ehciState->registerBase->USBCMD |= USBHS_USBCMD_RST_MASK;
1623 
1624 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1625     (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
1626 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1627     if (kStatus_hsdcd_Success != USB_HSDCD_Deinit(ehciState->dcdHandle))
1628     {
1629         return kStatus_USB_Error;
1630     }
1631 #else
1632     (void)USB_HSDCD_Deinit(ehciState->dcdHandle);
1633 #endif
1634 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1635     (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
1636 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1637     if (kStatus_USB_Success != USB_PHYDCD_Deinit(ehciState->dcdHandle))
1638     {
1639         return kStatus_USB_Error;
1640     }
1641 #else
1642     (void)USB_PHYDCD_Deinit(ehciState->dcdHandle);
1643 #endif
1644 #endif
1645 
1646     return kStatus_USB_Success;
1647 }
1648 
1649 /*!
1650  * @brief Send data through a specified endpoint.
1651  *
1652  * This function sends data through a specified endpoint.
1653  *
1654  * @param ehciHandle      Pointer of the device EHCI handle.
1655  * @param endpointAddress Endpoint index.
1656  * @param buffer           The memory address to hold the data need to be sent.
1657  * @param length           The data length need to be sent.
1658  *
1659  * @return A USB error code or kStatus_USB_Success.
1660  *
1661  * @note The return value just means if the sending request is successful or not; the transfer done is notified by the
1662  * corresponding callback function.
1663  * Currently, only one transfer request can be supported for one specific endpoint.
1664  * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1665  * should implement a queue in the application level.
1666  * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1667  * callback).
1668  */
1669 usb_status_t USB_DeviceEhciSend(usb_device_controller_handle ehciHandle,
1670                                 uint8_t endpointAddress,
1671                                 uint8_t *buffer,
1672                                 uint32_t length)
1673 {
1674     /* Add dtd to the QH */
1675     return USB_DeviceEhciTransfer(
1676         (usb_device_ehci_state_struct_t *)ehciHandle,
1677         (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
1678         buffer, length);
1679 }
1680 
1681 /*!
1682  * @brief Receive data through a specified endpoint.
1683  *
1684  * This function Receives data through a specified endpoint.
1685  *
1686  * @param ehciHandle      Pointer of the device EHCI handle.
1687  * @param endpointAddress Endpoint index.
1688  * @param buffer           The memory address to save the received data.
1689  * @param length           The data length want to be received.
1690  *
1691  * @return A USB error code or kStatus_USB_Success.
1692  *
1693  * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the
1694  * corresponding callback function.
1695  * Currently, only one transfer request can be supported for one specific endpoint.
1696  * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1697  * should implement a queue in the application level.
1698  * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1699  * callback).
1700  */
1701 usb_status_t USB_DeviceEhciRecv(usb_device_controller_handle ehciHandle,
1702                                 uint8_t endpointAddress,
1703                                 uint8_t *buffer,
1704                                 uint32_t length)
1705 {
1706     /* Add dtd to the QH */
1707     return USB_DeviceEhciTransfer(
1708         (usb_device_ehci_state_struct_t *)ehciHandle,
1709         (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
1710         buffer, length);
1711 }
1712 
1713 /*!
1714  * @brief Cancel the pending transfer in a specified endpoint.
1715  *
1716  * The function is used to cancel the pending transfer in a specified endpoint.
1717  *
1718  * @param ehciHandle      Pointer of the device EHCI handle.
1719  * @param ep               Endpoint address, bit7 is the direction of endpoint, 1U - IN, 0U - OUT.
1720  *
1721  * @return A USB error code or kStatus_USB_Success.
1722  */
1723 usb_status_t USB_DeviceEhciCancel(usb_device_controller_handle ehciHandle, uint8_t ep)
1724 {
1725     usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)ehciHandle;
1726     usb_device_callback_message_struct_t message;
1727     usb_device_ehci_dtd_struct_t *currentDtd;
1728     uint32_t primeBit =
1729         1UL << ((ep & USB_ENDPOINT_NUMBER_MASK) + ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U));
1730     uint8_t index =
1731         ((ep & USB_ENDPOINT_NUMBER_MASK) << 1U) | ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x07U);
1732     uint8_t flag = 0;
1733 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1734     uint32_t convert_addr = 0U;
1735 #endif
1736 
1737     OSA_SR_ALLOC();
1738 
1739     if (NULL == ehciHandle)
1740     {
1741         return kStatus_USB_InvalidHandle;
1742     }
1743 
1744     OSA_ENTER_CRITICAL();
1745 
1746     message.buffer = NULL;
1747     message.length = USB_CANCELLED_TRANSFER_LENGTH;
1748 
1749     /* Get the first dtd */
1750     currentDtd =
1751         (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK);
1752 
1753     /* In the next loop, USB_DeviceNotificationTrigger function may trigger a new transfer and the context always
1754      * keep in the critical section, so the Dtd sequence would still keep non-empty and the loop would be endless.
1755      * We set the Dtd's dtdInvalid in this while and add an if statement in the next loop so that this issue could
1756      * be fixed.
1757      */
1758     while (NULL != currentDtd)
1759     {
1760         currentDtd->reservedUnion.originalBufferInfo.dtdInvalid = 1U;
1761 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1762         currentDtd = (usb_device_ehci_dtd_struct_t *)USB_DEV_MEMORY_DMA_2_CPU(currentDtd->nextDtdPointer &
1763                                                                               USB_DEVICE_ECHI_DTD_POINTER_MASK);
1764 #else
1765         currentDtd = (usb_device_ehci_dtd_struct_t *)(currentDtd->nextDtdPointer & USB_DEVICE_ECHI_DTD_POINTER_MASK);
1766 #endif
1767     }
1768 
1769     /* Get the first dtd */
1770     currentDtd =
1771         (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK);
1772     while (NULL != currentDtd)
1773     {
1774         /* this if statement is used with  the previous while loop to avoid the endless loop */
1775         if (0U == currentDtd->reservedUnion.originalBufferInfo.dtdInvalid)
1776         {
1777             break;
1778         }
1779         else
1780         {
1781             if (0U != (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE))
1782             {
1783                 /* Flush the endpoint to stop a transfer. */
1784                 do
1785                 {
1786                     /* Set the corresponding bit(s) in the EPFLUSH register */
1787                     ehciState->registerBase->EPFLUSH |= primeBit;
1788 
1789                     /* Wait until all bits in the EPFLUSH register are cleared. */
1790                     while (0U != (ehciState->registerBase->EPFLUSH & primeBit))
1791                     {
1792                     }
1793                     /*
1794                      * Read the EPSR register to ensure that for all endpoints
1795                      * commanded to be flushed, that the corresponding bits
1796                      * are now cleared.
1797                      */
1798                 } while (0U != (ehciState->registerBase->EPSR & primeBit));
1799             }
1800 
1801             /* Save the original buffer address. */
1802             if (NULL == message.buffer)
1803             {
1804 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1805                 convert_addr   = (uint32_t)USB_DEV_MEMORY_DMA_2_CPU(currentDtd->bufferPointerPage[0]);
1806                 message.buffer = (uint8_t *)((convert_addr & USB_DEVICE_ECHI_DTD_PAGE_MASK) |
1807                                              (currentDtd->reservedUnion.originalBufferInfo.originalBufferOffest));
1808 #else
1809                 message.buffer = (uint8_t *)((currentDtd->bufferPointerPage[0] & USB_DEVICE_ECHI_DTD_PAGE_MASK) |
1810                                              (currentDtd->reservedUnion.originalBufferInfo.originalBufferOffest));
1811 #endif
1812             }
1813 
1814             /* Remove the dtd from the dtd in-used queue. */
1815             if (ehciState->dtdHard[index] == ehciState->dtdTail[index])
1816             {
1817                 ehciState->dtdHard[index] = NULL;
1818                 ehciState->dtdTail[index] = NULL;
1819             }
1820             else
1821             {
1822 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1823                 ehciState->dtdHard[index] =
1824                     (usb_device_ehci_dtd_struct_t *)USB_DEV_MEMORY_DMA_2_CPU(ehciState->dtdHard[index]->nextDtdPointer);
1825 #else
1826                 ehciState->dtdHard[index] = (usb_device_ehci_dtd_struct_t *)ehciState->dtdHard[index]->nextDtdPointer;
1827 #endif
1828             }
1829 
1830             /* When the ioc is set or the dtd queue is empty, the up layer will be notified. */
1831             if ((0U != currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc) ||
1832                 (0U == ((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK)))
1833             {
1834                 flag = 1;
1835             }
1836             /* Clear the token field. */
1837             currentDtd->dtdTokenUnion.dtdToken = 0U;
1838             /* Save the dtd to the free queue. */
1839             currentDtd->nextDtdPointer = (uint32_t)ehciState->dtdFree;
1840             ehciState->dtdFree         = currentDtd;
1841             ehciState->dtdCount++;
1842         }
1843         /* Get the next dtd. */
1844         currentDtd =
1845             (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK);
1846     }
1847     if (NULL == currentDtd)
1848     {
1849         /* Set the QH to empty. */
1850         ehciState->qh[index].nextDtdPointer         = USB_DEVICE_ECHI_DTD_TERMINATE_MASK;
1851         ehciState->qh[index].dtdTokenUnion.dtdToken = 0U;
1852     }
1853     OSA_EXIT_CRITICAL();
1854 
1855     if (0U != flag)
1856     {
1857         message.code    = ep;
1858         message.isSetup = 0U;
1859 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1860         if (kStatus_USB_Success != USB_DeviceEhciNotification(ehciState, &message))
1861         {
1862             return kStatus_USB_Error;
1863         }
1864 #else
1865         (void)USB_DeviceEhciNotification(ehciState, &message);
1866 #endif
1867         message.buffer = NULL;
1868     }
1869 
1870     return kStatus_USB_Success;
1871 }
1872 
1873 /*!
1874  * @brief Control the status of the selected item.
1875  *
1876  * The function is used to control the status of the selected item.
1877  *
1878  * @param ehciHandle      Pointer of the device EHCI handle.
1879  * @param type             The selected item. Please refer to enumeration type usb_device_control_type_t.
1880  * @param param            The param type is determined by the selected item.
1881  *
1882  * @return A USB error code or kStatus_USB_Success.
1883  */
1884 usb_status_t USB_DeviceEhciControl(usb_device_controller_handle ehciHandle, usb_device_control_type_t type, void *param)
1885 {
1886     usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)ehciHandle;
1887     usb_status_t error                        = kStatus_USB_Error;
1888 #if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
1889     uint32_t *temp32;
1890 #endif
1891     uint16_t *temp16;
1892     uint8_t *temp8;
1893 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1894     OSA_SR_ALLOC();
1895 #endif
1896 
1897 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1898     usb_device_struct_t *deviceHandle;
1899 #endif
1900 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1901 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1902     uint64_t startTick;
1903 #endif
1904 #endif
1905 
1906     if (NULL == ehciHandle)
1907     {
1908         return kStatus_USB_InvalidHandle;
1909     }
1910 
1911 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1912     deviceHandle = (usb_device_struct_t *)ehciState->deviceHandle;
1913 #endif
1914 
1915     switch (type)
1916     {
1917         case kUSB_DeviceControlRun:
1918             ehciState->registerBase->USBCMD |= USBHS_USBCMD_RS_MASK;
1919             error = kStatus_USB_Success;
1920             break;
1921         case kUSB_DeviceControlStop:
1922             ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_RS_MASK;
1923             error = kStatus_USB_Success;
1924             break;
1925         case kUSB_DeviceControlEndpointInit:
1926             if (NULL != param)
1927             {
1928                 error = USB_DeviceEhciEndpointInit(ehciState, (usb_device_endpoint_init_struct_t *)param);
1929             }
1930             break;
1931         case kUSB_DeviceControlEndpointDeinit:
1932             if (NULL != param)
1933             {
1934                 temp8 = (uint8_t *)param;
1935                 error = USB_DeviceEhciEndpointDeinit(ehciState, *temp8);
1936             }
1937             break;
1938         case kUSB_DeviceControlEndpointStall:
1939             if (NULL != param)
1940             {
1941                 temp8 = (uint8_t *)param;
1942                 error = USB_DeviceEhciEndpointStall(ehciState, *temp8);
1943             }
1944             break;
1945         case kUSB_DeviceControlEndpointUnstall:
1946             if (NULL != param)
1947             {
1948                 temp8 = (uint8_t *)param;
1949                 error = USB_DeviceEhciEndpointUnstall(ehciState, *temp8);
1950             }
1951             break;
1952         case kUSB_DeviceControlGetDeviceStatus:
1953             if (NULL != param)
1954             {
1955                 temp16  = (uint16_t *)param;
1956                 *temp16 = ((uint16_t)USB_DEVICE_CONFIG_SELF_POWER
1957                            << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT))
1958 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1959                           | ((uint16_t)deviceHandle->remotewakeup
1960                              << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT))
1961 #endif
1962                     ;
1963                 error = kStatus_USB_Success;
1964             }
1965             break;
1966         case kUSB_DeviceControlGetEndpointStatus:
1967             if (NULL != param)
1968             {
1969                 usb_device_endpoint_status_struct_t *endpointStatus = (usb_device_endpoint_status_struct_t *)param;
1970                 uint8_t ep = (endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK;
1971                 uint8_t direction =
1972                     ((endpointStatus->endpointAddress) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1973                     USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
1974 
1975                 if (ep < USB_DEVICE_CONFIG_ENDPOINTS)
1976                 {
1977                     if (0U != ep)
1978                     {
1979                         endpointStatus->endpointStatus =
1980                             (0U != (ehciState->registerBase->EPCR[ep - 1U] &
1981                                     ((0U != direction) ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK))) ?
1982                                 (uint16_t)kUSB_DeviceEndpointStateStalled :
1983                                 (uint16_t)kUSB_DeviceEndpointStateIdle;
1984                     }
1985                     else
1986                     {
1987                         endpointStatus->endpointStatus =
1988                             (0U != (ehciState->registerBase->EPCR0 &
1989                                     ((0U != direction) ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK))) ?
1990                                 (uint16_t)kUSB_DeviceEndpointStateStalled :
1991                                 (uint16_t)kUSB_DeviceEndpointStateIdle;
1992                     }
1993                     error = kStatus_USB_Success;
1994                 }
1995             }
1996             break;
1997         case kUSB_DeviceControlPreSetDeviceAddress:
1998             if (NULL != param)
1999             {
2000                 temp8 = (uint8_t *)param;
2001                 ehciState->registerBase->DEVICEADDR =
2002                     ((((uint32_t)(*temp8)) << USBHS_DEVICEADDR_USBADR_SHIFT) | USBHS_DEVICEADDR_USBADRA_MASK);
2003                 error = kStatus_USB_Success;
2004             }
2005             break;
2006         case kUSB_DeviceControlSetDeviceAddress:
2007             error = kStatus_USB_Success;
2008             break;
2009         case kUSB_DeviceControlGetSynchFrame:
2010             break;
2011 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
2012 #if defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)
2013         case kUSB_DeviceControlResume:
2014 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
2015             ehciState->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
2016 #else
2017 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
2018 #else
2019             ehciState->registerBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK;
2020 #endif
2021 #endif
2022             ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
2023             ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK;
2024             startTick = deviceHandle->hwTick;
2025             while ((deviceHandle->hwTick - startTick) < 10U)
2026             {
2027                 __NOP();
2028             }
2029             ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_FPR_MASK;
2030             error = kStatus_USB_Success;
2031             break;
2032 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
2033         case kUSB_DeviceControlSleepResume:
2034 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
2035             ehciState->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
2036 #endif
2037             ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
2038             ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK;
2039             error = kStatus_USB_Success;
2040             break;
2041 #endif
2042 #endif /* USB_DEVICE_CONFIG_REMOTE_WAKEUP */
2043         case kUSB_DeviceControlSuspend:
2044             ehciState->registerBase->OTGSC |= 0x007F0000U;
2045             OSA_ENTER_CRITICAL();
2046 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
2047             /* ehciState->registerBase->PLL_CONTROL_1 |= USBC_PLL_CONTROL_1_PLL_SUSPEND_EN(1); */
2048 #endif
2049 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2050 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2051             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2052 #endif
2053             {
2054                 ehciState->registerPhyBase->PWD = 0xFFFFFFFFU;
2055                 /* ehciState->registerBase->OTGCTL |= ((1U<<10) | (1U<<17) | (1U<<16)); */
2056             }
2057 #endif
2058             /* ehciState->registerPhyBase->CTRL |= ((1U << 21) | (1U << 22) | (1U << 23)); */
2059             ehciState->registerBase->USBSTS |= USBHS_USBSTS_SRI_MASK;
2060 #if (defined(FSL_FEATURE_USBPHY_28FDSOI) && (FSL_FEATURE_USBPHY_28FDSOI > 0U))
2061 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2062 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2063             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2064 #endif
2065             {
2066                 ehciState->registerPhyBase->USB1_VBUS_DETECT_SET |= USBPHY_USB1_VBUS_DETECT_VBUSVALID_TO_SESSVALID_MASK;
2067             }
2068 #endif
2069 #endif
2070             ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_PHCD_MASK;
2071 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
2072 #if (defined(USBPHY_CTRL_ENVBUSCHG_WKUP_MASK))
2073 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2074 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2075             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2076 #endif
2077             {
2078                 ehciState->registerPhyBase->CTRL |= USBPHY_CTRL_ENVBUSCHG_WKUP_MASK | USBPHY_CTRL_ENIDCHG_WKUP_MASK |
2079                                                     USBPHY_CTRL_ENDPDMCHG_WKUP_MASK |
2080                                                     USBPHY_CTRL_ENIRQRESUMEDETECT_MASK;
2081             }
2082 #endif
2083 #endif
2084 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2085             ehciState->registerNcBase->USB_OTGn_CTRL |=
2086                 USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK | USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
2087 #else
2088             ehciState->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_ID_EN_MASK |
2089                                                         USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK |
2090                                                         USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
2091 #endif
2092             ehciState->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WIE_MASK;
2093 #else
2094 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
2095             PMU->WAKEUP_PM2_MASK1 |= PMU_WAKEUP_PM2_MASK1_USB(1);
2096 #else
2097             ehciState->registerBase->USBGENCTRL = USBHS_USBGENCTRL_WU_IE_MASK;
2098 #endif
2099 #endif
2100 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2101 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2102             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2103 #endif
2104             {
2105                 ehciState->registerPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK;
2106             }
2107 #endif
2108             ehciState->isSuspending = 1U;
2109             OSA_EXIT_CRITICAL();
2110             error = kStatus_USB_Success;
2111             break;
2112 
2113 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
2114         case kUSB_DeviceControlSleep:
2115             ehciState->registerBase->OTGSC |= 0x007F0000U;
2116             OSA_ENTER_CRITICAL();
2117 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2118 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2119             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2120 #endif
2121             {
2122                 ehciState->registerPhyBase->PWD = 0xFFFFFFFFU;
2123                 /* ehciState->registerBase->OTGCTL |= ((1U<<10) | (1U<<17) | (1U<<16)); */
2124             }
2125 #endif
2126             ehciState->registerBase->USBSTS |= USBHS_USBSTS_SRI_MASK;
2127 #if (defined(FSL_FEATURE_USBPHY_28FDSOI) && (FSL_FEATURE_USBPHY_28FDSOI > 0U))
2128 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2129 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2130             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2131 #endif
2132             {
2133                 ehciState->registerPhyBase->USB1_VBUS_DETECT_SET |= USBPHY_USB1_VBUS_DETECT_VBUSVALID_TO_SESSVALID_MASK;
2134             }
2135 #endif
2136 #endif
2137             /* ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_PHCD_MASK;*/
2138 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
2139 #if (defined(USBPHY_CTRL_ENVBUSCHG_WKUP_MASK))
2140 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2141 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2142             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2143 #endif
2144             {
2145                 ehciState->registerPhyBase->CTRL |= USBPHY_CTRL_ENVBUSCHG_WKUP_MASK | USBPHY_CTRL_ENIDCHG_WKUP_MASK |
2146                                                     USBPHY_CTRL_ENDPDMCHG_WKUP_MASK |
2147                                                     USBPHY_CTRL_ENIRQRESUMEDETECT_MASK;
2148             }
2149 #endif
2150 #endif
2151 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2152             ehciState->registerNcBase->USB_OTGn_CTRL |=
2153                 USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK | USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
2154 #else
2155             ehciState->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_ID_EN_MASK |
2156                                                         USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK |
2157                                                         USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
2158 #endif
2159             ehciState->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WIE_MASK;
2160 #else
2161 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
2162             PMU->WAKEUP_PM2_MASK1 |= PMU_WAKEUP_PM2_MASK1_USB(1);
2163 #else
2164             ehciState->registerBase->USBGENCTRL = USBHS_USBGENCTRL_WU_IE_MASK;
2165 #endif
2166 #endif
2167 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2168 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2169             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2170 #endif
2171             {
2172                 ehciState->registerPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK;
2173             }
2174 #endif
2175             /* TODO: wait 3us delay */
2176             ehciState->isSuspending = 1U;
2177             OSA_EXIT_CRITICAL();
2178             error = kStatus_USB_Success;
2179             break;
2180 #endif
2181 
2182 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
2183         case kUSB_DeviceControlSetDefaultStatus:
2184             for (uint8_t count = 0U; count < USB_DEVICE_CONFIG_ENDPOINTS; count++)
2185             {
2186 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
2187                 if ((kStatus_USB_Success != USB_DeviceEhciEndpointDeinit(ehciState, (count | (USB_IN << 0x07U)))) ||
2188                     (kStatus_USB_Success != USB_DeviceEhciEndpointDeinit(ehciState, (count | (USB_OUT << 0x07U)))))
2189                 {
2190                     return kStatus_USB_Error;
2191                 }
2192 #else
2193                 (void)USB_DeviceEhciEndpointDeinit(ehciState, (count | (USB_IN << 0x07U)));
2194                 (void)USB_DeviceEhciEndpointDeinit(ehciState, (count | (USB_OUT << 0x07U)));
2195 #endif
2196             }
2197             USB_DeviceEhciSetDefaultState(ehciState);
2198             error = kStatus_USB_Success;
2199             break;
2200         case kUSB_DeviceControlGetSpeed:
2201             if (NULL != param)
2202             {
2203                 temp8  = (uint8_t *)param;
2204                 *temp8 = ehciState->speed;
2205                 error  = kStatus_USB_Success;
2206             }
2207             break;
2208         case kUSB_DeviceControlGetOtgStatus:
2209             break;
2210         case kUSB_DeviceControlSetOtgStatus:
2211             break;
2212 #if (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U))
2213         case kUSB_DeviceControlSetTestMode:
2214             if (param)
2215             {
2216                 temp8 = (uint8_t *)param;
2217                 ehciState->registerBase->PORTSC1 |= ((uint32_t)(*temp8) << 16U);
2218                 error = kStatus_USB_Success;
2219             }
2220             break;
2221 #endif
2222 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
2223 
2224         case kUSB_DeviceControlUpdateHwTick:
2225             /*udpate 1ms time tick*/
2226 #if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
2227 #ifndef USBHSDCD_IRQS
2228             USB_HSDcdIsrFunction(ehciState->dcdHandle);
2229 #endif
2230 #elif (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
2231 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
2232             if (kStatus_USB_Success != USB_PHYDCD_TimerIsrFunction(ehciState->dcdHandle))
2233             {
2234                 return kStatus_USB_Error;
2235             }
2236 #else
2237             (void)USB_PHYDCD_TimerIsrFunction(ehciState->dcdHandle);
2238 #endif
2239 #endif
2240 
2241             error = kStatus_USB_Success;
2242             break;
2243         case kUSB_DeviceControlDcdEnable:
2244 
2245 #if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
2246             if (kStatus_hsdcd_Success == USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DeviceHSDcdEnable, NULL))
2247             {
2248                 error = kStatus_USB_Success;
2249             }
2250 #elif (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
2251             if (kStatus_phydcd_Success == USB_PHYDCD_Control(ehciState->dcdHandle, kUSB_DevicePHYDcdEnable, NULL))
2252             {
2253                 error = kStatus_USB_Success;
2254             }
2255 #endif
2256 
2257             break;
2258         case kUSB_DeviceControlDcdDisable:
2259 
2260 #if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
2261             if (kStatus_hsdcd_Success == USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DeviceHSDcdDisable, NULL))
2262             {
2263                 error = kStatus_USB_Success;
2264             }
2265 #elif (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
2266             if (kStatus_phydcd_Success == USB_PHYDCD_Control(ehciState->dcdHandle, kUSB_DevicePHYDcdDisable, NULL))
2267             {
2268                 error = kStatus_USB_Success;
2269             }
2270 #endif
2271 
2272             break;
2273 #endif
2274 #if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
2275         case kUSB_DeviceControlGetCurrentFrameCount:
2276             if (NULL != param)
2277             {
2278                 temp32 = (uint32_t *)param;
2279                 if (USB_SPEED_HIGH == ehciState->speed)
2280                 {
2281                     *temp32 = ehciState->registerBase->FRINDEX & (USB_DEVICE_MAX_FRAME_COUNT);
2282                 }
2283                 else /* if not high speed, change to use frame count */
2284                 {
2285                     *temp32 = (ehciState->registerBase->FRINDEX & (USB_DEVICE_MAX_FRAME_COUNT)) / 8U;
2286                 }
2287                 error = kStatus_USB_Success;
2288             }
2289             break;
2290 #endif
2291         default:
2292             /*no action*/
2293             break;
2294     }
2295 
2296     return error;
2297 }
2298 
2299 /*!
2300  * @brief Handle the EHCI device interrupt.
2301  *
2302  * The function is used to handle the EHCI device interrupt.
2303  *
2304  * @param deviceHandle    The device handle got from USB_DeviceInit.
2305  *
2306  */
2307 void USB_DeviceEhciIsrFunction(void *deviceHandle)
2308 {
2309     usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
2310     usb_device_ehci_state_struct_t *ehciState;
2311     uint32_t status;
2312 
2313     if (NULL == deviceHandle)
2314     {
2315         return;
2316     }
2317 
2318     ehciState = (usb_device_ehci_state_struct_t *)(handle->controllerHandle);
2319 
2320 #if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
2321 
2322 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
2323 
2324     if (0U != (ehciState->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIE_MASK))
2325     {
2326         if (0U != (ehciState->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIR_MASK))
2327         {
2328             ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
2329             ehciState->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
2330         }
2331     }
2332     else
2333     {
2334     }
2335 
2336 #else
2337 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
2338 #else
2339     if (0U != (ehciState->registerBase->USBGENCTRL & USBHS_USBGENCTRL_WU_IE_MASK))
2340     {
2341         if (0U != (ehciState->registerBase->USBGENCTRL & (1UL << 8)))
2342         {
2343             ehciState->registerBase->USBGENCTRL &= ~(1UL << 8);
2344             ehciState->registerBase->USBGENCTRL |= USBHS_USBGENCTRL_WU_INT_CLR_MASK;
2345             ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
2346             ehciState->registerBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK;
2347         }
2348     }
2349     else
2350     {
2351     }
2352 #endif
2353 #endif
2354 
2355 #endif
2356 
2357 #if defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)
2358     if ((ehciState->registerBase->OTGSC & USBHS_OTGSC_BSVIS_MASK) != 0U)
2359     {
2360         usb_device_callback_message_struct_t message;
2361 
2362         ehciState->registerBase->OTGSC |= USBHS_OTGSC_BSVIS_MASK;
2363 
2364         message.buffer  = (uint8_t *)NULL;
2365         message.length  = 0U;
2366         message.isSetup = 0U;
2367         if (0U != (ehciState->registerBase->OTGSC & USBHS_OTGSC_BSV_MASK))
2368         {
2369             /* Device is connected to a host. */
2370             message.code = (uint8_t)kUSB_DeviceNotifyAttach;
2371             (void)USB_DeviceEhciNotification(ehciState, &message);
2372 
2373 #if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) && \
2374     (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
2375 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
2376             if (kStatus_hsdcd_Success != USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DeviceHSDcdRun, NULL))
2377             {
2378 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
2379                 usb_echo("hsdcd run error\n");
2380 #endif
2381             }
2382 #else
2383             (void)USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DeviceHSDcdRun, NULL);
2384 #endif
2385 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
2386     (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
2387 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
2388             if (kStatus_phydcd_Error != USB_PHYDCD_Control(ehciState->dcdHandle, kUSB_DevicePHYDcdRun, NULL))
2389             {
2390 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
2391                 usb_echo("phydcd run error\n");
2392 #endif
2393             }
2394 #else
2395             (void)USB_PHYDCD_Control(ehciState->dcdHandle, kUSB_DevicePHYDcdRun, NULL);
2396 #endif
2397 #endif
2398         }
2399         else
2400         {
2401             /* Device is disconnected from a host. */
2402             message.code = (uint8_t)kUSB_DeviceNotifyDetach;
2403             (void)USB_DeviceEhciNotification(ehciState, &message);
2404         }
2405     }
2406 #endif /* USB_DEVICE_CONFIG_DETACH_ENABLE */
2407 
2408     status = ehciState->registerBase->USBSTS;
2409     status &= ehciState->registerBase->USBINTR;
2410 
2411     ehciState->registerBase->USBSTS = status;
2412 
2413 #if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)
2414     if (0U != (status & USBHS_USBSTS_UEI_MASK))
2415     {
2416         /* Error interrupt */
2417         USB_DeviceEhciInterruptError(ehciState);
2418     }
2419 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
2420 
2421     if (0U != (status & USBHS_USBSTS_URI_MASK))
2422     {
2423         /* Reset interrupt */
2424         USB_DeviceEhciInterruptReset(ehciState);
2425     }
2426 
2427     if (0U != (status & USBHS_USBSTS_UI_MASK))
2428     {
2429         /* Token done interrupt */
2430         USB_DeviceEhciInterruptTokenDone(ehciState);
2431     }
2432 
2433     if (0U != (status & USBHS_USBSTS_PCI_MASK))
2434     {
2435         /* Port status change interrupt */
2436         USB_DeviceEhciInterruptPortChange(ehciState);
2437     }
2438 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
2439     if (0U != (status & USBHS_USBSTS_SLI_MASK))
2440     {
2441         /* Suspend interrupt */
2442         USB_DeviceEhciInterruptSuspend(ehciState);
2443     }
2444 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
2445     if (0U != (status & USB_USBSTS_LPM_L1_ENTRYI_MASK))
2446     {
2447         USB_DeviceEhciInterruptLPMSleep(ehciState);
2448     }
2449 #endif
2450 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
2451 
2452 #if (defined(USB_DEVICE_CONFIG_SOF_NOTIFICATIONS) && (USB_DEVICE_CONFIG_SOF_NOTIFICATIONS > 0U))
2453     if (0U != (status & USBHS_USBSTS_SRI_MASK))
2454     {
2455         /* SOF interrupt */
2456         USB_DeviceEhciInterruptSOF(ehciState);
2457     }
2458 #endif
2459 }
2460 
2461 #endif /* USB_DEVICE_CONFIG_EHCI */
2462