1 /*
2 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2018 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "usb_device_config.h"
10 #include "usb.h"
11
12 #include "usb_device.h"
13
14 #include "fsl_device_registers.h"
15
16 #if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
17
18 #include "usb_device_dci.h"
19
20 #include "usb_device_khci.h"
21
22 /*******************************************************************************
23 * Definitions
24 ******************************************************************************/
25 #if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM > 0U)
26
27 /* USB_STACK_USE_DEDICATED_RAM */
28 #if defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
29
30 #if (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL)
31 #if (FSL_FEATURE_USB_KHCI_USB_RAM > 512U)
32 #else
33 #error The dedicated RAM length is not more than 512 Bytes, the SOC does not support this case.
34 #endif
35 #endif /* USB_STACK_USE_DEDICATED_RAM */
36
37 #else
38 #error The SOC does not suppoort dedicated RAM case.
39 #endif /* USB_STACK_USE_DEDICATED_RAM */
40
41 #endif
42
43 /*******************************************************************************
44 * Prototypes
45 ******************************************************************************/
46 static usb_status_t USB_DeviceKhciEndpointTransfer(
47 usb_device_khci_state_struct_t *khciState, uint8_t endpoint, uint8_t direction, uint8_t *buffer, uint32_t length);
48 static void USB_DeviceKhciPrimeNextSetup(usb_device_khci_state_struct_t *khciState);
49 static void USB_DeviceKhciSetDefaultState(usb_device_khci_state_struct_t *khciState);
50 static usb_status_t USB_DeviceKhciEndpointInit(usb_device_khci_state_struct_t *khciState,
51 usb_device_endpoint_init_struct_t *epInit);
52 static usb_status_t USB_DeviceKhciEndpointDeinit(usb_device_khci_state_struct_t *khciState, uint8_t ep);
53 static usb_status_t USB_DeviceKhciEndpointStall(usb_device_khci_state_struct_t *khciState, uint8_t ep);
54 static usb_status_t USB_DeviceKhciEndpointUnstall(usb_device_khci_state_struct_t *khciState, uint8_t ep);
55 static void USB_DeviceKhciInterruptTokenDone(usb_device_khci_state_struct_t *khciState);
56 static void USB_DeviceKhciInterruptReset(usb_device_khci_state_struct_t *khciState);
57 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
58 static void USB_DeviceKhciInterruptSleep(usb_device_khci_state_struct_t *khciState);
59 static void USB_DeviceKhciInterruptResume(usb_device_khci_state_struct_t *khciState);
60 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
61 static void USB_DeviceKhciInterruptStall(usb_device_khci_state_struct_t *khciState);
62 #if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)
63 static void USB_DeviceKhciInterruptError(usb_device_khci_state_struct_t *khciState);
64 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
65
66 /*******************************************************************************
67 * Variables
68 ******************************************************************************/
69
70 /* Apply for BDT buffer, 512-byte alignment */
71 USB_BDT USB_RAM_ADDRESS_ALIGNMENT(512) static uint32_t
72 s_UsbDeviceKhciBdtBuffer[USB_DEVICE_CONFIG_KHCI][512U / sizeof(uint32_t)];
73
74 /* Apply for khci device state structure */
75 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_khci_state_struct_t
76 s_UsbDeviceKhciState[USB_DEVICE_CONFIG_KHCI];
77
78 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
79 (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U))
80 /* Apply for device dcd state structure */
81 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_dcd_state_struct_t
82 s_UsbDeviceDcdState[USB_DEVICE_CONFIG_KHCI];
83 #endif
84
85 /* Apply for KHCI DMA aligned buffer when macro USB_DEVICE_CONFIG_KHCI_DMA_ALIGN enabled */
USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE)86 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint32_t
87 s_UsbDeviceKhciDmaAlignBuffer[USB_DEVICE_CONFIG_KHCI]
88 [((USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH - 1U) >> 2U) + 1U];
89
90 /*******************************************************************************
91 * Code
92 ******************************************************************************/
93
94 /*!
95 * @brief Write the BDT to start a transfer.
96 *
97 * The function is used to start a transfer by writing the BDT.
98 *
99 * @param khciState Pointer of the device KHCI state structure.
100 * @param endpoint Endpoint number.
101 * @param direction The direction of the endpoint, 0U - USB_OUT, 1U - USB_IN.
102 * @param buffer The memory address to save the received data, or the memory address to hold the data need to
103 * be sent.
104 * @param length The length of the data.
105 *
106 * @return A USB error code or kStatus_USB_Success.
107 */
108 static usb_status_t USB_DeviceKhciEndpointTransfer(
109 usb_device_khci_state_struct_t *khciState, uint8_t endpoint, uint8_t direction, uint8_t *buffer, uint32_t length)
110 {
111 uint32_t index = ((uint32_t)endpoint << 1U) | (uint32_t)direction;
112 OSA_SR_ALLOC();
113
114 /* Enter critical */
115 OSA_ENTER_CRITICAL();
116
117 /* Flag the endpoint is busy. */
118 khciState->endpointState[index].stateUnion.stateBitField.transferring = 1U;
119
120 /* Add the data buffer address to the BDT. */
121 USB_KHCI_BDT_SET_ADDRESS((uint32_t)khciState->bdt, endpoint, direction,
122 khciState->endpointState[index].stateUnion.stateBitField.bdtOdd, (uint32_t)buffer);
123
124 /* Change the BDT control field to start the transfer. */
125 USB_KHCI_BDT_SET_CONTROL(
126 (uint32_t)khciState->bdt, endpoint, direction, khciState->endpointState[index].stateUnion.stateBitField.bdtOdd,
127 USB_LONG_TO_LITTLE_ENDIAN(USB_KHCI_BDT_BC(length) | USB_KHCI_BDT_OWN | USB_KHCI_BDT_DTS |
128 USB_KHCI_BDT_DATA01(khciState->endpointState[index].stateUnion.stateBitField.data0)));
129
130 /* Exit critical */
131 OSA_EXIT_CRITICAL();
132
133 /* Clear the token busy state */
134 khciState->registerBase->CTL &= (uint8_t)(~USB_CTL_TXSUSPENDTOKENBUSY_MASK);
135 return kStatus_USB_Success;
136 }
137
138 /*!
139 * @brief Prime a next setup transfer.
140 *
141 * The function is used to prime a buffer in control out pipe to wait for receiving the host's setup packet.
142 *
143 * @param khciState Pointer of the device KHCI state structure.
144 *
145 */
USB_DeviceKhciPrimeNextSetup(usb_device_khci_state_struct_t * khciState)146 static void USB_DeviceKhciPrimeNextSetup(usb_device_khci_state_struct_t *khciState)
147 {
148 /* Update the endpoint state */
149 /* Save the buffer address used to receive the setup packet. */
150 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
151 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
152 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
153 /* In case of lowpower mode enabled, it requires to put the setup packet buffer(16 bytes) into the USB RAM so
154 * that the setup packet would wake up the USB.
155 */
156 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer =
157 (uint8_t *)(khciState->bdt + 0x200U - 0x10U) +
158 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.bdtOdd *
159 USB_SETUP_PACKET_SIZE;
160 #else
161 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer =
162 (uint8_t *)&khciState->setupPacketBuffer[0] +
163 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.bdtOdd *
164 USB_SETUP_PACKET_SIZE;
165 #endif
166 /* Clear the transferred length. */
167 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferDone = 0U;
168 /* Save the data length expected to get from a host. */
169 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferLength = USB_SETUP_PACKET_SIZE;
170 /* Save the data buffer DMA align flag. */
171 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.dmaAlign = 1U;
172 /* Set the DATA0/1 to DATA0. */
173 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.data0 = 0U;
174 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
175 if (kStatus_USB_Success !=
176 USB_DeviceKhciEndpointTransfer(khciState, USB_CONTROL_ENDPOINT, USB_OUT,
177 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer,
178 USB_SETUP_PACKET_SIZE))
179 {
180 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
181 usb_echo("start transfer error\r\n");
182 #endif
183 }
184 #else
185 (void)USB_DeviceKhciEndpointTransfer(
186 khciState, USB_CONTROL_ENDPOINT, USB_OUT,
187 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer, USB_SETUP_PACKET_SIZE);
188 #endif
189 }
190
191 /*!
192 * @brief Set device controller state to default state.
193 *
194 * The function is used to set device controller state to default state.
195 * The function will be called when USB_DeviceKhciInit called or the control type kUSB_DeviceControlGetEndpointStatus
196 * received in USB_DeviceKhciControl.
197 *
198 * @param khciState Pointer of the device KHCI state structure.
199 *
200 */
USB_DeviceKhciSetDefaultState(usb_device_khci_state_struct_t * khciState)201 static void USB_DeviceKhciSetDefaultState(usb_device_khci_state_struct_t *khciState)
202 {
203 uint8_t interruptFlag;
204 uint8_t count;
205
206 /* Clear the error state register */
207 khciState->registerBase->ERRSTAT = 0xFFU;
208
209 /* Setting this bit to 1U resets all the BDT ODD ping/pong fields to 0U, which then specifies the EVEN BDT bank. */
210 khciState->registerBase->CTL |= USB_CTL_ODDRST_MASK;
211
212 /* Clear the device address */
213 khciState->registerBase->ADDR = 0U;
214
215 /* Clear the endpoint state and disable the endpoint */
216 for (count = 0U; count < USB_DEVICE_CONFIG_ENDPOINTS; count++)
217 {
218 USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_OUT, 0U, 0U);
219 USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_OUT, 1U, 0U);
220 USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_IN, 0U, 0U);
221 USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_IN, 1U, 0U);
222
223 khciState->endpointState[((uint32_t)count << 1U) | USB_OUT].stateUnion.state = 0U;
224 khciState->endpointState[((uint32_t)count << 1U) | USB_IN].stateUnion.state = 0U;
225 khciState->registerBase->ENDPOINT[count].ENDPT = 0x00U;
226 }
227 khciState->isDmaAlignBufferInusing = 0U;
228
229 /* Clear the BDT odd reset flag */
230 khciState->registerBase->CTL &= (uint8_t)(~USB_CTL_ODDRST_MASK);
231
232 /* Enable all error */
233 khciState->registerBase->ERREN = 0xFFU;
234
235 /* Enable reset, sof, token, stall interrupt */
236 interruptFlag = USB_INTEN_USBRSTEN_MASK
237 #if 0U
238 | USB_INTEN_SOFTOKEN_MASK
239 #endif
240 | USB_INTEN_TOKDNEEN_MASK | USB_INTEN_STALLEN_MASK;
241
242 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
243 /* Enable suspend interrupt */
244 interruptFlag |= USB_INTEN_SLEEPEN_MASK;
245 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
246
247 #if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)
248 /* Enable error interrupt */
249 interruptFlag |= USB_INTEN_ERROREN_MASK;
250 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
251
252 #if defined(USB_DEVICE_CONFIG_SOF_NOTIFICATIONS) && (USB_DEVICE_CONFIG_SOF_NOTIFICATIONS > 0U)
253 /* Enable SOF interrupt */
254 interruptFlag |= USB_INTEN_SOFTOKEN_MASK;
255 #endif /* USB_DEVICE_CONFIG_SOF_NOTIFICATIONS */
256
257 /* Write the interrupt enable register */
258 khciState->registerBase->INTEN = interruptFlag;
259
260 /* Clear reset flag */
261 khciState->isResetting = 0U;
262
263 khciState->registerBase->CTL &= (uint8_t)(~USB_CTL_TXSUSPENDTOKENBUSY_MASK);
264 }
265
266 /*!
267 * @brief Initialize a specified endpoint.
268 *
269 * The function is used to initialize a specified endpoint.
270 *
271 * @param khciState Pointer of the device KHCI state structure.
272 * @param epInit The endpoint initialization structure pointer.
273 *
274 * @return A USB error code or kStatus_USB_Success.
275 */
USB_DeviceKhciEndpointInit(usb_device_khci_state_struct_t * khciState,usb_device_endpoint_init_struct_t * epInit)276 static usb_status_t USB_DeviceKhciEndpointInit(usb_device_khci_state_struct_t *khciState,
277 usb_device_endpoint_init_struct_t *epInit)
278 {
279 uint16_t maxPacketSize = epInit->maxPacketSize;
280 uint8_t endpoint = (epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK);
281 uint8_t direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
282 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
283 uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
284
285 /* Make the endpoint max packet size align with USB Specification 2.0. */
286 if (USB_ENDPOINT_ISOCHRONOUS == epInit->transferType)
287 {
288 if (maxPacketSize > USB_DEVICE_MAX_FS_ISO_MAX_PACKET_SIZE)
289 {
290 maxPacketSize = USB_DEVICE_MAX_FS_ISO_MAX_PACKET_SIZE;
291 }
292 }
293 else
294 {
295 if (maxPacketSize > USB_DEVICE_MAX_FS_NONE_ISO_MAX_PACKET_SIZE)
296 {
297 maxPacketSize = USB_DEVICE_MAX_FS_NONE_ISO_MAX_PACKET_SIZE;
298 }
299 /* Enable an endpoint to perform handshaking during a transaction to this endpoint. */
300 khciState->registerBase->ENDPOINT[endpoint].ENDPT |= USB_ENDPT_EPHSHK_MASK;
301 }
302 /* Set the endpoint idle */
303 khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
304 /* Save the max packet size of the endpoint */
305 khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize = maxPacketSize;
306 /* Set the data toggle to DATA0 */
307 khciState->endpointState[index].stateUnion.stateBitField.data0 = 0U;
308 /* Clear the endpoint stalled state */
309 khciState->endpointState[index].stateUnion.stateBitField.stalled = 0U;
310 /* Set the ZLT field */
311 khciState->endpointState[index].stateUnion.stateBitField.zlt = epInit->zlt;
312 /* Enable the endpoint. */
313 khciState->registerBase->ENDPOINT[endpoint].ENDPT |=
314 (USB_IN == direction) ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK;
315 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_LOW) && (FSL_FEATURE_USB_KHCI_HAS_STALL_LOW > 0U)
316 /*control endpoint bidirection stall default state should be enable, iso doesn't support stall*/
317 if ((USB_ENDPOINT_BULK == epInit->transferType) || (USB_ENDPOINT_INTERRUPT == epInit->transferType))
318 {
319 if (USB_IN == direction)
320 {
321 if (endpoint < 8U)
322 {
323 khciState->registerBase->STALL_IL_DIS |= (uint8_t)(1UL << endpoint);
324 }
325 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH) && (FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH > 0U)
326 else if ((endpoint >= 8U) && (endpoint < 16U))
327 {
328 khciState->registerBase->STALL_IH_DIS |= (uint8_t)(1UL << (endpoint - 8U));
329 }
330 #endif
331 else
332 {
333 /*no action*/
334 }
335 }
336 else
337 {
338 if (endpoint < 8U)
339 {
340 khciState->registerBase->STALL_OL_DIS |= (uint8_t)(1UL << endpoint);
341 }
342 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH) && (FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH > 0U)
343 else if ((endpoint >= 8U) && (endpoint < 16U))
344 {
345 khciState->registerBase->STALL_OH_DIS |= (uint8_t)(1UL << (endpoint - 8U));
346 }
347 #endif
348 else
349 {
350 /*no action*/
351 }
352 }
353 }
354 else if ((USB_ENDPOINT_CONTROL == epInit->transferType))
355 {
356 khciState->registerBase->STALL_IL_DIS &= (uint8_t)(~(1UL << endpoint));
357 khciState->registerBase->STALL_OL_DIS &= (uint8_t)(~(1UL << endpoint));
358 }
359 else
360 {
361 /*no action*/
362 }
363 #endif
364
365 /* Prime a transfer to receive next setup packet when the endpoint is control out endpoint. */
366 if ((USB_CONTROL_ENDPOINT == endpoint) && (USB_OUT == direction))
367 {
368 USB_DeviceKhciPrimeNextSetup(khciState);
369 }
370
371 return kStatus_USB_Success;
372 }
373
374 /*!
375 * @brief De-initialize a specified endpoint.
376 *
377 * The function is used to de-initialize a specified endpoint.
378 * Current transfer of the endpoint will be canceled and the specified endpoint will be disabled.
379 *
380 * @param khciState Pointer of the device KHCI state structure.
381 * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
382 *
383 * @return A USB error code or kStatus_USB_Success.
384 */
USB_DeviceKhciEndpointDeinit(usb_device_khci_state_struct_t * khciState,uint8_t ep)385 static usb_status_t USB_DeviceKhciEndpointDeinit(usb_device_khci_state_struct_t *khciState, uint8_t ep)
386 {
387 uint8_t endpoint = (ep & USB_ENDPOINT_NUMBER_MASK);
388 uint8_t direction =
389 (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
390 uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
391
392 /* Cancel the transfer of the endpoint */
393 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
394 if (kStatus_USB_Success != USB_DeviceKhciCancel(khciState, ep))
395 {
396 return kStatus_USB_Error;
397 }
398 #else
399 (void)USB_DeviceKhciCancel(khciState, ep);
400 #endif
401
402 /* Disable the endpoint */
403 khciState->registerBase->ENDPOINT[endpoint].ENDPT = 0x00U;
404 /* Clear the max packet size */
405 khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize = 0U;
406
407 return kStatus_USB_Success;
408 }
409
410 /*!
411 * @brief Stall a specified endpoint.
412 *
413 * The function is used to stall a specified endpoint.
414 * Current transfer of the endpoint will be canceled and the specified endpoint will be stalled.
415 *
416 * @param khciState Pointer of the device KHCI state structure.
417 * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
418 *
419 * @return A USB error code or kStatus_USB_Success.
420 */
USB_DeviceKhciEndpointStall(usb_device_khci_state_struct_t * khciState,uint8_t ep)421 static usb_status_t USB_DeviceKhciEndpointStall(usb_device_khci_state_struct_t *khciState, uint8_t ep)
422 {
423 uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK;
424 uint8_t direction =
425 (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
426 uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
427 OSA_SR_ALLOC();
428
429 if (USB_CONTROL_ENDPOINT == endpoint)
430 {
431 /* Cancel the transfer of the endpoint */
432 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
433 if ((kStatus_USB_Success != USB_DeviceKhciCancel(khciState, 0x00)) ||
434 (kStatus_USB_Success != USB_DeviceKhciCancel(khciState, 0x80)))
435 {
436 return kStatus_USB_Error;
437 }
438 #else
439 (void)USB_DeviceKhciCancel(khciState, 0x00);
440 (void)USB_DeviceKhciCancel(khciState, 0x80);
441 #endif
442 /* Set endpoint stall flag. */
443 khciState->endpointState[0].stateUnion.stateBitField.stalled = 1U;
444 khciState->endpointState[1].stateUnion.stateBitField.stalled = 1U;
445 /* Enter critical */
446 OSA_ENTER_CRITICAL();
447 /* Set endpoint stall in BDT. And then if the host send a IN/OUT tansaction, the device will response a STALL
448 * state. */
449 USB_KHCI_BDT_SET_CONTROL(
450 (uint32_t)khciState->bdt, endpoint, 0, khciState->endpointState[0].stateUnion.stateBitField.bdtOdd,
451 USB_LONG_TO_LITTLE_ENDIAN(
452 (uint32_t)(USB_KHCI_BDT_BC(khciState->endpointState[0].stateUnion.stateBitField.maxPacketSize) |
453 USB_KHCI_BDT_DTS | USB_KHCI_BDT_STALL | USB_KHCI_BDT_OWN)));
454 /* Set endpoint stall in BDT. And then if the host send a IN/OUT tansaction, the device will response a STALL
455 * state. */
456 USB_KHCI_BDT_SET_CONTROL(
457 (uint32_t)khciState->bdt, endpoint, 1, khciState->endpointState[1].stateUnion.stateBitField.bdtOdd,
458 USB_LONG_TO_LITTLE_ENDIAN(
459 (uint32_t)(USB_KHCI_BDT_BC(khciState->endpointState[1].stateUnion.stateBitField.maxPacketSize) |
460 USB_KHCI_BDT_DTS | USB_KHCI_BDT_STALL | USB_KHCI_BDT_OWN)));
461 /* Exit critical */
462 OSA_EXIT_CRITICAL();
463 }
464 else
465 {
466 /* Cancel the transfer of the endpoint */
467 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
468 if (kStatus_USB_Success != USB_DeviceKhciCancel(khciState, ep))
469 {
470 return kStatus_USB_Error;
471 }
472 #else
473 (void)USB_DeviceKhciCancel(khciState, ep);
474 #endif
475
476 /* Set endpoint stall flag. */
477 khciState->endpointState[index].stateUnion.stateBitField.stalled = 1U;
478 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_LOW) && (FSL_FEATURE_USB_KHCI_HAS_STALL_LOW > 0U)
479 if (USB_CONTROL_ENDPOINT != endpoint)
480 {
481 if (USB_IN == direction)
482 {
483 /*endpoint is between 1 and 15*/
484 if (endpoint < 8U)
485 {
486 khciState->registerBase->STALL_IL_DIS &= (uint8_t)(~(1UL << endpoint));
487 }
488 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH) && (FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH > 0U)
489 else if (endpoint >= 8U)
490 {
491 khciState->registerBase->STALL_IH_DIS &= (uint8_t)(~(1UL << (endpoint - 8U)));
492 }
493 #endif
494 else
495 {
496 /*no action*/
497 }
498 }
499 else
500 {
501 if (endpoint < 8U)
502 {
503 khciState->registerBase->STALL_OL_DIS &= (uint8_t)(~(1UL << endpoint));
504 }
505 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH) && (FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH > 0U)
506 else if (endpoint >= 8U)
507 {
508 khciState->registerBase->STALL_OH_DIS &= (uint8_t)(~(1UL << (endpoint - 8U)));
509 }
510 #endif
511 else
512 {
513 /*no action*/
514 }
515 }
516 }
517 #endif
518 /* Set endpoint stall in BDT. And then if the host send a IN/OUT tansaction, the device will response a STALL
519 * state.
520 */
521 USB_KHCI_BDT_SET_CONTROL(
522 (uint32_t)khciState->bdt, endpoint, direction,
523 khciState->endpointState[index].stateUnion.stateBitField.bdtOdd,
524 USB_LONG_TO_LITTLE_ENDIAN(
525 (uint32_t)(USB_KHCI_BDT_BC(khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize) |
526 USB_KHCI_BDT_DTS | USB_KHCI_BDT_STALL | USB_KHCI_BDT_OWN)));
527 }
528
529 khciState->registerBase->CTL &= (uint8_t)(~USB_CTL_TXSUSPENDTOKENBUSY_MASK);
530
531 return kStatus_USB_Success;
532 }
533
534 /*!
535 * @brief Un-stall a specified endpoint.
536 *
537 * The function is used to un-stall a specified endpoint.
538 * Current transfer of the endpoint will be canceled and the specified endpoint will be un-stalled.
539 *
540 * @param khciState Pointer of the device KHCI state structure.
541 * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
542 *
543 * @return A USB error code or kStatus_USB_Success.
544 */
USB_DeviceKhciEndpointUnstall(usb_device_khci_state_struct_t * khciState,uint8_t ep)545 static usb_status_t USB_DeviceKhciEndpointUnstall(usb_device_khci_state_struct_t *khciState, uint8_t ep)
546 {
547 uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK;
548 uint8_t direction =
549 (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
550 uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
551 uint8_t i;
552
553 /* Clear the endpoint stall state */
554 khciState->endpointState[index].stateUnion.stateBitField.stalled = 0U;
555 /* Reset the endpoint data toggle to DATA0 */
556 khciState->endpointState[index].stateUnion.stateBitField.data0 = 0U;
557
558 /* Clear stall state in BDT */
559 for (i = 0U; i < 2U; i++)
560 {
561 USB_KHCI_BDT_SET_CONTROL(
562 (uint32_t)khciState->bdt, endpoint, direction, i,
563 USB_LONG_TO_LITTLE_ENDIAN(
564 (uint32_t)(USB_KHCI_BDT_BC(khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize) |
565 USB_KHCI_BDT_DTS | USB_KHCI_BDT_DATA01(0U))));
566 }
567
568 /* Clear stall state in endpoint control register */
569 khciState->registerBase->ENDPOINT[endpoint].ENDPT &= (uint8_t)(~USB_ENDPT_EPSTALL_MASK);
570 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_LOW) && (FSL_FEATURE_USB_KHCI_HAS_STALL_LOW > 0U)
571 if (USB_CONTROL_ENDPOINT != endpoint)
572 {
573 if (USB_IN == direction)
574 {
575 if (endpoint < 8U)
576 {
577 khciState->registerBase->STALL_IL_DIS |= (uint8_t)(1UL << endpoint);
578 }
579 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH) && (FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH > 0U)
580 else if (endpoint >= 8U)
581 {
582 khciState->registerBase->STALL_IH_DIS |= (uint8_t)(1UL << (endpoint - 8U));
583 }
584 #endif
585 else
586 {
587 /*no action*/
588 }
589 }
590 else
591 {
592 if (endpoint < 8U)
593 {
594 khciState->registerBase->STALL_OL_DIS |= (uint8_t)(1UL << endpoint);
595 }
596 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH) && (FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH > 0U)
597 else if (endpoint >= 8U)
598 {
599 khciState->registerBase->STALL_OH_DIS |= (uint8_t)(1UL << (endpoint - 8U));
600 }
601 #endif
602 else
603 {
604 /*no action*/
605 }
606 }
607 }
608 #endif
609 if ((USB_CONTROL_ENDPOINT != endpoint))
610 {
611 /* Cancel the transfer of the endpoint */
612 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
613 if (kStatus_USB_Success != USB_DeviceKhciCancel(khciState, ep))
614 {
615 return kStatus_USB_Error;
616 }
617 #else
618 (void)USB_DeviceKhciCancel(khciState, ep);
619 #endif
620 }
621
622 /* Prime a transfer to receive next setup packet when the endpoint is a control out endpoint. */
623 if ((USB_CONTROL_ENDPOINT == endpoint) && (USB_OUT == direction))
624 {
625 USB_DeviceKhciPrimeNextSetup(khciState);
626 }
627
628 khciState->registerBase->CTL &= (uint8_t)(~USB_CTL_TXSUSPENDTOKENBUSY_MASK);
629
630 return kStatus_USB_Success;
631 }
632
633 /*!
634 * @brief Handle the token done interrupt.
635 *
636 * The function is used to handle the token done interrupt.
637 *
638 * @param khciState Pointer of the device KHCI state structure.
639 *
640 */
USB_DeviceKhciInterruptTokenDone(usb_device_khci_state_struct_t * khciState)641 static void USB_DeviceKhciInterruptTokenDone(usb_device_khci_state_struct_t *khciState)
642 {
643 uint32_t control;
644 uint32_t length;
645 uint32_t remainingLength;
646 uint8_t *bdtBuffer;
647 void *temp;
648 usb_device_callback_message_struct_t message;
649 uint8_t endpoint;
650 uint8_t direction;
651 uint8_t bdtOdd;
652 uint8_t isSetup;
653 uint8_t index;
654 uint8_t stateRegister = khciState->registerBase->STAT;
655
656 /* Get the endpoint number to identify which one triggers the token done interrupt. */
657 endpoint = (stateRegister & USB_STAT_ENDP_MASK) >> USB_STAT_ENDP_SHIFT;
658
659 /* Get the direction of the endpoint number. */
660 direction = (stateRegister & USB_STAT_TX_MASK) >> USB_STAT_TX_SHIFT;
661
662 /* Get the finished BDT ODD. */
663 bdtOdd = (stateRegister & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT;
664
665 /* Clear token done interrupt flag. */
666 khciState->registerBase->ISTAT = USB_INTEN_TOKDNEEN_MASK;
667
668 /* Get the Control field of the BDT element according to the endpoint number, the direction and finished BDT ODD. */
669 control = USB_KHCI_BDT_GET_CONTROL((uint32_t)khciState->bdt, endpoint, direction, bdtOdd);
670
671 /* Get the buffer field of the BDT element according to the endpoint number, the direction and finished BDT ODD. */
672 bdtBuffer = (uint8_t *)USB_KHCI_BDT_GET_ADDRESS((uint32_t)khciState->bdt, endpoint, direction, bdtOdd);
673
674 /* Get the transferred length. */
675 length = ((USB_LONG_FROM_LITTLE_ENDIAN(control)) >> 16U) & 0x3FFU;
676
677 /* Get the transferred length. */
678 isSetup = (USB_KHCI_BDT_DEVICE_SETUP_TOKEN == ((uint8_t)(((USB_LONG_FROM_LITTLE_ENDIAN(control)) >> 2U) & 0x0FU))) ?
679 1U :
680 0U;
681
682 index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
683
684 if (0U == khciState->endpointState[index].stateUnion.stateBitField.transferring)
685 {
686 return;
687 }
688
689 if (0U != isSetup)
690 {
691 khciState->setupBufferIndex = bdtOdd;
692 }
693
694 /* USB_IN, Send completed */
695 if (direction == USB_IN)
696 {
697 /* The transferred length */
698 khciState->endpointState[index].transferDone += length;
699
700 /* Remaining length */
701 remainingLength = khciState->endpointState[index].transferLength - khciState->endpointState[index].transferDone;
702
703 /* Change the data toggle flag */
704 khciState->endpointState[index].stateUnion.stateBitField.data0 ^= 1U;
705 /* Change the BDT odd toggle flag */
706 khciState->endpointState[index].stateUnion.stateBitField.bdtOdd ^= 1U;
707
708 /* Whether the transfer is completed or not. */
709 /*
710 * The transfer is completed when one of the following conditions meet:
711 * 1. The remaining length is zero.
712 * 2. The length of current tansaction is less than the max packet size of the current pipe.
713 */
714 if ((0U == remainingLength) ||
715 (khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize > length))
716 {
717 message.length = khciState->endpointState[index].transferDone;
718 message.buffer = khciState->endpointState[index].transferBuffer;
719 khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
720
721 /*
722 * Whether need to send ZLT when the pipe is control in pipe and the transferred length of current
723 * transaction equals to max packet size.
724 */
725 if ((0U != length) &&
726 (0U == (length % khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize)))
727 {
728 if (USB_CONTROL_ENDPOINT == endpoint)
729 {
730 temp =
731 (void *)(&khciState->setupPacketBuffer[(USB_SETUP_PACKET_SIZE * khciState->setupBufferIndex)]);
732 usb_setup_struct_t *setup_packet = (usb_setup_struct_t *)temp;
733 /*
734 * Send the ZLT and terminate the token done interrupt service when the transferred length in data
735 * phase
736 * is less than the host request.
737 */
738 if (USB_SHORT_FROM_LITTLE_ENDIAN(setup_packet->wLength) >
739 khciState->endpointState[index].transferLength)
740 {
741 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
742 if (kStatus_USB_Success !=
743 USB_DeviceKhciEndpointTransfer(khciState, endpoint, USB_IN, (uint8_t *)NULL, 0U))
744 {
745 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
746 usb_echo("prime error\r\n");
747 #endif
748 }
749 #else
750 (void)USB_DeviceKhciEndpointTransfer(khciState, endpoint, USB_IN, (uint8_t *)NULL, 0U);
751 #endif
752 return;
753 }
754 }
755 else if (0U != khciState->endpointState[index].stateUnion.stateBitField.zlt)
756 {
757 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
758 if (kStatus_USB_Success !=
759 USB_DeviceKhciEndpointTransfer(khciState, endpoint, USB_IN, (uint8_t *)NULL, 0U))
760 {
761 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
762 usb_echo("start transfer error\r\n");
763 #endif
764 }
765 #else
766 (void)USB_DeviceKhciEndpointTransfer(khciState, endpoint, USB_IN, (uint8_t *)NULL, 0U);
767 #endif
768 return;
769 }
770 else
771 {
772 }
773 }
774 }
775 else
776 {
777 /* Send remaining data and terminate the token done interrupt service. */
778 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
779 if (kStatus_USB_Success != USB_DeviceKhciSend(khciState, endpoint | (USB_IN << 0x07U),
780 khciState->endpointState[index].transferBuffer,
781 remainingLength))
782 {
783 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
784 usb_echo("send error\r\n");
785 #endif
786 }
787 #else
788 (void)USB_DeviceKhciSend(khciState, endpoint | (USB_IN << 0x07U),
789 khciState->endpointState[index].transferBuffer, remainingLength);
790 #endif
791 return;
792 }
793 }
794 else
795 {
796 if ((USB_CONTROL_ENDPOINT == endpoint) && (0U == length))
797 {
798 message.length = 0U;
799 message.buffer = (uint8_t *)NULL;
800 }
801 else
802 {
803 if (0U == khciState->endpointState[index].stateUnion.stateBitField.dmaAlign)
804 {
805 uint8_t *buffer = (uint8_t *)USB_LONG_FROM_LITTLE_ENDIAN(
806 USB_KHCI_BDT_GET_ADDRESS((uint32_t)khciState->bdt, endpoint, USB_OUT,
807 khciState->endpointState[index].stateUnion.stateBitField.bdtOdd));
808 uint8_t *transferBuffer =
809 khciState->endpointState[index].transferBuffer + khciState->endpointState[index].transferDone;
810 if (buffer != transferBuffer)
811 {
812 (void)memcpy(transferBuffer, buffer, length);
813 }
814 khciState->isDmaAlignBufferInusing = 0U;
815 }
816 /* The transferred length */
817 khciState->endpointState[index].transferDone += length;
818 /* Remaining length */
819 remainingLength =
820 khciState->endpointState[index].transferLength - khciState->endpointState[index].transferDone;
821
822 if ((USB_CONTROL_ENDPOINT == endpoint) && (0U != isSetup))
823 {
824 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.data0 = 1U;
825 khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_IN].stateUnion.stateBitField.data0 = 1U;
826 }
827 else
828 {
829 khciState->endpointState[index].stateUnion.stateBitField.data0 ^= 1U;
830 }
831 khciState->endpointState[index].stateUnion.stateBitField.bdtOdd ^= 1U;
832 if ((0U == khciState->endpointState[index].transferLength) || (0U == remainingLength) ||
833 (khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize > length))
834 {
835 message.length = khciState->endpointState[index].transferDone;
836 if (0U != isSetup)
837 {
838 message.buffer = bdtBuffer;
839 }
840 else
841 {
842 message.buffer = khciState->endpointState[index].transferBuffer;
843 }
844 khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
845 }
846 else
847 {
848 /* Receive remaining data and terminate the token done interrupt service. */
849 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
850 if (kStatus_USB_Success != USB_DeviceKhciRecv(khciState, (endpoint) | (USB_OUT << 0x07U),
851 khciState->endpointState[index].transferBuffer,
852 remainingLength))
853 {
854 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
855 usb_echo("recv error\r\n");
856 #endif
857 }
858 #else
859 (void)USB_DeviceKhciRecv(khciState, (endpoint) | (USB_OUT << 0x07U),
860 khciState->endpointState[index].transferBuffer, remainingLength);
861 #endif
862 return;
863 }
864 }
865 }
866
867 message.isSetup = isSetup;
868 message.code = (endpoint) | (uint8_t)(((uint32_t)direction << 0x07U));
869
870 /* Notify the up layer the KHCI status changed. */
871 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
872 if (kStatus_USB_Success != USB_DeviceNotificationTrigger(khciState->deviceHandle, &message))
873 {
874 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
875 usb_echo("notification error\n");
876 #endif
877 }
878 #else
879 (void)USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
880 #endif
881
882 khciState->registerBase->CTL &= (uint8_t)(~USB_CTL_TXSUSPENDTOKENBUSY_MASK);
883 }
884
885 /*!
886 * @brief Handle the USB bus reset interrupt.
887 *
888 * The function is used to handle the USB bus reset interrupt.
889 *
890 * @param khciState Pointer of the device KHCI state structure.
891 *
892 */
USB_DeviceKhciInterruptReset(usb_device_khci_state_struct_t * khciState)893 static void USB_DeviceKhciInterruptReset(usb_device_khci_state_struct_t *khciState)
894 {
895 usb_device_callback_message_struct_t message;
896
897 /* Set KHCI reset flag */
898 khciState->isResetting = 1U;
899
900 /* Clear the reset interrupt */
901 khciState->registerBase->ISTAT = (USB_INTEN_USBRSTEN_MASK);
902 #if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
903 /* Clear the suspend interrupt */
904 khciState->registerBase->ISTAT = (USB_INTEN_SLEEPEN_MASK);
905 khciState->registerBase->USBCTRL &= (uint8_t)(~USB_USBCTRL_SUSP_MASK);
906 #endif
907
908 message.buffer = (uint8_t *)NULL;
909 message.code = (uint8_t)kUSB_DeviceNotifyBusReset;
910 message.length = 0U;
911 message.isSetup = 0U;
912 /* Notify up layer the USB bus reset signal detected. */
913 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
914 if (kStatus_USB_Success != USB_DeviceNotificationTrigger(khciState->deviceHandle, &message))
915 {
916 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
917 usb_echo("notification error\n");
918 #endif
919 }
920 #else
921 (void)USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
922 #endif
923 }
924
925 /* The USB suspend and resume signals need to be detected and handled when the low power or remote wakeup function
926 * enabled. */
927 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
928
929 /*!
930 * @brief Handle the suspend interrupt.
931 *
932 * The function is used to handle the suspend interrupt when the suspend signal detected.
933 *
934 * @param khciState Pointer of the device KHCI state structure.
935 *
936 */
USB_DeviceKhciInterruptSleep(usb_device_khci_state_struct_t * khciState)937 static void USB_DeviceKhciInterruptSleep(usb_device_khci_state_struct_t *khciState)
938 {
939 usb_device_callback_message_struct_t message;
940
941 /* Enable the resume interrupt */
942 khciState->registerBase->INTEN |= USB_INTEN_RESUMEEN_MASK;
943 khciState->registerBase->USBTRC0 |= USB_USBTRC0_USBRESMEN_MASK;
944 khciState->registerBase->USBCTRL |= USB_USBCTRL_SUSP_MASK;
945 /* Disable the suspend interrupt */
946 khciState->registerBase->INTEN &= (uint8_t)(~(USB_INTEN_SLEEPEN_MASK));
947
948 /* Clear the suspend interrupt */
949 khciState->registerBase->ISTAT = (USB_INTEN_SLEEPEN_MASK);
950 /* Clear the resume interrupt */
951 khciState->registerBase->ISTAT = (USB_INTEN_RESUMEEN_MASK);
952
953 message.buffer = (uint8_t *)NULL;
954 message.code = (uint8_t)kUSB_DeviceNotifySuspend;
955 message.length = 0U;
956 message.isSetup = 0U;
957
958 /* Notify up layer the USB suspend signal detected. */
959 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
960 if (kStatus_USB_Success != USB_DeviceNotificationTrigger(khciState->deviceHandle, &message))
961 {
962 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
963 usb_echo("notification error\n");
964 #endif
965 }
966 #else
967 (void)USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
968 #endif
969 }
970
971 /*!
972 * @brief Handle the resume interrupt.
973 *
974 * The function is used to handle the resume interrupt when the resume signal detected.
975 *
976 * @param khciState Pointer of the device KHCI state structure.
977 *
978 */
USB_DeviceKhciInterruptResume(usb_device_khci_state_struct_t * khciState)979 static void USB_DeviceKhciInterruptResume(usb_device_khci_state_struct_t *khciState)
980 {
981 usb_device_callback_message_struct_t message;
982
983 khciState->registerBase->USBCTRL &= (uint8_t)(~USB_USBCTRL_SUSP_MASK);
984 /* Enable the suspend interrupt */
985 khciState->registerBase->INTEN |= USB_INTEN_SLEEPEN_MASK;
986 /* Disable the resume interrupt */
987 khciState->registerBase->INTEN &= (uint8_t)(~(USB_INTEN_RESUMEEN_MASK));
988 khciState->registerBase->USBTRC0 &= (uint8_t)(~USB_USBTRC0_USBRESMEN_MASK);
989
990 /* Clear the resume interrupt */
991 khciState->registerBase->ISTAT = (USB_INTEN_RESUMEEN_MASK);
992 /* Clear the suspend interrupt */
993 khciState->registerBase->ISTAT = (USB_INTEN_SLEEPEN_MASK);
994
995 message.buffer = (uint8_t *)NULL;
996 message.code = (uint8_t)kUSB_DeviceNotifyResume;
997 message.length = 0U;
998 message.isSetup = 0U;
999
1000 /* Notify up layer the USB resume signal detected. */
1001 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1002 if (kStatus_USB_Success != USB_DeviceNotificationTrigger(khciState->deviceHandle, &message))
1003 {
1004 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
1005 usb_echo("notification error\n");
1006 #endif
1007 }
1008 #else
1009 (void)USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
1010 #endif
1011 }
1012 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
1013
1014 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
1015 /*!
1016 * @brief Handle the VBUS rising interrupt.
1017 *
1018 * The function is used to handle the VBUS rising interrupt when the VBUS rising signal detected.
1019 *
1020 * @param khciState Pointer of the device KHCI state structure.
1021 *
1022 */
USB_DeviceKhciInterruptVbusRising(usb_device_khci_state_struct_t * khciState)1023 static void USB_DeviceKhciInterruptVbusRising(usb_device_khci_state_struct_t *khciState)
1024 {
1025 usb_device_callback_message_struct_t message;
1026
1027 /* Disable the VBUS rising interrupt */
1028 khciState->registerBase->MISCCTRL &= (uint8_t)(~USB_MISCCTRL_VREDG_EN_MASK);
1029 /* Enable the VBUS rising interrupt */
1030 khciState->registerBase->MISCCTRL |= USB_MISCCTRL_VREDG_EN_MASK;
1031
1032 message.buffer = (uint8_t *)NULL;
1033 message.code = (uint8_t)kUSB_DeviceNotifyAttach;
1034 message.length = 0U;
1035 message.isSetup = 0U;
1036
1037 /* Notify up layer the USB VBUS rising signal detected. */
1038 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1039 if (kStatus_USB_Success != USB_DeviceNotificationTrigger(khciState->deviceHandle, &message))
1040 {
1041 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
1042 usb_echo("notification error\n");
1043 #endif
1044 }
1045 #else
1046 (void)USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
1047 #endif
1048 }
1049
1050 /*!
1051 * @brief Handle the VBUS falling interrupt.
1052 *
1053 * The function is used to handle the VBUS falling interrupt when the VBUS falling signal detected.
1054 *
1055 * @param khciState Pointer of the device KHCI state structure.
1056 *
1057 */
USB_DeviceKhciInterruptVbusFalling(usb_device_khci_state_struct_t * khciState)1058 static void USB_DeviceKhciInterruptVbusFalling(usb_device_khci_state_struct_t *khciState)
1059 {
1060 usb_device_callback_message_struct_t message;
1061
1062 /* Disable the VBUS rising interrupt */
1063 khciState->registerBase->MISCCTRL &= (uint8_t)(~USB_MISCCTRL_VFEDG_EN_MASK);
1064 /* Enable the VBUS rising interrupt */
1065 khciState->registerBase->MISCCTRL |= USB_MISCCTRL_VFEDG_EN_MASK;
1066
1067 message.buffer = (uint8_t *)NULL;
1068 message.code = (uint8_t)kUSB_DeviceNotifyDetach;
1069 message.length = 0U;
1070 message.isSetup = 0U;
1071
1072 /* Notify up layer the USB VBUS falling signal detected. */
1073 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1074 if (kStatus_USB_Success != USB_DeviceNotificationTrigger(khciState->deviceHandle, &message))
1075 {
1076 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
1077 usb_echo("notification error\n");
1078 #endif
1079 }
1080 #else
1081 (void)USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
1082 #endif
1083 }
1084 #endif /* USB_DEVICE_CONFIG_DETACH_ENABLE || FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED */
1085
1086 #if (defined(USB_DEVICE_CONFIG_SOF_NOTIFICATIONS) && (USB_DEVICE_CONFIG_SOF_NOTIFICATIONS > 0U))
1087 /*!
1088 * @brief Handle Start of Frame (SOF) Interrupt.
1089 *
1090 * The function is used to handle the sof interrupt.
1091 *
1092 * @param khciState Pointer of the device KHCI state structure.
1093 *
1094 */
USB_DeviceKhciInterruptSOF(usb_device_khci_state_struct_t * khciState)1095 static void USB_DeviceKhciInterruptSOF(usb_device_khci_state_struct_t *khciState)
1096 {
1097 usb_device_callback_message_struct_t message;
1098
1099 khciState->registerBase->ISTAT = (USB_INTEN_SOFTOKEN_MASK);
1100 khciState->registerBase->ISTAT = (USB_INTEN_RESUMEEN_MASK);
1101
1102 message.buffer = (uint8_t *)NULL;
1103 message.code = (uint8_t)kUSB_DeviceNotifySOF;
1104 message.length = 0U;
1105 message.isSetup = 0U;
1106
1107 /* Notify upper layer */
1108 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1109 if (kStatus_USB_Success != USB_DeviceNotificationTrigger(khciState->deviceHandle, &message))
1110 {
1111 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
1112 usb_echo("notification error\n");
1113 #endif
1114 }
1115 #else
1116 (void)USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
1117 #endif
1118 }
1119 #endif /* USB_DEVICE_CONFIG_SOF_NOTIFICATIONS */
1120
1121 /*!
1122 * @brief Handle endpoint stalled interrupt.
1123 *
1124 * The function is used to handle endpoint stalled interrupt.
1125 *
1126 * @param khciState Pointer of the device KHCI state structure.
1127 *
1128 */
USB_DeviceKhciInterruptStall(usb_device_khci_state_struct_t * khciState)1129 static void USB_DeviceKhciInterruptStall(usb_device_khci_state_struct_t *khciState)
1130 {
1131 /* Clear the endpoint stalled interrupt flag */
1132 while (0U != (khciState->registerBase->ISTAT & (USB_INTEN_STALLEN_MASK)))
1133 {
1134 khciState->registerBase->ISTAT = (USB_INTEN_STALLEN_MASK);
1135 }
1136
1137 /* Un-stall the control in and out pipe when the control in or out pipe stalled. */
1138 if ((0U != khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_IN].stateUnion.stateBitField.stalled) ||
1139 (0U != khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.stalled))
1140 {
1141 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1142 if ((kStatus_USB_Success !=
1143 USB_DeviceKhciEndpointUnstall(
1144 khciState, (USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)))) ||
1145 (kStatus_USB_Success !=
1146 USB_DeviceKhciEndpointUnstall(
1147 khciState, (USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)))))
1148 {
1149 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
1150 usb_echo("unstall endpoint error\n");
1151 #endif
1152 }
1153 #else
1154 (void)USB_DeviceKhciEndpointUnstall(
1155 khciState, (USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)));
1156 (void)USB_DeviceKhciEndpointUnstall(
1157 khciState, (USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)));
1158 #endif
1159 }
1160 }
1161
1162 #if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)
USB_DeviceKhciInterruptError(usb_device_khci_state_struct_t * khciState)1163 static void USB_DeviceKhciInterruptError(usb_device_khci_state_struct_t *khciState)
1164 {
1165 usb_device_callback_message_struct_t message;
1166
1167 khciState->registerBase->ISTAT = (USB_INTEN_ERROREN_MASK);
1168
1169 message.buffer = (uint8_t *)NULL;
1170 message.code = (uint8_t)kUSB_DeviceNotifyError;
1171 message.length = 0U;
1172 message.isSetup = 0U;
1173
1174 /* Notify up layer the USB error detected. */
1175 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1176 if (kStatus_USB_Success != USB_DeviceNotificationTrigger(khciState->deviceHandle, &message))
1177 {
1178 #if (defined(DEVICE_ECHO) && (DEVICE_ECHO > 0U))
1179 usb_echo("notification error\n");
1180 #endif
1181 }
1182 #else
1183 (void)USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
1184 #endif
1185 }
1186 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
1187
1188 /*!
1189 * @brief Initialize the USB device KHCI instance.
1190 *
1191 * This function initializes the USB device KHCI module specified by the controllerId.
1192 *
1193 * @param controllerId The controller id of the USB IP. Please refer to enumeration type usb_controller_index_t.
1194 * @param handle Pointer of the device handle, used to identify the device object is belonged to.
1195 * @param khciHandle It is out parameter, is used to return pointer of the device KHCI handle to the caller.
1196 *
1197 * @return A USB error code or kStatus_USB_Success.
1198 */
USB_DeviceKhciInit(uint8_t controllerId,usb_device_handle handle,usb_device_controller_handle * khciHandle)1199 usb_status_t USB_DeviceKhciInit(uint8_t controllerId,
1200 usb_device_handle handle,
1201 usb_device_controller_handle *khciHandle)
1202 {
1203 usb_device_khci_state_struct_t *khciState;
1204 uint32_t khci_base[] = USB_BASE_ADDRS;
1205
1206 if (((controllerId - (uint8_t)kUSB_ControllerKhci0) >= (uint8_t)USB_DEVICE_CONFIG_KHCI) ||
1207 ((controllerId - (uint8_t)kUSB_ControllerKhci0) >= (sizeof(khci_base) / sizeof(uint32_t))))
1208 {
1209 return kStatus_USB_ControllerNotFound;
1210 }
1211 khciState = &s_UsbDeviceKhciState[controllerId - (uint8_t)kUSB_ControllerKhci0];
1212
1213 khciState->controllerId = controllerId;
1214
1215 khciState->registerBase = (USB_Type *)khci_base[controllerId - (uint8_t)kUSB_ControllerKhci0];
1216
1217 khciState->dmaAlignBuffer =
1218 (uint8_t *)&s_UsbDeviceKhciDmaAlignBuffer[controllerId - (uint8_t)kUSB_ControllerKhci0][0];
1219
1220 /* Clear all interrupt flags. */
1221 khciState->registerBase->ISTAT = 0xFFU;
1222
1223 #if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
1224 khciState->otgStatus = 0U;
1225 #else
1226 /* Disable the device functionality. */
1227 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1228 if (kStatus_USB_Success != USB_DeviceKhciControl(khciState, kUSB_DeviceControlStop, NULL))
1229 {
1230 return kStatus_USB_Error;
1231 }
1232 #else
1233 (void)USB_DeviceKhciControl(khciState, kUSB_DeviceControlStop, NULL);
1234 #endif
1235 #endif
1236
1237 #if defined(__DSC__) || defined(__CW__)
1238 khciState->bdt = (uint8_t *)s_UsbDeviceKhciBdtBuffer[controllerId - (uint8_t)kUSB_ControllerKhci0];
1239 #else
1240 khciState->bdt = s_UsbDeviceKhciBdtBuffer[controllerId - (uint8_t)kUSB_ControllerKhci0];
1241 #endif
1242
1243 /* Set BDT buffer address */
1244 khciState->registerBase->BDTPAGE1 = (uint8_t)((((uint32_t)khciState->bdt) >> 8U) & 0xFFU);
1245 khciState->registerBase->BDTPAGE2 = (uint8_t)((((uint32_t)khciState->bdt) >> 16U) & 0xFFU);
1246 khciState->registerBase->BDTPAGE3 = (uint8_t)((((uint32_t)khciState->bdt) >> 24U) & 0xFFU);
1247
1248 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
1249 khciState->registerBase->MISCCTRL |= USB_MISCCTRL_VREDG_EN_MASK | USB_MISCCTRL_VFEDG_EN_MASK;
1250 #endif
1251
1252 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
1253 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
1254 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
1255 khciState->registerBase->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK;
1256 khciState->registerBase->KEEP_ALIVE_CTRL =
1257 USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_EN_MASK | USB_KEEP_ALIVE_CTRL_OWN_OVERRD_EN_MASK |
1258 USB_KEEP_ALIVE_CTRL_WAKE_INT_EN_MASK | FSL_FEATURE_USB_KHCI_KEEP_ALIVE_MODE_CONTROL;
1259 /* wake on out and setup transaction */
1260 khciState->registerBase->KEEP_ALIVE_WKCTRL = 0x1U;
1261 #if defined(FSL_FEATURE_SOC_MCGLITE_COUNT) && (FSL_FEATURE_SOC_MCGLITE_COUNT > 0U)
1262 MCG->MC |= MCG_MC_HIRCLPEN_MASK;
1263 #endif
1264
1265 #endif
1266 #if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_LOW) && (FSL_FEATURE_USB_KHCI_HAS_STALL_LOW > 0U)
1267 khciState->registerBase->MISCCTRL |= USB_MISCCTRL_STL_ADJ_EN_MASK;
1268 #endif
1269
1270 /* Set KHCI device state to default value. */
1271 USB_DeviceKhciSetDefaultState(khciState);
1272
1273 *khciHandle = khciState;
1274 khciState->deviceHandle = (usb_device_struct_t *)handle;
1275
1276 return kStatus_USB_Success;
1277 }
1278
1279 /*!
1280 * @brief De-initialize the USB device KHCI instance.
1281 *
1282 * This function de-initializes the USB device KHCI module.
1283 *
1284 * @param khciHandle Pointer of the device KHCI handle.
1285 *
1286 * @return A USB error code or kStatus_USB_Success.
1287 */
USB_DeviceKhciDeinit(usb_device_controller_handle khciHandle)1288 usb_status_t USB_DeviceKhciDeinit(usb_device_controller_handle khciHandle)
1289 {
1290 usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
1291
1292 if (NULL == khciHandle)
1293 {
1294 return kStatus_USB_InvalidHandle;
1295 }
1296 /* Clear all interrupt flags. */
1297 khciState->registerBase->ISTAT = 0xFFU;
1298 /* Disable all interrupts. */
1299 khciState->registerBase->INTEN = (0U);
1300 /* Clear device address. */
1301 khciState->registerBase->ADDR = (0U);
1302
1303 /* Clear USB_CTL register */
1304 khciState->registerBase->CTL = 0x00U;
1305 khciState->registerBase->USBCTRL |= USB_USBCTRL_PDE_MASK | USB_USBCTRL_SUSP_MASK;
1306
1307 return kStatus_USB_Success;
1308 }
1309
1310 /*!
1311 * @brief Send data through a specified endpoint.
1312 *
1313 * This function sends data through a specified endpoint.
1314 *
1315 * @param khciHandle Pointer of the device KHCI handle.
1316 * @param endpointAddress Endpoint index.
1317 * @param buffer The memory address to hold the data need to be sent.
1318 * @param length The data length need to be sent.
1319 *
1320 * @return A USB error code or kStatus_USB_Success.
1321 *
1322 * @note The return value just means if the sending request is successful or not; the transfer done is notified by the
1323 * corresponding callback function.
1324 * Currently, only one transfer request can be supported for one specific endpoint.
1325 * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1326 * should implement a queue in the application level.
1327 * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1328 * callback).
1329 */
USB_DeviceKhciSend(usb_device_controller_handle khciHandle,uint8_t endpointAddress,uint8_t * buffer,uint32_t length)1330 usb_status_t USB_DeviceKhciSend(usb_device_controller_handle khciHandle,
1331 uint8_t endpointAddress,
1332 uint8_t *buffer,
1333 uint32_t length)
1334 {
1335 usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
1336 uint32_t index = (((uint32_t)endpointAddress & USB_ENDPOINT_NUMBER_MASK) << 1U) | USB_IN;
1337 usb_status_t status = kStatus_USB_Error;
1338
1339 /* Save the transfer information */
1340 if (0U == khciState->endpointState[index].stateUnion.stateBitField.transferring)
1341 {
1342 khciState->endpointState[index].transferDone = 0U;
1343 khciState->endpointState[index].transferBuffer = buffer;
1344 khciState->endpointState[index].transferLength = length;
1345 khciState->endpointState[index].stateUnion.stateBitField.dmaAlign = 1U;
1346 }
1347
1348 /* Data length needs to less than max packet size in each call. */
1349 if (length > khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize)
1350 {
1351 length = khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize;
1352 }
1353
1354 /* Send data when the device is not resetting. */
1355 if (0U == khciState->isResetting)
1356 {
1357 status = USB_DeviceKhciEndpointTransfer(khciState, endpointAddress & USB_ENDPOINT_NUMBER_MASK, USB_IN,
1358 (uint8_t *)((uint32_t)khciState->endpointState[index].transferBuffer +
1359 (uint32_t)khciState->endpointState[index].transferDone),
1360 length);
1361 }
1362
1363 /* Prime a transfer to receive next setup packet if the dat length is zero in a control in endpoint. */
1364 if ((0U == khciState->endpointState[index].transferDone) && (0U == length) &&
1365 (USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK)))
1366 {
1367 USB_DeviceKhciPrimeNextSetup(khciState);
1368 }
1369 return status;
1370 }
1371
1372 /*!
1373 * @brief Receive data through a specified endpoint.
1374 *
1375 * This function Receives data through a specified endpoint.
1376 *
1377 * @param khciHandle Pointer of the device KHCI handle.
1378 * @param endpointAddress Endpoint index.
1379 * @param buffer The memory address to save the received data.
1380 * @param length The data length want to be received.
1381 *
1382 * @return A USB error code or kStatus_USB_Success.
1383 *
1384 * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the
1385 * corresponding callback function.
1386 * Currently, only one transfer request can be supported for one specific endpoint.
1387 * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1388 * should implement a queue in the application level.
1389 * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1390 * callback).
1391 */
USB_DeviceKhciRecv(usb_device_controller_handle khciHandle,uint8_t endpointAddress,uint8_t * buffer,uint32_t length)1392 usb_status_t USB_DeviceKhciRecv(usb_device_controller_handle khciHandle,
1393 uint8_t endpointAddress,
1394 uint8_t *buffer,
1395 uint32_t length)
1396 {
1397 usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
1398 uint32_t index = (((uint32_t)endpointAddress & USB_ENDPOINT_NUMBER_MASK) << 1U) | USB_OUT;
1399 usb_status_t status = kStatus_USB_Error;
1400
1401 if ((0U == length) && (USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK)))
1402 {
1403 khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
1404 USB_DeviceKhciPrimeNextSetup(khciState);
1405 }
1406 else
1407 {
1408 /* Save the transfer information */
1409 if (0U == khciState->endpointState[index].stateUnion.stateBitField.transferring)
1410 {
1411 khciState->endpointState[index].transferDone = 0U;
1412 khciState->endpointState[index].transferBuffer = buffer;
1413 khciState->endpointState[index].transferLength = length;
1414 }
1415 khciState->endpointState[index].stateUnion.stateBitField.dmaAlign = 1U;
1416
1417 /* Data length needs to less than max packet size in each call. */
1418 if (length > khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize)
1419 {
1420 length = khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize;
1421 }
1422
1423 buffer = (uint8_t *)((uint32_t)buffer + (uint32_t)khciState->endpointState[index].transferDone);
1424
1425 if ((NULL != khciState->dmaAlignBuffer) && (0U == khciState->isDmaAlignBufferInusing) &&
1426 (USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH >= length) &&
1427 ((0U != (length & 0x03U)) || (0U != (((uint32_t)buffer) & 0x03U))))
1428 {
1429 khciState->endpointState[index].stateUnion.stateBitField.dmaAlign = 0U;
1430 buffer = khciState->dmaAlignBuffer;
1431 khciState->isDmaAlignBufferInusing = 1U;
1432 }
1433
1434 /* Receive data when the device is not resetting. */
1435 if (0U == khciState->isResetting)
1436 {
1437 status = USB_DeviceKhciEndpointTransfer(khciState, endpointAddress & USB_ENDPOINT_NUMBER_MASK, USB_OUT,
1438 buffer, length);
1439 }
1440 }
1441 return status;
1442 }
1443
1444 /*!
1445 * @brief Cancel the pending transfer in a specified endpoint.
1446 *
1447 * The function is used to cancel the pending transfer in a specified endpoint.
1448 *
1449 * @param khciHandle Pointer of the device KHCI handle.
1450 * @param ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1451 *
1452 * @return A USB error code or kStatus_USB_Success.
1453 */
USB_DeviceKhciCancel(usb_device_controller_handle khciHandle,uint8_t ep)1454 usb_status_t USB_DeviceKhciCancel(usb_device_controller_handle khciHandle, uint8_t ep)
1455 {
1456 usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
1457 usb_device_callback_message_struct_t message;
1458 uint8_t index = ((ep & USB_ENDPOINT_NUMBER_MASK) << 1U) | ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1459 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
1460
1461 /* Cancel the transfer and notify the up layer when the endpoint is busy. */
1462 if (0U != khciState->endpointState[index].stateUnion.stateBitField.transferring)
1463 {
1464 message.length = USB_CANCELLED_TRANSFER_LENGTH;
1465 message.buffer = khciState->endpointState[index].transferBuffer;
1466 message.code = ep;
1467 message.isSetup = 0U;
1468 khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
1469 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1470 if (kStatus_USB_Success != USB_DeviceNotificationTrigger(khciState->deviceHandle, &message))
1471 {
1472 return kStatus_USB_Error;
1473 }
1474 #else
1475 (void)USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
1476 #endif
1477 }
1478 return kStatus_USB_Success;
1479 }
1480
1481 /*!
1482 * @brief Control the status of the selected item.
1483 *
1484 * The function is used to control the status of the selected item.
1485 *
1486 * @param khciHandle Pointer of the device KHCI handle.
1487 * @param type The selected item. Please refer to enumeration type usb_device_control_type_t.
1488 * @param param The param type is determined by the selected item.
1489 *
1490 * @return A USB error code or kStatus_USB_Success.
1491 */
USB_DeviceKhciControl(usb_device_controller_handle khciHandle,usb_device_control_type_t type,void * param)1492 usb_status_t USB_DeviceKhciControl(usb_device_controller_handle khciHandle, usb_device_control_type_t type, void *param)
1493 {
1494 usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
1495 #if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
1496 uint32_t *temp32;
1497 #endif
1498 uint16_t *temp16;
1499 uint8_t *temp8;
1500 uint8_t count;
1501
1502 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
1503 (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U))
1504 usb_device_dcd_state_struct_t *dcdState;
1505 dcdState = &s_UsbDeviceDcdState[khciState->controllerId - kUSB_ControllerKhci0];
1506 usb_device_dcd_charging_time_t *deviceDcdTimingConfig = (usb_device_dcd_charging_time_t *)param;
1507 #endif
1508 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1509 usb_device_struct_t *deviceHandle;
1510 #endif
1511 #if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1512 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1513 uint64_t startTick;
1514 #endif
1515 #endif
1516 usb_status_t status = kStatus_USB_Error;
1517
1518 if (NULL == khciHandle)
1519 {
1520 return kStatus_USB_InvalidHandle;
1521 }
1522
1523 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1524 deviceHandle = (usb_device_struct_t *)khciState->deviceHandle;
1525 #endif
1526
1527 switch (type)
1528 {
1529 case kUSB_DeviceControlRun:
1530 khciState->registerBase->USBCTRL = 0U;
1531 #if defined(FSL_FEATURE_USB_KHCI_OTG_ENABLED) && (FSL_FEATURE_USB_KHCI_OTG_ENABLED > 0U)
1532 if (0U != (khciState->registerBase->OTGCTL & USB_OTGCTL_OTGEN_MASK))
1533 {
1534 khciState->registerBase->OTGCTL |= USB_OTGCTL_DPHIGH_MASK;
1535 }
1536 #endif /* FSL_FEATURE_USB_KHCI_OTG_ENABLED */
1537 khciState->registerBase->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
1538 khciState->registerBase->CTL |= USB_CTL_USBENSOFEN_MASK;
1539
1540 status = kStatus_USB_Success;
1541 break;
1542 case kUSB_DeviceControlStop:
1543 #if defined(FSL_FEATURE_USB_KHCI_OTG_ENABLED) && (FSL_FEATURE_USB_KHCI_OTG_ENABLED > 0U)
1544 if (0U != (khciState->registerBase->OTGCTL & USB_OTGCTL_OTGEN_MASK))
1545 {
1546 khciState->registerBase->OTGCTL &= (uint8_t)(~USB_OTGCTL_DPHIGH_MASK);
1547 }
1548 #endif /* FSL_FEATURE_USB_KHCI_OTG_ENABLED */
1549 khciState->registerBase->CONTROL &= (uint8_t)(~USB_CONTROL_DPPULLUPNONOTG_MASK);
1550 status = kStatus_USB_Success;
1551 break;
1552 case kUSB_DeviceControlEndpointInit:
1553 if (NULL != param)
1554 {
1555 status = USB_DeviceKhciEndpointInit(khciState, (usb_device_endpoint_init_struct_t *)param);
1556 }
1557 break;
1558 case kUSB_DeviceControlEndpointDeinit:
1559 if (NULL != param)
1560 {
1561 temp8 = (uint8_t *)param;
1562 status = USB_DeviceKhciEndpointDeinit(khciState, *temp8);
1563 }
1564 break;
1565 case kUSB_DeviceControlEndpointStall:
1566 if (NULL != param)
1567 {
1568 temp8 = (uint8_t *)param;
1569 status = USB_DeviceKhciEndpointStall(khciState, *temp8);
1570 }
1571 break;
1572 case kUSB_DeviceControlEndpointUnstall:
1573 if (NULL != param)
1574 {
1575 temp8 = (uint8_t *)param;
1576 status = USB_DeviceKhciEndpointUnstall(khciState, *temp8);
1577 }
1578 break;
1579 case kUSB_DeviceControlGetDeviceStatus:
1580 if (NULL != param)
1581 {
1582 temp16 = (uint16_t *)param;
1583 *temp16 = (USB_DEVICE_CONFIG_SELF_POWER << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT))
1584 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1585 | ((uint16_t)(((uint32_t)deviceHandle->remotewakeup)
1586 << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT)))
1587 #endif
1588 ;
1589 status = kStatus_USB_Success;
1590 }
1591 break;
1592 case kUSB_DeviceControlGetEndpointStatus:
1593 if (NULL != param)
1594 {
1595 usb_device_endpoint_status_struct_t *endpointStatus = (usb_device_endpoint_status_struct_t *)param;
1596
1597 if (((endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS)
1598 {
1599 endpointStatus->endpointStatus = (uint16_t)(
1600 (khciState
1601 ->endpointState[(((endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK) << 1U) |
1602 (((endpointStatus->endpointAddress) &
1603 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1604 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)]
1605 .stateUnion.stateBitField.stalled == 1U) ?
1606 kUSB_DeviceEndpointStateStalled :
1607 kUSB_DeviceEndpointStateIdle);
1608 status = kStatus_USB_Success;
1609 }
1610 }
1611 break;
1612 case kUSB_DeviceControlSetDeviceAddress:
1613 if (NULL != param)
1614 {
1615 temp8 = (uint8_t *)param;
1616 khciState->registerBase->ADDR = (*temp8);
1617 status = kStatus_USB_Success;
1618 }
1619 break;
1620 case kUSB_DeviceControlGetSynchFrame:
1621 break;
1622 #if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1623 #if defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)
1624 case kUSB_DeviceControlResume:
1625 khciState->registerBase->CTL |= USB_CTL_RESUME_MASK;
1626 startTick = deviceHandle->hwTick;
1627 while ((deviceHandle->hwTick - startTick) < 10U)
1628 {
1629 __NOP();
1630 }
1631 khciState->registerBase->CTL &= (uint8_t)(~USB_CTL_RESUME_MASK);
1632 status = kStatus_USB_Success;
1633 break;
1634 #endif /* USB_DEVICE_CONFIG_REMOTE_WAKEUP */
1635 case kUSB_DeviceControlSuspend:
1636 status = kStatus_USB_Success;
1637 break;
1638 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
1639 case kUSB_DeviceControlSetDefaultStatus:
1640 for (count = 0U; count < USB_DEVICE_CONFIG_ENDPOINTS; count++)
1641 {
1642 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1643 if ((kStatus_USB_Success != USB_DeviceKhciEndpointDeinit(khciState, (count | (USB_IN << 0x07U)))) ||
1644 (kStatus_USB_Success != USB_DeviceKhciEndpointDeinit(khciState, (count | (USB_OUT << 0x07U)))))
1645 {
1646 return kStatus_USB_Error;
1647 }
1648 #else
1649 (void)USB_DeviceKhciEndpointDeinit(khciState, (count | (USB_IN << 0x07U)));
1650 (void)USB_DeviceKhciEndpointDeinit(khciState, (count | (USB_OUT << 0x07U)));
1651 #endif
1652 }
1653 USB_DeviceKhciSetDefaultState(khciState);
1654 status = kStatus_USB_Success;
1655 break;
1656 case kUSB_DeviceControlGetSpeed:
1657 if (NULL != param)
1658 {
1659 temp8 = (uint8_t *)param;
1660 *temp8 = USB_SPEED_FULL;
1661 status = kStatus_USB_Success;
1662 }
1663 break;
1664 #if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
1665 case kUSB_DeviceControlGetOtgStatus:
1666 *((uint8_t *)param) = khciState->otgStatus;
1667 break;
1668 case kUSB_DeviceControlSetOtgStatus:
1669 khciState->otgStatus = *((uint8_t *)param);
1670 break;
1671 #endif
1672 case kUSB_DeviceControlSetTestMode:
1673 break;
1674 #if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U))
1675 case kUSB_DeviceControlUpdateHwTick:
1676 /*udpate 1ms time tick*/
1677 status = kStatus_USB_Success;
1678 break;
1679 #endif
1680 #if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U)
1681 case kUSB_DeviceControlGetCurrentFrameCount:
1682 if (NULL != param)
1683 {
1684 temp32 = (uint32_t *)param;
1685 *temp32 = (uint32_t)((khciState->registerBase->FRMNUMH << 8U) | (khciState->registerBase->FRMNUML));
1686 }
1687 break;
1688 #endif
1689 default:
1690 /*no action*/
1691 break;
1692 }
1693
1694 return status;
1695 }
1696
1697 /*!
1698 * @brief Handle the KHCI device interrupt.
1699 *
1700 * The function is used to handle the KHCI device interrupt.
1701 *
1702 * @param deviceHandle The device handle got from USB_DeviceInit.
1703 *
1704 */
USB_DeviceKhciIsrFunction(void * deviceHandle)1705 void USB_DeviceKhciIsrFunction(void *deviceHandle)
1706 {
1707 usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
1708 usb_device_khci_state_struct_t *khciState;
1709 uint8_t status;
1710
1711 if (NULL == deviceHandle)
1712 {
1713 return;
1714 }
1715
1716 khciState = (usb_device_khci_state_struct_t *)(handle->controllerHandle);
1717
1718 status = khciState->registerBase->ISTAT;
1719 status &= khciState->registerBase->INTEN;
1720 #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
1721 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
1722 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
1723 /* Clear EEP_ALIVE_CTRL_WAKE_INT interrupt state */
1724 if (0U != (khciState->registerBase->KEEP_ALIVE_CTRL & USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_MASK))
1725 {
1726 khciState->registerBase->KEEP_ALIVE_CTRL |= USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_MASK;
1727 }
1728 /* Clear SOFTOK interrupt state */
1729 if (0U != (khciState->registerBase->ISTAT & USB_ISTAT_SOFTOK_MASK))
1730 {
1731 khciState->registerBase->ISTAT = USB_ISTAT_SOFTOK_MASK;
1732 }
1733 #endif
1734 #if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)
1735 /* Error interrupt */
1736 if (0U != (status & USB_INTEN_ERROREN_MASK))
1737 {
1738 USB_DeviceKhciInterruptError(khciState);
1739 }
1740 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
1741 /* Token done interrupt */
1742 if (0U != (status & USB_INTEN_TOKDNEEN_MASK))
1743 {
1744 USB_DeviceKhciInterruptTokenDone(khciState);
1745 }
1746
1747 /* Reset interrupt */
1748 if (0U != (status & USB_INTEN_USBRSTEN_MASK))
1749 {
1750 USB_DeviceKhciInterruptReset(khciState);
1751 }
1752
1753 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
1754 /* Suspend interrupt */
1755 if (0U != (status & USB_INTEN_SLEEPEN_MASK))
1756 {
1757 USB_DeviceKhciInterruptSleep(khciState);
1758 }
1759
1760 /* Resume interrupt */
1761 if (0U != (status & USB_INTEN_RESUMEEN_MASK))
1762 {
1763 USB_DeviceKhciInterruptResume(khciState);
1764 }
1765
1766 /* Check for Asynchronous Resume interrupt if it was enabled */
1767 if ((0U != (khciState->registerBase->USBTRC0 & USB_USBTRC0_USB_RESUME_INT_MASK)) &&
1768 (0U != (khciState->registerBase->USBTRC0 & USB_USBTRC0_USBRESMEN_MASK)))
1769 {
1770 USB_DeviceKhciInterruptResume(khciState);
1771 }
1772 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
1773
1774 /* Endpoint stalled interrupt */
1775 if (0U != (status & USB_INTEN_STALLEN_MASK))
1776 {
1777 USB_DeviceKhciInterruptStall(khciState);
1778 }
1779
1780 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) && \
1781 (defined(FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED) && (FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED > 0U))
1782 if (0U != (khciState->registerBase->USBTRC0 & USB_USBTRC0_VREDG_DET_MASK))
1783 {
1784 USB_DeviceKhciInterruptVbusRising(khciState);
1785 }
1786
1787 if (0U != (khciState->registerBase->USBTRC0 & USB_USBTRC0_VFEDG_DET_MASK))
1788 {
1789 USB_DeviceKhciInterruptVbusFalling(khciState);
1790 }
1791 #endif /* USB_DEVICE_CONFIG_DETACH_ENABLE && FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED */
1792
1793 #if (defined(USB_DEVICE_CONFIG_SOF_NOTIFICATIONS) && (USB_DEVICE_CONFIG_SOF_NOTIFICATIONS > 0U))
1794 /* SOF token interrupt */
1795 if (0U != (status & USB_INTEN_SOFTOKEN_MASK))
1796 {
1797 USB_DeviceKhciInterruptSOF(khciState);
1798 }
1799 #endif
1800
1801 #if ((defined FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && \
1802 (FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED > 0U))
1803 status = khciState->registerBase->CLK_RECOVER_INT_STATUS;
1804 if (0U != status)
1805 {
1806 /* USB RECOVER interrupt is happened */
1807 if (0U != (USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_MASK & status))
1808 {
1809 /* Indicates that the USB clock recovery algorithm has detected that the frequency trim adjustment needed
1810 * for the IRC48M output clock is outside the available TRIM_FINE adjustment range for the IRC48M
1811 * module.
1812 */
1813 }
1814 khciState->registerBase->CLK_RECOVER_INT_STATUS = status;
1815 }
1816 #endif
1817 }
1818
1819 #endif /* USB_DEVICE_CONFIG_KHCI */
1820