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