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