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