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