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 /* CONFIG_UDC_DRIVER is for Zephyr, it will not be defined in NXP MCUXpresso SDK */
1074 #if !((defined CONFIG_UDC_DRIVER) && (CONFIG_UDC_DRIVER))
1075     void *temp;
1076 #endif
1077     OSA_SR_ALLOC();
1078 
1079     if (NULL == ehciState)
1080     {
1081         return kStatus_USB_InvalidHandle;
1082     }
1083 
1084     if (0U == ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.isOpened)
1085     {
1086         return kStatus_USB_Error;
1087     }
1088     /* Return error when ehci is doing reset */
1089     if (0U != ehciState->isResetting)
1090     {
1091         return kStatus_USB_Error;
1092     }
1093 
1094 #if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
1095     if (0U != length)
1096     {
1097         DCACHE_CleanByRange((uint32_t)buffer, length);
1098     }
1099 #endif
1100 
1101     if (0U == dtdRequestCount)
1102     {
1103         dtdRequestCount = 1U;
1104     }
1105 
1106     OSA_ENTER_CRITICAL();
1107     /* The free dtd count need to not less than the transfer requests. */
1108     if (dtdRequestCount > (uint32_t)ehciState->dtdCount)
1109     {
1110         OSA_EXIT_CRITICAL();
1111         return kStatus_USB_Busy;
1112     }
1113 
1114     do
1115     {
1116         /* The transfer length need to not more than USB_DEVICE_ECHI_DTD_TOTAL_BYTES for each dtd. */
1117         if (length > USB_DEVICE_ECHI_DTD_TOTAL_BYTES)
1118         {
1119             sendLength = USB_DEVICE_ECHI_DTD_TOTAL_BYTES;
1120         }
1121         else
1122         {
1123             sendLength = length;
1124         }
1125         length -= sendLength;
1126 
1127         /* Get a free dtd */
1128         dtd = ehciState->dtdFree;
1129 
1130         ehciState->dtdFree = (usb_device_ehci_dtd_struct_t *)dtd->nextDtdPointer;
1131         ehciState->dtdCount--;
1132 
1133         /* Save the dtd head when current active buffer offset is zero. */
1134         if (0U == currentIndex)
1135         {
1136             dtdHard = dtd;
1137         }
1138 
1139         /* Set the dtd field */
1140         dtd->nextDtdPointer         = USB_DEVICE_ECHI_DTD_TERMINATE_MASK;
1141         dtd->dtdTokenUnion.dtdToken = 0U;
1142 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1143         dtd->bufferPointerPage[0] = (uint32_t)USB_DEV_MEMORY_CPU_2_DMA((buffer + currentIndex));
1144 #else
1145         dtd->bufferPointerPage[0] = (uint32_t)(buffer + currentIndex);
1146 #endif
1147         dtd->bufferPointerPage[1] =
1148             (dtd->bufferPointerPage[0] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK) & USB_DEVICE_ECHI_DTD_PAGE_MASK;
1149         dtd->bufferPointerPage[2] = dtd->bufferPointerPage[1] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK;
1150         dtd->bufferPointerPage[3] = dtd->bufferPointerPage[2] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK;
1151         dtd->bufferPointerPage[4] = dtd->bufferPointerPage[3] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK;
1152 
1153         dtd->dtdTokenUnion.dtdTokenBitmap.totalBytes = sendLength;
1154 
1155         /* Save the data length needed to be transferred. */
1156         dtd->reservedUnion.originalBufferInfo.originalBufferLength = sendLength;
1157         /* Save the original buffer address */
1158 
1159         dtd->reservedUnion.originalBufferInfo.originalBufferOffest =
1160 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1161             ((uint32_t)(buffer + currentIndex)) & USB_DEVICE_ECHI_DTD_PAGE_OFFSET_MASK;
1162 #else
1163             dtd->bufferPointerPage[0] & USB_DEVICE_ECHI_DTD_PAGE_OFFSET_MASK;
1164 #endif
1165         dtd->reservedUnion.originalBufferInfo.dtdInvalid = 0U;
1166 
1167         /* Set the IOC field in last dtd. */
1168         if (0U == length)
1169         {
1170             dtd->dtdTokenUnion.dtdTokenBitmap.ioc = 1U;
1171         }
1172 
1173         /* Set dtd active */
1174         dtd->dtdTokenUnion.dtdTokenBitmap.status = USB_DEVICE_ECHI_DTD_STATUS_ACTIVE;
1175 
1176         /* Move the buffer offset index */
1177         currentIndex += sendLength;
1178 
1179         /* Add dtd to the in-used dtd queue */
1180         if (NULL != (ehciState->dtdTail[index]))
1181         {
1182 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1183             ehciState->dtdTail[index]->nextDtdPointer = (uint32_t)USB_DEV_MEMORY_CPU_2_DMA(dtd);
1184 #else
1185             ehciState->dtdTail[index]->nextDtdPointer = (uint32_t)dtd;
1186 #endif
1187             ehciState->dtdTail[index] = dtd;
1188         }
1189         else
1190         {
1191             ehciState->dtdHard[index] = dtd;
1192             ehciState->dtdTail[index] = dtd;
1193             qhIdle                    = 1U;
1194         }
1195     } while (0U != length);
1196 /* CONFIG_UDC_DRIVER is for Zephyr, it will not be defined in NXP MCUXpresso SDK */
1197 #if !((defined CONFIG_UDC_DRIVER) && (CONFIG_UDC_DRIVER))
1198     if ((USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK)) &&
1199         (USB_IN == ((endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1200                     USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)))
1201     {
1202         uint8_t setupindex = ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) * 2U);
1203         /* Get last setup packet */
1204         temp                            = (void *)&ehciState->qh[setupindex].setupBufferBack[0];
1205         usb_setup_struct_t *deviceSetup = (usb_setup_struct_t *)temp;
1206         if (1U == ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.zlt)
1207         {
1208             if ((0U != sendLength) && (sendLength < deviceSetup->wLength) &&
1209                 (0U ==
1210                  (sendLength % ehciState->qh[index]
1211                                    .capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.maxPacketSize)))
1212             {
1213                 /* enable ZLT. */
1214                 ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.zlt = 0U;
1215             }
1216         }
1217     }
1218 #endif
1219     /* If the QH is not empty */
1220     if (0U == qhIdle)
1221     {
1222         /* If the prime bit is set, nothing need to do. */
1223         if (0U != (ehciState->registerBase->EPPRIME & primeBit))
1224         {
1225             OSA_EXIT_CRITICAL();
1226             return kStatus_USB_Success;
1227         }
1228 
1229         /* To safely a dtd */
1230         while (0U != waitingSafelyAccess)
1231         {
1232             /* set the ATDTW flag to USBHS_USBCMD_REG. */
1233             ehciState->registerBase->USBCMD |= USBHS_USBCMD_ATDTW_MASK;
1234             /* Read EPSR */
1235             epStatus = ehciState->registerBase->EPSR;
1236             /* Wait the ATDTW bit set */
1237             if (0U != (ehciState->registerBase->USBCMD & USBHS_USBCMD_ATDTW_MASK))
1238             {
1239                 waitingSafelyAccess = 0U;
1240             }
1241         }
1242         /* Clear the ATDTW bit */
1243         ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_ATDTW_MASK;
1244     }
1245 
1246     /* If QH is empty or the endpoint is not primed, need to link current dtd head to the QH. */
1247     /* When the endpoint is not primed if qhIdle is zero, it means the QH is empty. */
1248     if ((0U != qhIdle) || (0U == (epStatus & primeBit)))
1249     {
1250 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1251         ehciState->qh[index].nextDtdPointer = (uint32_t)USB_DEV_MEMORY_CPU_2_DMA(dtdHard);
1252 #else
1253         ehciState->qh[index].nextDtdPointer = (uint32_t)dtdHard;
1254 #endif
1255         ehciState->qh[index].dtdTokenUnion.dtdToken = 0U;
1256         /*make sure dtd is linked to dqh*/
1257         __DSB();
1258         ehciState->registerBase->EPPRIME = primeBit;
1259         while (0U == (ehciState->registerBase->EPSR & primeBit))
1260         {
1261             primeTimesCount++;
1262             if (primeTimesCount == USB_DEVICE_MAX_TRANSFER_PRIME_TIMES)
1263             {
1264                 OSA_EXIT_CRITICAL();
1265                 return kStatus_USB_Error;
1266             }
1267             if (0U != (ehciState->registerBase->EPCOMPLETE & primeBit))
1268             {
1269                 break;
1270             }
1271             else
1272             {
1273                 ehciState->registerBase->EPPRIME = primeBit;
1274             }
1275         }
1276     }
1277 
1278     OSA_EXIT_CRITICAL();
1279     return kStatus_USB_Success;
1280 }
1281 
1282 /*!
1283  * @brief Get a valid device EHCI state for the device EHCI instance.
1284  *
1285  * This function gets a valid device EHCI state for the USB device EHCI module specified by the controllerId.
1286  *
1287  * @param instanceIndex The instanceIndex is used for other EHCI device structure to identify their instance index.
1288  *
1289  * @return A valid EHCI state or NULL.
1290  */
1291 static void *USB_EhciGetValidEhciState(uint8_t *instanceIndex)
1292 {
1293     for (uint8_t instance = 0; instance < USB_DEVICE_CONFIG_EHCI; instance++)
1294     {
1295         if (0U == g_UsbDeviceEhciStateStatus[instance])
1296         {
1297             g_UsbDeviceEhciStateStatus[instance] = 1U;
1298             *instanceIndex                       = instance;
1299             return (void *)(&g_UsbDeviceEhciState[instance]);
1300         }
1301     }
1302     return NULL;
1303 }
1304 
1305 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1306     (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
1307 /* The device dcd callback */
1308 static usb_hsdcd_status_t USB_DeviceEhciIsrHSDCDCallback(void *handle, uint32_t event, void *param)
1309 {
1310     usb_hsdcd_status_t error = kStatus_hsdcd_Success;
1311     usb_device_callback_message_struct_t message;
1312     usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)handle;
1313 
1314     if (ehciState == NULL)
1315     {
1316         return kStatus_hsdcd_Error;
1317     }
1318 
1319     /*messsgae buffer contain event information*/
1320     message.buffer  = (uint8_t *)param;
1321     message.length  = 0U;
1322     message.isSetup = 0U;
1323     message.code    = (uint8_t)kUSB_DeviceNotifyDcdDetectFinished;
1324 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1325     if (kStatus_USB_Success != USB_DeviceEhciNotification(ehciState, &message))
1326     {
1327         return kStatus_hsdcd_Error;
1328     }
1329 #else
1330     (void)USB_DeviceEhciNotification(ehciState, &message);
1331 #endif
1332 
1333     return error;
1334 }
1335 
1336 void USB_DeviceEhciIsrHSDCDFunction(void *deviceHandle)
1337 {
1338     usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
1339     usb_device_ehci_state_struct_t *ehciState;
1340     if (NULL == deviceHandle)
1341     {
1342         return;
1343     }
1344     ehciState = (usb_device_ehci_state_struct_t *)(handle->controllerHandle);
1345     USB_HSDcdIsrFunction(ehciState->dcdHandle);
1346 }
1347 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1348     (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
1349 /* The device dcd callback */
1350 static usb_phydcd_status_t USB_DeviceEhciIsrPHYDCDCallback(void *handle, uint32_t event, void *param)
1351 {
1352     usb_phydcd_status_t error = kStatus_phydcd_Success;
1353     usb_device_callback_message_struct_t message;
1354     usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)handle;
1355 
1356     if (ehciState == NULL)
1357     {
1358         return kStatus_phydcd_Error;
1359     }
1360 
1361     /*messsgae buffer contain event information*/
1362     message.buffer  = (uint8_t *)param;
1363     message.length  = 0U;
1364     message.isSetup = 0U;
1365     message.code    = (uint8_t)kUSB_DeviceNotifyDcdDetectFinished;
1366 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1367     if (kStatus_USB_Success != USB_DeviceEhciNotification(ehciState, &message))
1368     {
1369         return kStatus_phydcd_Error;
1370     }
1371 #else
1372     (void)USB_DeviceEhciNotification(ehciState, &message);
1373 #endif
1374 
1375     return error;
1376 }
1377 #endif
1378 
1379 /*!
1380  * @brief Notify the device that the controller status changed.
1381  *
1382  * This function is used to notify the device that the controller status changed.
1383  *
1384  * @param ehciState              Pointer of the device EHCI state structure.
1385  * @param message                The device callback message handle.
1386  *
1387  * @return A USB error code or kStatus_USB_Success.
1388  */
1389 static usb_status_t USB_DeviceEhciNotification(usb_device_ehci_state_struct_t *ehciState,
1390                                                usb_device_callback_message_struct_t *message)
1391 {
1392     usb_status_t error;
1393 
1394 #if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
1395     /* If valid OUT packet, invalidate data in cache */
1396     if ((message->code < kUSB_DeviceNotifyBusReset) && (message->buffer != NULL) && (message->length != 0U) &&
1397         (message->length != USB_CANCELLED_TRANSFER_LENGTH))
1398     {
1399         DCACHE_InvalidateByRange((uint32_t)message->buffer, message->length);
1400     }
1401 #endif
1402 
1403     error = USB_DeviceNotificationTrigger(ehciState->deviceHandle, message);
1404 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1405     if (kStatus_USB_Success != error)
1406     {
1407 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
1408         usb_echo("notification error\n");
1409 #endif
1410     }
1411 #else
1412     error                = kStatus_USB_Success;
1413 #endif
1414 
1415     return error;
1416 }
1417 
1418 /*!
1419  * @brief Initialize the USB device EHCI instance.
1420  *
1421  * This function initializes the USB device EHCI module specified by the controllerId.
1422  *
1423  * @param controllerId The controller id of the USB IP. Please refer to enumeration type usb_controller_index_t.
1424  * @param handle        Pointer of the device handle, used to identify the device object is belonged to.
1425  * @param ehciHandle   It is out parameter, is used to return pointer of the device EHCI handle to the caller.
1426  *
1427  * @return A USB error code or kStatus_USB_Success.
1428  */
1429 usb_status_t USB_DeviceEhciInit(uint8_t controllerId,
1430                                 usb_device_handle handle,
1431                                 usb_device_controller_handle *ehciHandle)
1432 {
1433     usb_device_ehci_state_struct_t *ehciState = NULL;
1434 #if defined(USBHS_STACK_BASE_ADDRS)
1435     uint32_t ehci_base[] = USBHS_STACK_BASE_ADDRS;
1436 #else
1437     uint32_t ehci_base[] = USBHS_BASE_ADDRS;
1438 #endif
1439 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1440 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
1441 #if defined(USBNC_STACK_BASE_ADDRS)
1442     uint32_t usbnc_base[] = USBNC_STACK_BASE_ADDRS;
1443 #else
1444     uint32_t usbnc_base[] = USBNC_BASE_ADDRS;
1445 #endif
1446 #endif
1447 #endif
1448     uint8_t intanceIndex;
1449     void *temp;
1450 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1451     ((defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) ||    \
1452      (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U)))
1453 
1454     usb_device_callback_message_struct_t message;
1455 #endif
1456 
1457 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1458     (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
1459 #if defined(USBHSDCD_STACK_BASE_ADDRS)
1460     uint32_t hsdcd_base[] = USBHSDCD_STACK_BASE_ADDRS;
1461 #else
1462     uint32_t hsdcd_base[] = USBHSDCD_BASE_ADDRS;
1463 #endif
1464     USBHSDCD_Type *base;
1465     usb_hsdcd_config_struct_t dcdParamConfig;
1466     usb_hsdcd_status_t dcdError = kStatus_hsdcd_Success;
1467 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1468     ((defined FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
1469 
1470     uint8_t index;
1471     usb_phydcd_config_struct_t phyDcdParamConfig;
1472     usb_phydcd_status_t phyDcdError = kStatus_phydcd_Success;
1473 #endif
1474 
1475     if ((controllerId < (uint8_t)kUSB_ControllerEhci0) ||
1476         ((uint32_t)((uint32_t)controllerId - (uint32_t)kUSB_ControllerEhci0) >= (sizeof(ehci_base) / sizeof(uint32_t))))
1477     {
1478         return kStatus_USB_ControllerNotFound;
1479     }
1480 
1481     ehciState = USB_EhciGetValidEhciState(&intanceIndex);
1482     if (NULL == ehciState)
1483     {
1484         return kStatus_USB_InvalidHandle;
1485     }
1486     ehciState->dtd = s_UsbDeviceEhciDtd[intanceIndex];
1487     temp           = (void *)&qh_buffer[intanceIndex * 2048U];
1488     ehciState->qh  = (usb_device_ehci_qh_struct_t *)temp;
1489 
1490     ehciState->controllerId = controllerId;
1491 
1492     ehciState->registerBase = (USBHS_Type *)ehci_base[controllerId - (uint8_t)kUSB_ControllerEhci0];
1493 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1494 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
1495 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
1496     if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
1497 #endif
1498     {
1499         ehciState->registerPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
1500     }
1501 #endif
1502 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
1503     ehciState->registerNcBase =
1504         (USBNC_Type *)USB_EhciGetBase(controllerId, &usbnc_base[0], sizeof(usbnc_base) / sizeof(uint32_t));
1505 #endif
1506 
1507 #endif
1508     /* For eUSB, do not need to reset controller. */
1509 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
1510     if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
1511 #endif
1512     {
1513         /* Reset the controller. */
1514         ehciState->registerBase->USBCMD |= USBHS_USBCMD_RST_MASK;
1515         while (0U != (ehciState->registerBase->USBCMD & USBHS_USBCMD_RST_MASK))
1516         {
1517         }
1518     }
1519 
1520     /* Get the HW's endpoint count */
1521     ehciState->endpointCount =
1522         (uint8_t)((ehciState->registerBase->DCCPARAMS & USBHS_DCCPARAMS_DEN_MASK) >> USBHS_DCCPARAMS_DEN_SHIFT);
1523 
1524     if (ehciState->endpointCount < USB_DEVICE_CONFIG_ENDPOINTS)
1525     {
1526         return kStatus_USB_Error;
1527     }
1528     ehciState->deviceHandle = (usb_device_struct_t *)handle;
1529 
1530     /* Clear the controller mode field and set to device mode. */
1531     ehciState->registerBase->USBMODE &= ~USBHS_USBMODE_CM_MASK;
1532     ehciState->registerBase->USBMODE |= USBHS_USBMODE_CM(0x02U);
1533 
1534     /* Set the EHCI to default status. */
1535     USB_DeviceEhciSetDefaultState(ehciState);
1536     *ehciHandle = (usb_device_controller_handle)ehciState;
1537 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1538     (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
1539     base = (USBHSDCD_Type *)USB_EhciGetBase(controllerId, &hsdcd_base[0], sizeof(hsdcd_base) / sizeof(uint32_t));
1540     dcdParamConfig.dcdCallback      = USB_DeviceEhciIsrHSDCDCallback;
1541     dcdParamConfig.dcdCallbackParam = (void *)ehciState;
1542     dcdError                        = USB_HSDCD_Init(base, &dcdParamConfig, &ehciState->dcdHandle);
1543     if (kStatus_hsdcd_Success != dcdError)
1544     {
1545         return kStatus_USB_Error;
1546     }
1547 
1548     if (0U != (ehciState->registerBase->OTGSC & USBHS_OTGSC_BSV_MASK))
1549     {
1550         /* Device is connected to a host. */
1551         message.code = (uint8_t)kUSB_DeviceNotifyAttach;
1552 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1553         if ((kStatus_USB_Success != USB_DeviceEhciNotification(ehciState, &message)) ||
1554             (kStatus_hsdcd_Success != USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DeviceHSDcdRun, NULL)))
1555         {
1556             return kStatus_USB_Error;
1557         }
1558 #else
1559         (void)USB_DeviceEhciNotification(ehciState, &message);
1560         (void)USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DeviceHSDcdRun, NULL);
1561 #endif
1562     }
1563 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1564     (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
1565 
1566     index = controllerId - (uint8_t)kUSB_ControllerEhci0;
1567 
1568     phyDcdParamConfig.dcdCallback      = USB_DeviceEhciIsrPHYDCDCallback;
1569     phyDcdParamConfig.dcdCallbackParam = (void *)ehciState;
1570 
1571     phyDcdError =
1572         USB_PHYDCD_Init(index, (usb_phydcd_config_struct_t *)&phyDcdParamConfig, (void *)&ehciState->dcdHandle);
1573     if (kStatus_phydcd_Success != phyDcdError)
1574     {
1575         return kStatus_USB_Error;
1576     }
1577 
1578     if (0U != (ehciState->registerBase->OTGSC & USBHS_OTGSC_BSV_MASK))
1579     {
1580         /* Device is connected to a host. */
1581         message.code = (uint8_t)kUSB_DeviceNotifyAttach;
1582 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1583         if ((kStatus_USB_Success != USB_DeviceEhciNotification(ehciState, &message)) ||
1584             (kStatus_USB_Success != USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DevicePHYDcdRun, NULL)))
1585         {
1586             return kStatus_USB_Error;
1587         }
1588 #else
1589         (void)USB_DeviceEhciNotification(ehciState, &message);
1590         (void)USB_PHYDCD_Control(ehciState->dcdHandle, kUSB_DevicePHYDcdRun, NULL);
1591 #endif
1592     }
1593 #endif
1594 
1595     return kStatus_USB_Success;
1596 }
1597 
1598 /*!
1599  * @brief De-initialize the USB device EHCI instance.
1600  *
1601  * This function de-initializes the USB device EHCI module.
1602  *
1603  * @param ehciHandle   Pointer of the device EHCI handle.
1604  *
1605  * @return A USB error code or kStatus_USB_Success.
1606  */
1607 usb_status_t USB_DeviceEhciDeinit(usb_device_controller_handle ehciHandle)
1608 {
1609     usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)ehciHandle;
1610 
1611     if (NULL == ehciHandle)
1612     {
1613         return kStatus_USB_InvalidHandle;
1614     }
1615     for (uint8_t instance = 0; instance < USB_DEVICE_CONFIG_EHCI; instance++)
1616     {
1617         if (ehciState == &g_UsbDeviceEhciState[instance])
1618         {
1619             g_UsbDeviceEhciStateStatus[instance] = 0;
1620         }
1621     }
1622 
1623     /* Disable all interrupt. */
1624     ehciState->registerBase->USBINTR = 0U;
1625     /* Stop the device functionality. */
1626     ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_RS_MASK;
1627     /* Reset the controller. */
1628     ehciState->registerBase->USBCMD |= USBHS_USBCMD_RST_MASK;
1629 
1630 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1631     (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
1632 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1633     if (kStatus_hsdcd_Success != USB_HSDCD_Deinit(ehciState->dcdHandle))
1634     {
1635         return kStatus_USB_Error;
1636     }
1637 #else
1638     (void)USB_HSDCD_Deinit(ehciState->dcdHandle);
1639 #endif
1640 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
1641     (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
1642 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1643     if (kStatus_USB_Success != USB_PHYDCD_Deinit(ehciState->dcdHandle))
1644     {
1645         return kStatus_USB_Error;
1646     }
1647 #else
1648     (void)USB_PHYDCD_Deinit(ehciState->dcdHandle);
1649 #endif
1650 #endif
1651 
1652     return kStatus_USB_Success;
1653 }
1654 
1655 /*!
1656  * @brief Send data through a specified endpoint.
1657  *
1658  * This function sends data through a specified endpoint.
1659  *
1660  * @param ehciHandle      Pointer of the device EHCI handle.
1661  * @param endpointAddress Endpoint index.
1662  * @param buffer           The memory address to hold the data need to be sent.
1663  * @param length           The data length need to be sent.
1664  *
1665  * @return A USB error code or kStatus_USB_Success.
1666  *
1667  * @note The return value just means if the sending request is successful or not; the transfer done is notified by the
1668  * corresponding callback function.
1669  * Currently, only one transfer request can be supported for one specific endpoint.
1670  * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1671  * should implement a queue in the application level.
1672  * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1673  * callback).
1674  */
1675 usb_status_t USB_DeviceEhciSend(usb_device_controller_handle ehciHandle,
1676                                 uint8_t endpointAddress,
1677                                 uint8_t *buffer,
1678                                 uint32_t length)
1679 {
1680     /* Add dtd to the QH */
1681     return USB_DeviceEhciTransfer(
1682         (usb_device_ehci_state_struct_t *)ehciHandle,
1683         (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
1684         buffer, length);
1685 }
1686 
1687 /*!
1688  * @brief Receive data through a specified endpoint.
1689  *
1690  * This function Receives data through a specified endpoint.
1691  *
1692  * @param ehciHandle      Pointer of the device EHCI handle.
1693  * @param endpointAddress Endpoint index.
1694  * @param buffer           The memory address to save the received data.
1695  * @param length           The data length want to be received.
1696  *
1697  * @return A USB error code or kStatus_USB_Success.
1698  *
1699  * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the
1700  * corresponding callback function.
1701  * Currently, only one transfer request can be supported for one specific endpoint.
1702  * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1703  * should implement a queue in the application level.
1704  * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1705  * callback).
1706  */
1707 usb_status_t USB_DeviceEhciRecv(usb_device_controller_handle ehciHandle,
1708                                 uint8_t endpointAddress,
1709                                 uint8_t *buffer,
1710                                 uint32_t length)
1711 {
1712     /* Add dtd to the QH */
1713     return USB_DeviceEhciTransfer(
1714         (usb_device_ehci_state_struct_t *)ehciHandle,
1715         (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
1716         buffer, length);
1717 }
1718 
1719 /*!
1720  * @brief Cancel the pending transfer in a specified endpoint.
1721  *
1722  * The function is used to cancel the pending transfer in a specified endpoint.
1723  *
1724  * @param ehciHandle      Pointer of the device EHCI handle.
1725  * @param ep               Endpoint address, bit7 is the direction of endpoint, 1U - IN, 0U - OUT.
1726  *
1727  * @return A USB error code or kStatus_USB_Success.
1728  */
1729 usb_status_t USB_DeviceEhciCancel(usb_device_controller_handle ehciHandle, uint8_t ep)
1730 {
1731     usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)ehciHandle;
1732     usb_device_callback_message_struct_t message;
1733     usb_device_ehci_dtd_struct_t *currentDtd;
1734     uint32_t primeBit =
1735         1UL << ((ep & USB_ENDPOINT_NUMBER_MASK) + ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U));
1736     uint8_t index =
1737         ((ep & USB_ENDPOINT_NUMBER_MASK) << 1U) | ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x07U);
1738     uint8_t flag = 0;
1739 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1740     uint32_t convert_addr = 0U;
1741 #endif
1742 
1743     OSA_SR_ALLOC();
1744 
1745     if (NULL == ehciHandle)
1746     {
1747         return kStatus_USB_InvalidHandle;
1748     }
1749 
1750     OSA_ENTER_CRITICAL();
1751 
1752     message.buffer = NULL;
1753     message.length = USB_CANCELLED_TRANSFER_LENGTH;
1754 
1755     /* Get the first dtd */
1756     currentDtd =
1757         (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK);
1758 
1759     /* In the next loop, USB_DeviceNotificationTrigger function may trigger a new transfer and the context always
1760      * keep in the critical section, so the Dtd sequence would still keep non-empty and the loop would be endless.
1761      * We set the Dtd's dtdInvalid in this while and add an if statement in the next loop so that this issue could
1762      * be fixed.
1763      */
1764     while (NULL != currentDtd)
1765     {
1766         currentDtd->reservedUnion.originalBufferInfo.dtdInvalid = 1U;
1767 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1768         currentDtd = (usb_device_ehci_dtd_struct_t *)USB_DEV_MEMORY_DMA_2_CPU(currentDtd->nextDtdPointer &
1769                                                                               USB_DEVICE_ECHI_DTD_POINTER_MASK);
1770 #else
1771         currentDtd = (usb_device_ehci_dtd_struct_t *)(currentDtd->nextDtdPointer & USB_DEVICE_ECHI_DTD_POINTER_MASK);
1772 #endif
1773     }
1774 
1775     /* Get the first dtd */
1776     currentDtd =
1777         (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK);
1778     while (NULL != currentDtd)
1779     {
1780         /* this if statement is used with  the previous while loop to avoid the endless loop */
1781         if (0U == currentDtd->reservedUnion.originalBufferInfo.dtdInvalid)
1782         {
1783             break;
1784         }
1785         else
1786         {
1787             if (0U != (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE))
1788             {
1789                 /* Flush the endpoint to stop a transfer. */
1790                 do
1791                 {
1792                     /* Set the corresponding bit(s) in the EPFLUSH register */
1793                     ehciState->registerBase->EPFLUSH |= primeBit;
1794 
1795                     /* Wait until all bits in the EPFLUSH register are cleared. */
1796                     while (0U != (ehciState->registerBase->EPFLUSH & primeBit))
1797                     {
1798                     }
1799                     /*
1800                      * Read the EPSR register to ensure that for all endpoints
1801                      * commanded to be flushed, that the corresponding bits
1802                      * are now cleared.
1803                      */
1804                 } while (0U != (ehciState->registerBase->EPSR & primeBit));
1805             }
1806 
1807             /* Save the original buffer address. */
1808             if (NULL == message.buffer)
1809             {
1810 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1811                 convert_addr   = (uint32_t)USB_DEV_MEMORY_DMA_2_CPU(currentDtd->bufferPointerPage[0]);
1812                 message.buffer = (uint8_t *)((convert_addr & USB_DEVICE_ECHI_DTD_PAGE_MASK) |
1813                                              (currentDtd->reservedUnion.originalBufferInfo.originalBufferOffest));
1814 #else
1815                 message.buffer = (uint8_t *)((currentDtd->bufferPointerPage[0] & USB_DEVICE_ECHI_DTD_PAGE_MASK) |
1816                                              (currentDtd->reservedUnion.originalBufferInfo.originalBufferOffest));
1817 #endif
1818             }
1819 
1820             /* Remove the dtd from the dtd in-used queue. */
1821             if (ehciState->dtdHard[index] == ehciState->dtdTail[index])
1822             {
1823                 ehciState->dtdHard[index] = NULL;
1824                 ehciState->dtdTail[index] = NULL;
1825             }
1826             else
1827             {
1828 #if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1829                 ehciState->dtdHard[index] =
1830                     (usb_device_ehci_dtd_struct_t *)USB_DEV_MEMORY_DMA_2_CPU(ehciState->dtdHard[index]->nextDtdPointer);
1831 #else
1832                 ehciState->dtdHard[index] = (usb_device_ehci_dtd_struct_t *)ehciState->dtdHard[index]->nextDtdPointer;
1833 #endif
1834             }
1835 
1836             /* When the ioc is set or the dtd queue is empty, the up layer will be notified. */
1837             if ((0U != currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc) ||
1838                 (0U == ((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK)))
1839             {
1840                 flag = 1;
1841             }
1842             /* Clear the token field. */
1843             currentDtd->dtdTokenUnion.dtdToken = 0U;
1844             /* Save the dtd to the free queue. */
1845             currentDtd->nextDtdPointer = (uint32_t)ehciState->dtdFree;
1846             ehciState->dtdFree         = currentDtd;
1847             ehciState->dtdCount++;
1848         }
1849         /* Get the next dtd. */
1850         currentDtd =
1851             (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK);
1852     }
1853     if (NULL == currentDtd)
1854     {
1855         /* Set the QH to empty. */
1856         ehciState->qh[index].nextDtdPointer         = USB_DEVICE_ECHI_DTD_TERMINATE_MASK;
1857         ehciState->qh[index].dtdTokenUnion.dtdToken = 0U;
1858     }
1859     OSA_EXIT_CRITICAL();
1860 
1861     if (0U != flag)
1862     {
1863         message.code    = ep;
1864         message.isSetup = 0U;
1865 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1866         if (kStatus_USB_Success != USB_DeviceEhciNotification(ehciState, &message))
1867         {
1868             return kStatus_USB_Error;
1869         }
1870 #else
1871         (void)USB_DeviceEhciNotification(ehciState, &message);
1872 #endif
1873         message.buffer = NULL;
1874     }
1875 
1876     return kStatus_USB_Success;
1877 }
1878 
1879 /*!
1880  * @brief Control the status of the selected item.
1881  *
1882  * The function is used to control the status of the selected item.
1883  *
1884  * @param ehciHandle      Pointer of the device EHCI handle.
1885  * @param type             The selected item. Please refer to enumeration type usb_device_control_type_t.
1886  * @param param            The param type is determined by the selected item.
1887  *
1888  * @return A USB error code or kStatus_USB_Success.
1889  */
1890 usb_status_t USB_DeviceEhciControl(usb_device_controller_handle ehciHandle, usb_device_control_type_t type, void *param)
1891 {
1892     usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)ehciHandle;
1893     usb_status_t error                        = kStatus_USB_Error;
1894 #if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
1895     uint32_t *temp32;
1896 #endif
1897     uint16_t *temp16;
1898     uint8_t *temp8;
1899 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1900     OSA_SR_ALLOC();
1901 #endif
1902 
1903 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1904     usb_device_struct_t *deviceHandle;
1905 #endif
1906 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1907 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1908     uint64_t startTick;
1909 #endif
1910 #endif
1911 
1912     if (NULL == ehciHandle)
1913     {
1914         return kStatus_USB_InvalidHandle;
1915     }
1916 
1917 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1918     deviceHandle = (usb_device_struct_t *)ehciState->deviceHandle;
1919 #endif
1920 
1921     switch (type)
1922     {
1923         case kUSB_DeviceControlRun:
1924             ehciState->registerBase->USBCMD |= USBHS_USBCMD_RS_MASK;
1925             error = kStatus_USB_Success;
1926             break;
1927         case kUSB_DeviceControlStop:
1928             ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_RS_MASK;
1929             error = kStatus_USB_Success;
1930             break;
1931         case kUSB_DeviceControlEndpointInit:
1932             if (NULL != param)
1933             {
1934                 error = USB_DeviceEhciEndpointInit(ehciState, (usb_device_endpoint_init_struct_t *)param);
1935             }
1936             break;
1937         case kUSB_DeviceControlEndpointDeinit:
1938             if (NULL != param)
1939             {
1940                 temp8 = (uint8_t *)param;
1941                 error = USB_DeviceEhciEndpointDeinit(ehciState, *temp8);
1942             }
1943             break;
1944         case kUSB_DeviceControlEndpointStall:
1945             if (NULL != param)
1946             {
1947                 temp8 = (uint8_t *)param;
1948                 error = USB_DeviceEhciEndpointStall(ehciState, *temp8);
1949             }
1950             break;
1951         case kUSB_DeviceControlEndpointUnstall:
1952             if (NULL != param)
1953             {
1954                 temp8 = (uint8_t *)param;
1955                 error = USB_DeviceEhciEndpointUnstall(ehciState, *temp8);
1956             }
1957             break;
1958         case kUSB_DeviceControlGetDeviceStatus:
1959             if (NULL != param)
1960             {
1961                 temp16  = (uint16_t *)param;
1962                 *temp16 = ((uint16_t)USB_DEVICE_CONFIG_SELF_POWER
1963                            << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT))
1964 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1965                           | ((uint16_t)deviceHandle->remotewakeup
1966                              << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT))
1967 #endif
1968                     ;
1969                 error = kStatus_USB_Success;
1970             }
1971             break;
1972         case kUSB_DeviceControlGetEndpointStatus:
1973             if (NULL != param)
1974             {
1975                 usb_device_endpoint_status_struct_t *endpointStatus = (usb_device_endpoint_status_struct_t *)param;
1976                 uint8_t ep = (endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK;
1977                 uint8_t direction =
1978                     ((endpointStatus->endpointAddress) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1979                     USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
1980 
1981                 if (ep < USB_DEVICE_CONFIG_ENDPOINTS)
1982                 {
1983                     if (0U != ep)
1984                     {
1985                         endpointStatus->endpointStatus =
1986                             (0U != (ehciState->registerBase->EPCR[ep - 1U] &
1987                                     ((0U != direction) ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK))) ?
1988                                 (uint16_t)kUSB_DeviceEndpointStateStalled :
1989                                 (uint16_t)kUSB_DeviceEndpointStateIdle;
1990                     }
1991                     else
1992                     {
1993                         endpointStatus->endpointStatus =
1994                             (0U != (ehciState->registerBase->EPCR0 &
1995                                     ((0U != direction) ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK))) ?
1996                                 (uint16_t)kUSB_DeviceEndpointStateStalled :
1997                                 (uint16_t)kUSB_DeviceEndpointStateIdle;
1998                     }
1999                     error = kStatus_USB_Success;
2000                 }
2001             }
2002             break;
2003         case kUSB_DeviceControlPreSetDeviceAddress:
2004             if (NULL != param)
2005             {
2006                 temp8 = (uint8_t *)param;
2007                 ehciState->registerBase->DEVICEADDR =
2008                     ((((uint32_t)(*temp8)) << USBHS_DEVICEADDR_USBADR_SHIFT) | USBHS_DEVICEADDR_USBADRA_MASK);
2009                 error = kStatus_USB_Success;
2010             }
2011             break;
2012         case kUSB_DeviceControlSetDeviceAddress:
2013             error = kStatus_USB_Success;
2014             break;
2015         case kUSB_DeviceControlGetSynchFrame:
2016             break;
2017 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
2018 #if defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)
2019         case kUSB_DeviceControlResume:
2020 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
2021             ehciState->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
2022 #else
2023 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
2024 #else
2025             ehciState->registerBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK;
2026 #endif
2027 #endif
2028             ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
2029             ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK;
2030             startTick = deviceHandle->hwTick;
2031             while ((deviceHandle->hwTick - startTick) < 10U)
2032             {
2033                 __NOP();
2034             }
2035             ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_FPR_MASK;
2036             error = kStatus_USB_Success;
2037             break;
2038 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
2039         case kUSB_DeviceControlSleepResume:
2040 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
2041             ehciState->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
2042 #endif
2043             ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
2044             ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK;
2045             error = kStatus_USB_Success;
2046             break;
2047 #endif
2048 #endif /* USB_DEVICE_CONFIG_REMOTE_WAKEUP */
2049         case kUSB_DeviceControlSuspend:
2050             ehciState->registerBase->OTGSC |= 0x007F0000U;
2051             OSA_ENTER_CRITICAL();
2052 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
2053             /* ehciState->registerBase->PLL_CONTROL_1 |= USBC_PLL_CONTROL_1_PLL_SUSPEND_EN(1); */
2054 #endif
2055 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2056 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2057             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2058 #endif
2059             {
2060                 ehciState->registerPhyBase->PWD = 0xFFFFFFFFU;
2061                 /* ehciState->registerBase->OTGCTL |= ((1U<<10) | (1U<<17) | (1U<<16)); */
2062             }
2063 #endif
2064             /* ehciState->registerPhyBase->CTRL |= ((1U << 21) | (1U << 22) | (1U << 23)); */
2065             ehciState->registerBase->USBSTS |= USBHS_USBSTS_SRI_MASK;
2066 #if (defined(FSL_FEATURE_USBPHY_28FDSOI) && (FSL_FEATURE_USBPHY_28FDSOI > 0U))
2067 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2068 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2069             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2070 #endif
2071             {
2072                 ehciState->registerPhyBase->USB1_VBUS_DETECT_SET |= USBPHY_USB1_VBUS_DETECT_VBUSVALID_TO_SESSVALID_MASK;
2073             }
2074 #endif
2075 #endif
2076             ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_PHCD_MASK;
2077 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
2078 #if (defined(USBPHY_CTRL_ENVBUSCHG_WKUP_MASK))
2079 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2080 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2081             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2082 #endif
2083             {
2084                 ehciState->registerPhyBase->CTRL |= USBPHY_CTRL_ENVBUSCHG_WKUP_MASK | USBPHY_CTRL_ENIDCHG_WKUP_MASK |
2085                                                     USBPHY_CTRL_ENDPDMCHG_WKUP_MASK |
2086                                                     USBPHY_CTRL_ENIRQRESUMEDETECT_MASK;
2087             }
2088 #endif
2089 #endif
2090 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2091             ehciState->registerNcBase->USB_OTGn_CTRL |=
2092                 USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK | USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
2093 #else
2094             ehciState->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_ID_EN_MASK |
2095                                                         USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK |
2096                                                         USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
2097 #endif
2098             ehciState->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WIE_MASK;
2099 #else
2100 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
2101             PMU->WAKEUP_PM2_MASK1 |= PMU_WAKEUP_PM2_MASK1_USB(1);
2102 #else
2103             ehciState->registerBase->USBGENCTRL = USBHS_USBGENCTRL_WU_IE_MASK;
2104 #endif
2105 #endif
2106 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2107 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2108             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2109 #endif
2110             {
2111                 ehciState->registerPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK;
2112             }
2113 #endif
2114             ehciState->isSuspending = 1U;
2115             OSA_EXIT_CRITICAL();
2116             error = kStatus_USB_Success;
2117             break;
2118 
2119 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
2120         case kUSB_DeviceControlSleep:
2121             ehciState->registerBase->OTGSC |= 0x007F0000U;
2122             OSA_ENTER_CRITICAL();
2123 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2124 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2125             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2126 #endif
2127             {
2128                 ehciState->registerPhyBase->PWD = 0xFFFFFFFFU;
2129                 /* ehciState->registerBase->OTGCTL |= ((1U<<10) | (1U<<17) | (1U<<16)); */
2130             }
2131 #endif
2132             ehciState->registerBase->USBSTS |= USBHS_USBSTS_SRI_MASK;
2133 #if (defined(FSL_FEATURE_USBPHY_28FDSOI) && (FSL_FEATURE_USBPHY_28FDSOI > 0U))
2134 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2135 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2136             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2137 #endif
2138             {
2139                 ehciState->registerPhyBase->USB1_VBUS_DETECT_SET |= USBPHY_USB1_VBUS_DETECT_VBUSVALID_TO_SESSVALID_MASK;
2140             }
2141 #endif
2142 #endif
2143             /* ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_PHCD_MASK;*/
2144 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
2145 #if (defined(USBPHY_CTRL_ENVBUSCHG_WKUP_MASK))
2146 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2147 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2148             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2149 #endif
2150             {
2151                 ehciState->registerPhyBase->CTRL |= USBPHY_CTRL_ENVBUSCHG_WKUP_MASK | USBPHY_CTRL_ENIDCHG_WKUP_MASK |
2152                                                     USBPHY_CTRL_ENDPDMCHG_WKUP_MASK |
2153                                                     USBPHY_CTRL_ENIRQRESUMEDETECT_MASK;
2154             }
2155 #endif
2156 #endif
2157 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2158             ehciState->registerNcBase->USB_OTGn_CTRL |=
2159                 USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK | USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
2160 #else
2161             ehciState->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_ID_EN_MASK |
2162                                                         USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK |
2163                                                         USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
2164 #endif
2165             ehciState->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WIE_MASK;
2166 #else
2167 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
2168             PMU->WAKEUP_PM2_MASK1 |= PMU_WAKEUP_PM2_MASK1_USB(1);
2169 #else
2170             ehciState->registerBase->USBGENCTRL = USBHS_USBGENCTRL_WU_IE_MASK;
2171 #endif
2172 #endif
2173 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
2174 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
2175             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciState->registerBase))
2176 #endif
2177             {
2178                 ehciState->registerPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK;
2179             }
2180 #endif
2181             /* TODO: wait 3us delay */
2182             ehciState->isSuspending = 1U;
2183             OSA_EXIT_CRITICAL();
2184             error = kStatus_USB_Success;
2185             break;
2186 #endif
2187 
2188 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
2189         case kUSB_DeviceControlSetDefaultStatus:
2190             for (uint8_t count = 0U; count < USB_DEVICE_CONFIG_ENDPOINTS; count++)
2191             {
2192 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
2193                 if ((kStatus_USB_Success != USB_DeviceEhciEndpointDeinit(ehciState, (count | (USB_IN << 0x07U)))) ||
2194                     (kStatus_USB_Success != USB_DeviceEhciEndpointDeinit(ehciState, (count | (USB_OUT << 0x07U)))))
2195                 {
2196                     return kStatus_USB_Error;
2197                 }
2198 #else
2199                 (void)USB_DeviceEhciEndpointDeinit(ehciState, (count | (USB_IN << 0x07U)));
2200                 (void)USB_DeviceEhciEndpointDeinit(ehciState, (count | (USB_OUT << 0x07U)));
2201 #endif
2202             }
2203             USB_DeviceEhciSetDefaultState(ehciState);
2204             error = kStatus_USB_Success;
2205             break;
2206         case kUSB_DeviceControlGetSpeed:
2207             if (NULL != param)
2208             {
2209                 temp8  = (uint8_t *)param;
2210                 *temp8 = ehciState->speed;
2211                 error  = kStatus_USB_Success;
2212             }
2213             break;
2214         case kUSB_DeviceControlGetOtgStatus:
2215             break;
2216         case kUSB_DeviceControlSetOtgStatus:
2217             break;
2218 #if (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U))
2219         case kUSB_DeviceControlSetTestMode:
2220             if (param)
2221             {
2222                 temp8 = (uint8_t *)param;
2223                 ehciState->registerBase->PORTSC1 |= ((uint32_t)(*temp8) << 16U);
2224                 error = kStatus_USB_Success;
2225             }
2226             break;
2227 #endif
2228 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
2229 
2230         case kUSB_DeviceControlUpdateHwTick:
2231             /*udpate 1ms time tick*/
2232 #if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
2233 #ifndef USBHSDCD_IRQS
2234             USB_HSDcdIsrFunction(ehciState->dcdHandle);
2235 #endif
2236 #elif (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
2237 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
2238             if (kStatus_USB_Success != USB_PHYDCD_TimerIsrFunction(ehciState->dcdHandle))
2239             {
2240                 return kStatus_USB_Error;
2241             }
2242 #else
2243             (void)USB_PHYDCD_TimerIsrFunction(ehciState->dcdHandle);
2244 #endif
2245 #endif
2246 
2247             error = kStatus_USB_Success;
2248             break;
2249         case kUSB_DeviceControlDcdEnable:
2250 
2251 #if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
2252             if (kStatus_hsdcd_Success == USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DeviceHSDcdEnable, NULL))
2253             {
2254                 error = kStatus_USB_Success;
2255             }
2256 #elif (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
2257             if (kStatus_phydcd_Success == USB_PHYDCD_Control(ehciState->dcdHandle, kUSB_DevicePHYDcdEnable, NULL))
2258             {
2259                 error = kStatus_USB_Success;
2260             }
2261 #endif
2262 
2263             break;
2264         case kUSB_DeviceControlDcdDisable:
2265 
2266 #if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
2267             if (kStatus_hsdcd_Success == USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DeviceHSDcdDisable, NULL))
2268             {
2269                 error = kStatus_USB_Success;
2270             }
2271 #elif (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
2272             if (kStatus_phydcd_Success == USB_PHYDCD_Control(ehciState->dcdHandle, kUSB_DevicePHYDcdDisable, NULL))
2273             {
2274                 error = kStatus_USB_Success;
2275             }
2276 #endif
2277 
2278             break;
2279 #endif
2280 #if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
2281         case kUSB_DeviceControlGetCurrentFrameCount:
2282             if (NULL != param)
2283             {
2284                 temp32 = (uint32_t *)param;
2285                 if (USB_SPEED_HIGH == ehciState->speed)
2286                 {
2287                     *temp32 = ehciState->registerBase->FRINDEX & (USB_DEVICE_MAX_FRAME_COUNT);
2288                 }
2289                 else /* if not high speed, change to use frame count */
2290                 {
2291                     *temp32 = (ehciState->registerBase->FRINDEX & (USB_DEVICE_MAX_FRAME_COUNT)) / 8U;
2292                 }
2293                 error = kStatus_USB_Success;
2294             }
2295             break;
2296 #endif
2297         default:
2298             /*no action*/
2299             break;
2300     }
2301 
2302     return error;
2303 }
2304 
2305 /*!
2306  * @brief Handle the EHCI device interrupt.
2307  *
2308  * The function is used to handle the EHCI device interrupt.
2309  *
2310  * @param deviceHandle    The device handle got from USB_DeviceInit.
2311  *
2312  */
2313 void USB_DeviceEhciIsrFunction(void *deviceHandle)
2314 {
2315     usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
2316     usb_device_ehci_state_struct_t *ehciState;
2317     uint32_t status;
2318 
2319     if (NULL == deviceHandle)
2320     {
2321         return;
2322     }
2323 
2324     ehciState = (usb_device_ehci_state_struct_t *)(handle->controllerHandle);
2325 
2326 #if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
2327 
2328 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
2329 
2330     if (0U != (ehciState->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIE_MASK))
2331     {
2332         if (0U != (ehciState->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIR_MASK))
2333         {
2334             ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
2335             ehciState->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
2336         }
2337     }
2338     else
2339     {
2340     }
2341 
2342 #else
2343 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
2344 #else
2345     if (0U != (ehciState->registerBase->USBGENCTRL & USBHS_USBGENCTRL_WU_IE_MASK))
2346     {
2347         if (0U != (ehciState->registerBase->USBGENCTRL & (1UL << 8)))
2348         {
2349             ehciState->registerBase->USBGENCTRL &= ~(1UL << 8);
2350             ehciState->registerBase->USBGENCTRL |= USBHS_USBGENCTRL_WU_INT_CLR_MASK;
2351             ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
2352             ehciState->registerBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK;
2353         }
2354     }
2355     else
2356     {
2357     }
2358 #endif
2359 #endif
2360 
2361 #endif
2362 
2363 #if defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)
2364     if ((ehciState->registerBase->OTGSC & USBHS_OTGSC_BSVIS_MASK) != 0U)
2365     {
2366         usb_device_callback_message_struct_t message;
2367 
2368         ehciState->registerBase->OTGSC |= USBHS_OTGSC_BSVIS_MASK;
2369 
2370         message.buffer  = (uint8_t *)NULL;
2371         message.length  = 0U;
2372         message.isSetup = 0U;
2373         if (0U != (ehciState->registerBase->OTGSC & USBHS_OTGSC_BSV_MASK))
2374         {
2375             /* Device is connected to a host. */
2376             message.code = (uint8_t)kUSB_DeviceNotifyAttach;
2377             (void)USB_DeviceEhciNotification(ehciState, &message);
2378 
2379 #if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) && \
2380     (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
2381 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
2382             if (kStatus_hsdcd_Success != USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DeviceHSDcdRun, NULL))
2383             {
2384 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
2385                 usb_echo("hsdcd run error\n");
2386 #endif
2387             }
2388 #else
2389             (void)USB_HSDCD_Control(ehciState->dcdHandle, kUSB_DeviceHSDcdRun, NULL);
2390 #endif
2391 #elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \
2392     (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U))
2393 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
2394             if (kStatus_phydcd_Error != USB_PHYDCD_Control(ehciState->dcdHandle, kUSB_DevicePHYDcdRun, NULL))
2395             {
2396 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
2397                 usb_echo("phydcd run error\n");
2398 #endif
2399             }
2400 #else
2401             (void)USB_PHYDCD_Control(ehciState->dcdHandle, kUSB_DevicePHYDcdRun, NULL);
2402 #endif
2403 #endif
2404         }
2405         else
2406         {
2407             /* Device is disconnected from a host. */
2408             message.code = (uint8_t)kUSB_DeviceNotifyDetach;
2409             (void)USB_DeviceEhciNotification(ehciState, &message);
2410         }
2411     }
2412 #endif /* USB_DEVICE_CONFIG_DETACH_ENABLE */
2413 
2414     status = ehciState->registerBase->USBSTS;
2415     status &= ehciState->registerBase->USBINTR;
2416 
2417     ehciState->registerBase->USBSTS = status;
2418 
2419 #if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)
2420     if (0U != (status & USBHS_USBSTS_UEI_MASK))
2421     {
2422         /* Error interrupt */
2423         USB_DeviceEhciInterruptError(ehciState);
2424     }
2425 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
2426 
2427     if (0U != (status & USBHS_USBSTS_URI_MASK))
2428     {
2429         /* Reset interrupt */
2430         USB_DeviceEhciInterruptReset(ehciState);
2431     }
2432 
2433     if (0U != (status & USBHS_USBSTS_UI_MASK))
2434     {
2435         /* Token done interrupt */
2436         USB_DeviceEhciInterruptTokenDone(ehciState);
2437     }
2438 
2439     if (0U != (status & USBHS_USBSTS_PCI_MASK))
2440     {
2441         /* Port status change interrupt */
2442         USB_DeviceEhciInterruptPortChange(ehciState);
2443     }
2444 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
2445     if (0U != (status & USBHS_USBSTS_SLI_MASK))
2446     {
2447         /* Suspend interrupt */
2448         USB_DeviceEhciInterruptSuspend(ehciState);
2449     }
2450 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
2451     if (0U != (status & USB_USBSTS_LPM_L1_ENTRYI_MASK))
2452     {
2453         USB_DeviceEhciInterruptLPMSleep(ehciState);
2454     }
2455 #endif
2456 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
2457 
2458 #if (defined(USB_DEVICE_CONFIG_SOF_NOTIFICATIONS) && (USB_DEVICE_CONFIG_SOF_NOTIFICATIONS > 0U))
2459     if (0U != (status & USBHS_USBSTS_SRI_MASK))
2460     {
2461         /* SOF interrupt */
2462         USB_DeviceEhciInterruptSOF(ehciState);
2463     }
2464 #endif
2465 }
2466 
2467 #endif /* USB_DEVICE_CONFIG_EHCI */
2468