2 * The Clear BSD License
3 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
4 * Copyright 2016 - 2017 NXP
7 * Redistribution and use in source and binary forms, with or without modification,
8 * are permitted (subject to the limitations in the disclaimer below) provided
9 * that the following conditions are met:
11 * o Redistributions of source code must retain the above copyright notice, this list
12 * of conditions and the following disclaimer.
14 * o Redistributions in binary form must reproduce the above copyright notice, this
15 * list of conditions and the following disclaimer in the documentation and/or
16 * other materials provided with the distribution.
18 * o Neither the name of the copyright holder nor the names of its
19 * contributors may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
22 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include "usb_device_config.h"
38 #include "usb_device.h"
39 #include "usb_device_dci.h"
41 #include "fsl_device_registers.h"
43 #if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U))
45 #if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
46 #include "usb_device_khci.h"
49 #if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
50 #include "usb_device_ehci.h"
53 #if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
54 ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
55 #include "usb_device_lpcip3511.h"
58 #include "usb_device_ch9.h"
59 #if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
60 #include "fsl_cache.h"
62 /*******************************************************************************
64 ******************************************************************************/
66 /*******************************************************************************
68 ******************************************************************************/
69 static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle);
70 static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle);
71 static usb_status_t USB_DeviceGetControllerInterface(
72 uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface);
73 static usb_status_t USB_DeviceTransfer(usb_device_handle handle,
74 uint8_t endpointAddress,
77 static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param);
78 static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle,
79 usb_device_callback_message_struct_t *message);
80 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
81 static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle,
82 usb_device_callback_message_struct_t *message);
83 static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle,
84 usb_device_callback_message_struct_t *message);
85 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
86 static usb_status_t USB_DeviceSleepNotification(usb_device_struct_t *handle,
87 usb_device_callback_message_struct_t *message);
90 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
91 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
92 static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle,
93 usb_device_callback_message_struct_t *message);
94 static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle,
95 usb_device_callback_message_struct_t *message);
97 static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message);
99 /*******************************************************************************
101 ******************************************************************************/
103 USB_GLOBAL static usb_device_struct_t s_UsbDevice[USB_DEVICE_CONFIG_NUM];
105 /*******************************************************************************
107 ******************************************************************************/
110 * @brief Allocate a device handle.
112 * This function allocates a device handle.
114 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
115 * @param handle It is out parameter, is used to return pointer of the device handle to the caller.
117 * @retval kStatus_USB_Success Get a device handle successfully.
118 * @retval kStatus_USB_Busy Cannot allocate a device handle.
119 * @retval kStatus_USB_Error The device has been initialized.
121 static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle)
126 USB_OSA_ENTER_CRITICAL();
127 /* Check the controller is initialized or not. */
128 for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
130 if ((NULL != s_UsbDevice[count].controllerHandle) && (controllerId == s_UsbDevice[count].controllerId))
132 USB_OSA_EXIT_CRITICAL();
133 return kStatus_USB_Error;
136 /* Get a free device handle. */
137 for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
139 if (NULL == s_UsbDevice[count].controllerHandle)
141 s_UsbDevice[count].controllerId = controllerId;
142 *handle = &s_UsbDevice[count];
143 USB_OSA_EXIT_CRITICAL();
144 return kStatus_USB_Success;
147 USB_OSA_EXIT_CRITICAL();
148 return kStatus_USB_Busy;
152 * @brief Free a device handle.
154 * This function frees a device handle.
156 * @param handle The device handle.
158 * @retval kStatus_USB_Success Free device handle successfully.
160 static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle)
164 USB_OSA_ENTER_CRITICAL();
165 handle->controllerHandle = NULL;
166 handle->controllerId = 0U;
167 USB_OSA_EXIT_CRITICAL();
168 return kStatus_USB_Success;
171 #if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
172 /* KHCI device driver interface */
173 static const usb_device_controller_interface_struct_t s_UsbDeviceKhciInterface = {
174 USB_DeviceKhciInit, USB_DeviceKhciDeinit, USB_DeviceKhciSend,
175 USB_DeviceKhciRecv, USB_DeviceKhciCancel, USB_DeviceKhciControl};
178 #if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
179 /* EHCI device driver interface */
180 static const usb_device_controller_interface_struct_t s_UsbDeviceEhciInterface = {
181 USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend,
182 USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl};
185 #if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
186 ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
187 /* EHCI device driver interface */
188 static const usb_device_controller_interface_struct_t s_UsbDeviceLpc3511IpInterface = {
189 USB_DeviceLpc3511IpInit, USB_DeviceLpc3511IpDeinit, USB_DeviceLpc3511IpSend,
190 USB_DeviceLpc3511IpRecv, USB_DeviceLpc3511IpCancel, USB_DeviceLpc3511IpControl};
194 * @brief Get the controller interface handle.
196 * This function is used to get the controller interface handle.
198 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
199 * @param controllerInterface It is out parameter, is used to return pointer of the device controller handle to the
202 * @retval kStatus_USB_Success Get a device handle successfully.
203 * @retval kStatus_USB_ControllerNotFound The controller id is invalided.
205 static usb_status_t USB_DeviceGetControllerInterface(
206 uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface)
208 usb_status_t error = kStatus_USB_ControllerNotFound;
209 switch (controllerId)
211 #if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
212 /* Get the KHCI controller driver interface */
213 case kUSB_ControllerKhci0:
214 case kUSB_ControllerKhci1:
215 *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceKhciInterface;
216 error = kStatus_USB_Success;
219 #if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
220 /* Get the EHCI controller driver interface */
221 case kUSB_ControllerEhci0:
222 case kUSB_ControllerEhci1:
223 error = kStatus_USB_Success;
224 *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceEhciInterface;
227 #if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
228 ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
229 /* Get the EHCI controller driver interface */
230 case kUSB_ControllerLpcIp3511Fs0:
231 case kUSB_ControllerLpcIp3511Fs1:
232 case kUSB_ControllerLpcIp3511Hs0:
233 case kUSB_ControllerLpcIp3511Hs1:
234 error = kStatus_USB_Success;
235 *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceLpc3511IpInterface;
245 * @brief Start a new transfer.
247 * This function is used to start a new transfer.
249 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
250 * @param endpointAddress Endpoint address. Bit7 is direction, 0U - USB_OUT, 1U - USB_IN.
251 * @param buffer The memory address to be transferred, or the memory address to hold the data need to be
253 * @param length The length of the data.
255 * @retval kStatus_USB_Success Get a device handle successfully.
256 * @retval kStatus_USB_InvalidHandle The device handle is invalided.
257 * @retval kStatus_USB_ControllerNotFound The controller interface is not found.
258 * @retval kStatus_USB_Error The device is doing reset.
260 static usb_status_t USB_DeviceTransfer(usb_device_handle handle,
261 uint8_t endpointAddress,
265 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
266 usb_status_t error = kStatus_USB_Error;
267 uint8_t endpoint = endpointAddress & USB_ENDPOINT_NUMBER_MASK;
268 uint8_t direction = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
269 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
272 if (NULL == deviceHandle)
274 return kStatus_USB_InvalidHandle;
277 if (NULL != deviceHandle->controllerInterface)
279 if (deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy)
281 return kStatus_USB_Busy;
283 USB_OSA_ENTER_CRITICAL();
284 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 1U;
285 USB_OSA_EXIT_CRITICAL();
286 if (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)
288 #if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
291 DCACHE_CleanByRange((uint32_t)buffer, length);
294 /* Call the controller send interface, the callbackFn is initialized in
295 USB_DeviceGetControllerInterface */
296 error = deviceHandle->controllerInterface->deviceSend(deviceHandle->controllerHandle, endpointAddress,
301 #if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
304 DCACHE_CleanInvalidateByRange((uint32_t)buffer, length);
307 /* Call the controller receive interface, the callbackFn is initialized in
308 USB_DeviceGetControllerInterface */
309 error = deviceHandle->controllerInterface->deviceRecv(deviceHandle->controllerHandle, endpointAddress,
312 if (kStatus_USB_Success != error)
314 USB_OSA_ENTER_CRITICAL();
315 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U;
316 USB_OSA_EXIT_CRITICAL();
321 error = kStatus_USB_ControllerNotFound;
327 * @brief Control the status of the selected item.
329 * This function is used to control the status of the selected item..
331 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
332 * @param type The control type, please refer to the enumeration usb_device_control_type_t.
333 * @param param The param type is determined by the selected item.
335 * @retval kStatus_USB_Success Get a device handle successfully.
336 * @retval kStatus_USB_InvalidHandle The device handle is invalided.
337 * @retval kStatus_USB_ControllerNotFound The controller interface is not found.
338 * @retval kStatus_USB_Error Unsupport type.
339 * Or, the param is NULL pointer.
341 static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param)
343 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
344 usb_status_t error = kStatus_USB_Error;
346 if (NULL == deviceHandle)
348 return kStatus_USB_InvalidHandle;
351 if (NULL != deviceHandle->controllerInterface)
353 /* Call the controller control interface. the controllerInterface is initialized in
354 USB_DeviceGetControllerInterface */
355 error = deviceHandle->controllerInterface->deviceControl(deviceHandle->controllerHandle, type, param);
359 error = kStatus_USB_ControllerNotFound;
365 * @brief Handle the reset notification.
367 * This function is used to handle the reset notification.
369 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
370 * @param message The device callback message handle.
372 * @retval kStatus_USB_Success Get a device handle successfully.
374 static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle,
375 usb_device_callback_message_struct_t *message)
377 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
381 handle->isResetting = 1U;
383 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
384 /* Clear remote wakeup feature */
385 handle->remotewakeup = 0U;
388 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
389 USB_OSA_ENTER_CRITICAL();
390 handle->epCallbackDirectly = 1;
391 USB_OSA_EXIT_CRITICAL();
393 /* Set the controller to default status. */
394 USB_DeviceControl(handle, kUSB_DeviceControlSetDefaultStatus, NULL);
395 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
396 USB_OSA_ENTER_CRITICAL();
397 handle->epCallbackDirectly = 0;
398 USB_OSA_EXIT_CRITICAL();
401 handle->state = kUSB_DeviceStateDefault;
402 handle->deviceAddress = 0U;
404 for (uint32_t count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++)
406 handle->epCallback[count].callbackFn = (usb_device_endpoint_callback_t)NULL;
407 handle->epCallback[count].callbackParam = NULL;
408 handle->epCallback[count].isBusy = 0U;
411 /* Call device callback to notify the application that the USB bus reset signal detected.
412 the deviceCallback is the second parameter of USB_DeviceInit */
413 handle->deviceCallback(handle, kUSB_DeviceEventBusReset, NULL);
415 handle->isResetting = 0U;
416 return kStatus_USB_Success;
419 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
421 * @brief Handle the suspend notification.
423 * This function is used to handle the suspend notification.
425 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
426 * @param message The device callback message handle.
428 * @return A USB error code or kStatus_USB_Success.
430 static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle,
431 usb_device_callback_message_struct_t *message)
433 /* Call device callback to notify the application that the USB bus suspend signal detected.
434 the deviceCallback is the second parameter of USB_DeviceInit */
435 return handle->deviceCallback(handle, kUSB_DeviceEventSuspend, NULL);
439 * @brief Handle the resume notification.
441 * This function is used to handle the resume notification.
443 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
444 * @param message The device callback message handle.
446 * @return A USB error code or kStatus_USB_Success.
448 static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle,
449 usb_device_callback_message_struct_t *message)
451 /* Call device callback to notify the application that the USB bus resume signal detected.
452 the deviceCallback is the second parameter of USB_DeviceInit */
453 return handle->deviceCallback(handle, kUSB_DeviceEventResume, NULL);
455 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
457 * @brief Handle the suspend notification.
459 * This function is used to handle the suspend notification.
461 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
462 * @param message The device callback message handle.
464 * @return A USB error code or kStatus_USB_Success.
466 static usb_status_t USB_DeviceSleepNotification(usb_device_struct_t *handle,
467 usb_device_callback_message_struct_t *message)
469 /* Call device callback to notify the application that the USB bus suspend signal detected.
470 the deviceCallback is the second parameter of USB_DeviceInit */
471 return handle->deviceCallback(handle, kUSB_DeviceEventSleeped, NULL);
475 * @brief Handle the remotewakeup notification.
477 * This function is used to handle the remotewakeup notification.
479 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
480 * @param flag The buffer pointer to store remotewakeup flag.
482 * @return A USB error code or kStatus_USB_Success.
484 usb_status_t USB_DeviceGetRemoteWakeUp(usb_device_struct_t *handle, uint8_t **flag)
486 /* Call device callback to notify the application that the USB bus suspend signal detected. */
487 return USB_DeviceControl(handle, kUSB_DeviceControlGetRemoteWakeUp, flag);
490 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
492 #if (defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U))
493 usb_status_t USB_DeviceErrorNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message)
495 /* Call device callback to notify the application that the USB bus error signal detected.
496 the deviceCallback is the second parameter of USB_DeviceInit */
497 return handle->deviceCallback(handle, kUSB_DeviceEventError, NULL);
499 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
501 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
503 * @brief Handle the detach notification.
505 * This function is used to handle the detach notification.
507 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
508 * @param message The device callback message handle.
510 * @return A USB error code or kStatus_USB_Success.
512 static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle,
513 usb_device_callback_message_struct_t *message)
515 /* Call device callback to notify the application that the device is disconnected from a host.
516 the deviceCallback is the second parameter of USB_DeviceInit */
517 return handle->deviceCallback(handle, kUSB_DeviceEventDetach, NULL);
521 * @brief Handle the attach notification.
523 * This function is used to handle the attach notification.
525 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
526 * @param message The device callback message handle.
528 * @return A USB error code or kStatus_USB_Success.
530 static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle,
531 usb_device_callback_message_struct_t *message)
533 /* Call device callback to notify the application that the device is connected to a host.
534 the deviceCallback is the second parameter of USB_DeviceInit */
535 return handle->deviceCallback(handle, kUSB_DeviceEventAttach, NULL);
539 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
540 ((defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) || \
541 (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
543 * @brief Handle the dcd module timeout notification.
545 * This function is used to handle the dcd module timeout notification.
547 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
548 * @param message The device callback message handle.
550 * @return A USB error code or kStatus_USB_Success.
552 static usb_status_t USB_DeviceDcdTimeOutNotification(usb_device_struct_t *handle,
553 usb_device_callback_message_struct_t *message)
555 /* Call device callback to notify the application that the device charger detect timeout happened.
556 the deviceCallback is the second parameter of USB_DeviceInit */
557 return handle->deviceCallback(handle, kUSB_DeviceEventDcdTimeOut, NULL);
561 * @brief Handle the dcd module unknown port type notification.
563 * This function is used to handle the dcd module unknown port type notification.
565 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
566 * @param message The device callback message handle.
568 * @return A USB error code or kStatus_USB_Success.
570 static usb_status_t USB_DeviceDcdUnknownPortTypeNotification(usb_device_struct_t *handle,
571 usb_device_callback_message_struct_t *message)
573 /* Call device callback to notify the application that the device charger detect unknown port type happened.
574 the deviceCallback is the second parameter of USB_DeviceInit */
575 return handle->deviceCallback(handle, kUSB_DeviceEventDcdUnknownType, NULL);
579 * @brief Handle the SDP facility is detected notification.
581 * This function is used to handle the SDP facility is detectednotification.
583 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
584 * @param message The device callback message handle.
586 * @return A USB error code or kStatus_USB_Success.
588 static usb_status_t USB_DeviceDcdSDPDetectNotification(usb_device_struct_t *handle,
589 usb_device_callback_message_struct_t *message)
591 /* Call device callback to notify the application that the SDP facility is detected.
592 the deviceCallback is the second parameter of USB_DeviceInit */
593 return handle->deviceCallback(handle, kUSB_DeviceEventSDPDetected, NULL);
597 * @brief Handle the charging port is detected notification.
599 * This function is used to handle the charging port is detectednotification.
601 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
602 * @param message The device callback message handle.
604 * @return A USB error code or kStatus_USB_Success.
606 static usb_status_t USB_DeviceDcdChargingPortDetectNotification(usb_device_struct_t *handle,
607 usb_device_callback_message_struct_t *message)
609 /* Call device callback to notify the application that the charing port is detected.
610 the deviceCallback is the second parameter of USB_DeviceInit */
611 return handle->deviceCallback(handle, kUSB_DeviceEventChargingPortDetected, NULL);
615 * @brief Handle the CDP facility is detected notification.
617 * This function is used to handle the CDP facility is detectednotification.
619 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
620 * @param message The device callback message handle.
622 * @return A USB error code or kStatus_USB_Success.
624 static usb_status_t USB_DeviceDcdChargingHostDetectNotification(usb_device_struct_t *handle,
625 usb_device_callback_message_struct_t *message)
627 /* Call device callback to notify the application that the CDP facility is detected.
628 the deviceCallback is the second parameter of USB_DeviceInit */
629 return handle->deviceCallback(handle, kUSB_DeviceEventChargingHostDetected, NULL);
633 * @brief Handle the DCP facility is detected notification.
635 * This function is used to handle the DCP facility is detectednotification.
637 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
638 * @param message The device callback message handle.
640 * @return A USB error code or kStatus_USB_Success.
643 static usb_status_t USB_DeviceDcdDedicatedChargerDetectNotification(usb_device_struct_t *handle,
644 usb_device_callback_message_struct_t *message)
646 /* Call device callback to notify the application that the DCP facility is detected.
647 the deviceCallback is the second parameter of USB_DeviceInit */
648 return handle->deviceCallback(handle, kUSB_DeviceEventDedicatedChargerDetected, NULL);
653 * @brief Handle the attach notification.
655 * This function is used to handle the attach notification.
657 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
658 * @param message The device callback message handle.
660 * @return A USB error code or kStatus_USB_Success.
662 static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message)
664 uint8_t endpoint = message->code & USB_ENDPOINT_NUMBER_MASK;
665 uint8_t direction = (message->code & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
666 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
667 usb_status_t error = kStatus_USB_Error;
669 switch (message->code)
671 case kUSB_DeviceNotifyBusReset:
672 error = USB_DeviceResetNotification(handle, message);
674 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
675 case kUSB_DeviceNotifySuspend:
676 error = USB_DeviceSuspendNotification(handle, message);
678 case kUSB_DeviceNotifyResume:
679 error = USB_DeviceResumeNotification(handle, message);
681 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
682 case kUSB_DeviceNotifyLPMSleep:
683 error = USB_DeviceSleepNotification(handle, message);
688 #if (defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U))
689 case kUSB_DeviceNotifyError:
690 error = USB_DeviceErrorNotification(handle, message);
694 #if USB_DEVICE_CONFIG_DETACH_ENABLE
695 case kUSB_DeviceNotifyDetach:
696 error = USB_DeviceDetachNotification(handle, message);
698 case kUSB_DeviceNotifyAttach:
699 error = USB_DeviceAttachNotification(handle, message);
702 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
703 ((defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) || \
704 (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
705 case kUSB_DeviceNotifyDcdTimeOut:
706 error = USB_DeviceDcdTimeOutNotification(handle, message);
708 case kUSB_DeviceNotifyDcdUnknownPortType:
709 error = USB_DeviceDcdUnknownPortTypeNotification(handle, message);
711 case kUSB_DeviceNotifySDPDetected:
712 error = USB_DeviceDcdSDPDetectNotification(handle, message);
714 case kUSB_DeviceNotifyChargingPortDetected:
715 error = USB_DeviceDcdChargingPortDetectNotification(handle, message);
717 case kUSB_DeviceNotifyChargingHostDetected:
718 error = USB_DeviceDcdChargingHostDetectNotification(handle, message);
720 case kUSB_DeviceNotifyDedicatedChargerDetected:
721 error = USB_DeviceDcdDedicatedChargerDetectNotification(handle, message);
726 if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS)
728 if (handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn)
730 usb_device_endpoint_callback_message_struct_t endpointCallbackMessage;
731 endpointCallbackMessage.buffer = message->buffer;
732 endpointCallbackMessage.length = message->length;
733 endpointCallbackMessage.isSetup = message->isSetup;
734 if (message->isSetup)
736 handle->epCallback[0].isBusy = 0U;
737 handle->epCallback[1].isBusy = 0U;
741 handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U;
743 /* Call endpoint callback, callbackFn is in the third parameter of USB_DeviceInitEndpoint */
744 error = handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn(
745 handle, &endpointCallbackMessage,
746 handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam);
755 * @brief Notify the device that the controller status changed.
757 * This function is used to notify the device that the controller status changed.
759 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
760 * @param message The device callback message handle.
762 * @return A USB error code or kStatus_USB_Success.
764 usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg)
766 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
767 usb_device_callback_message_struct_t *message = (usb_device_callback_message_struct_t *)msg;
769 if ((NULL == msg) || (NULL == handle))
771 return kStatus_USB_InvalidHandle;
774 /* The device callback is invalid or not. */
775 if (!deviceHandle->deviceCallback)
777 return kStatus_USB_Error;
780 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
781 if (deviceHandle->epCallbackDirectly)
783 if ((message->code & USB_ENDPOINT_NUMBER_MASK) && (!(message->code & 0x70U)))
785 return USB_DeviceNotification(deviceHandle, message);
789 /* Add the message to message queue when the device task is enabled. */
790 if (kStatus_USB_OSA_Success != USB_OsaMsgqSend(deviceHandle->notificationQueue, (void *)message))
792 return kStatus_USB_Busy;
794 return kStatus_USB_Success;
796 /* Handle the notification by calling USB_DeviceNotification. */
797 return USB_DeviceNotification(deviceHandle, message);
802 * @brief Initialize the USB device stack.
804 * This function initializes the USB device module specified by the controllerId.
806 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
807 * @param deviceCallback Function pointer of the device callback.
808 * @param handle It is out parameter, is used to return pointer of the device handle to the caller.
810 * @retval kStatus_USB_Success The device is initialized successfully.
811 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer.
812 * @retval kStatus_USB_Busy Cannot allocate a device handle.
813 * @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller id.
814 * @retval kStatus_USB_InvalidControllerInterface The controller driver interfaces is invaild, There is an empty
816 * @retval kStatus_USB_Error The macro USB_DEVICE_CONFIG_ENDPOINTS is more than IP's endpoint number.
817 * Or, the device has been initialized.
818 * Or, the message queue is created failed.
820 usb_status_t USB_DeviceInit(uint8_t controllerId, usb_device_callback_t deviceCallback, usb_device_handle *handle)
822 usb_device_struct_t *deviceHandle = NULL;
828 return kStatus_USB_InvalidHandle;
831 /* Allocate a device handle by using the controller id. */
832 error = USB_DeviceAllocateHandle(controllerId, &deviceHandle);
834 if (kStatus_USB_Success != error)
839 /* Save the device callback */
840 deviceHandle->deviceCallback = deviceCallback;
841 /* Save the controller id */
842 deviceHandle->controllerId = controllerId;
843 /* Clear the device address */
844 deviceHandle->deviceAddress = 0U;
845 /* Clear the device reset state */
846 deviceHandle->isResetting = 0U;
848 /* Initialize the enpoints */
849 for (count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++)
851 deviceHandle->epCallback[count].callbackFn = (usb_device_endpoint_callback_t)NULL;
852 deviceHandle->epCallback[count].callbackParam = NULL;
853 deviceHandle->epCallback[count].isBusy = 0U;
856 /* Get the controller interface according to the controller id */
857 error = USB_DeviceGetControllerInterface(controllerId, &deviceHandle->controllerInterface);
858 if (kStatus_USB_Success != error)
860 USB_DeviceFreeHandle(deviceHandle);
863 if (NULL == deviceHandle->controllerInterface)
865 USB_DeviceFreeHandle(deviceHandle);
866 return kStatus_USB_ControllerNotFound;
868 if (((usb_device_controller_init_t)NULL == deviceHandle->controllerInterface->deviceInit) ||
869 ((usb_device_controller_deinit_t)NULL == deviceHandle->controllerInterface->deviceDeinit) ||
870 ((usb_device_controller_send_t)NULL == deviceHandle->controllerInterface->deviceSend) ||
871 ((usb_device_controller_recv_t)NULL == deviceHandle->controllerInterface->deviceRecv) ||
872 ((usb_device_controller_cancel_t)NULL == deviceHandle->controllerInterface->deviceCancel) ||
873 ((usb_device_controller_control_t)NULL == deviceHandle->controllerInterface->deviceControl))
875 USB_DeviceFreeHandle(deviceHandle);
876 return kStatus_USB_InvalidControllerInterface;
879 #if USB_DEVICE_CONFIG_USE_TASK
880 /* Create a message queue when the device handle is enabled. */
881 if (kStatus_USB_OSA_Success !=
882 USB_OsaMsgqCreate(&deviceHandle->notificationQueue, USB_DEVICE_CONFIG_MAX_MESSAGES,
883 (1U + (sizeof(usb_device_callback_message_struct_t) - 1U) / sizeof(uint32_t))))
885 USB_DeviceDeinit(deviceHandle);
886 return kStatus_USB_Error;
890 *handle = deviceHandle;
892 /* Initialize the controller, the callbackFn is initialized in USB_DeviceGetControllerInterface */
893 error = deviceHandle->controllerInterface->deviceInit(controllerId, deviceHandle, &deviceHandle->controllerHandle);
894 if (kStatus_USB_Success != error)
896 USB_DeviceDeinit(deviceHandle);
900 /* Set the device to deafult state */
901 deviceHandle->state = kUSB_DeviceStateDefault;
907 * @brief Enable the device functionality.
909 * The function enables the device functionality, so that the device can be recognized by the host when the device
910 * detects that it has been connected to a host.
912 * @param handle The device handle got from USB_DeviceInit.
914 * @retval kStatus_USB_Success The device is run successfully.
915 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
916 * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
919 usb_status_t USB_DeviceRun(usb_device_handle handle)
921 return USB_DeviceControl(handle, kUSB_DeviceControlRun, NULL);
924 * @brief Disable the device functionality.
926 * The function disables the device functionality, after this function called, even the device is detached to the host,
927 * and the device can't work.
929 * @param handle The device handle got from USB_DeviceInit.
931 * @retval kStatus_USB_Success The device is stopped successfully.
932 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
933 * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
935 usb_status_t USB_DeviceStop(usb_device_handle handle)
937 return USB_DeviceControl(handle, kUSB_DeviceControlStop, NULL);
940 * @brief De-initialize the device controller.
942 * The function de-initializes the device controller specified by the handle.
944 * @param handle The device handle got from USB_DeviceInit.
946 * @retval kStatus_USB_Success The device is stopped successfully.
947 * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
949 usb_status_t USB_DeviceDeinit(usb_device_handle handle)
951 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
953 if (NULL == deviceHandle)
955 return kStatus_USB_InvalidHandle;
957 /* De-initialize the controller */
958 if (NULL != deviceHandle->controllerInterface)
960 /* the callbackFn is initialized in USB_DeviceGetControllerInterface */
961 deviceHandle->controllerInterface->deviceDeinit(deviceHandle->controllerHandle);
962 deviceHandle->controllerInterface = (usb_device_controller_interface_struct_t *)NULL;
965 #if USB_DEVICE_CONFIG_USE_TASK
966 /* Destroy the message queue. */
967 if (NULL != deviceHandle->notificationQueue)
969 USB_OsaMsgqDestroy(deviceHandle->notificationQueue);
970 deviceHandle->notificationQueue = NULL;
974 /* Free the device handle. */
975 USB_DeviceFreeHandle(deviceHandle);
976 return kStatus_USB_Success;
980 * @brief Send data through a specified endpoint.
982 * The function is used to send data through a specified endpoint.
984 * @param handle The device handle got from USB_DeviceInit.
985 * @param endpointAddress Endpoint index.
986 * @param buffer The memory address to hold the data need to be sent.
987 * @param length The data length need to be sent.
989 * @retval kStatus_USB_Success The send request is sent successfully.
990 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
991 * @retval kStatus_USB_Busy Cannot allocate dtds for current tansfer in EHCI driver.
992 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
993 * @retval kStatus_USB_Error The device is doing reset.
995 * @note The return value just means if the sending request is successful or not; the transfer done is notified by the
996 * corresponding callback function.
997 * Currently, only one transfer request can be supported for one specific endpoint.
998 * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
999 * should implement a queue in the application level.
1000 * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1003 usb_status_t USB_DeviceSendRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length)
1005 return USB_DeviceTransfer(handle, (endpointAddress & USB_ENDPOINT_NUMBER_MASK) |
1006 (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
1011 * @brief Receive data through a specified endpoint.
1013 * The function is used to receive data through a specified endpoint.
1015 * @param handle The device handle got from USB_DeviceInit.
1016 * @param endpointAddress Endpoint index.
1017 * @param buffer The memory address to save the received data.
1018 * @param length The data length want to be received.
1020 * @retval kStatus_USB_Success The receive request is sent successfully.
1021 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1022 * @retval kStatus_USB_Busy Cannot allocate dtds for current tansfer in EHCI driver.
1023 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1024 * @retval kStatus_USB_Error The device is doing reset.
1026 * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the
1027 * corresponding callback function.
1028 * Currently, only one transfer request can be supported for one specific endpoint.
1029 * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1030 * should implement a queue in the application level.
1031 * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1034 usb_status_t USB_DeviceRecvRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length)
1036 return USB_DeviceTransfer(handle, (endpointAddress & USB_ENDPOINT_NUMBER_MASK) |
1037 (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
1042 * @brief Cancel the pending transfer in a specified endpoint.
1044 * The function is used to cancel the pending transfer in a specified endpoint.
1046 * @param handle The device handle got from USB_DeviceInit.
1047 * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1049 * @retval kStatus_USB_Success The transfer is cancelled.
1050 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1051 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1053 usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress)
1055 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
1056 usb_status_t error = kStatus_USB_Error;
1058 if (NULL == deviceHandle)
1060 return kStatus_USB_InvalidHandle;
1063 if (NULL != deviceHandle->controllerInterface)
1065 /* the callbackFn is initialized in USB_DeviceGetControllerInterface */
1066 error = deviceHandle->controllerInterface->deviceCancel(deviceHandle->controllerHandle, endpointAddress);
1070 error = kStatus_USB_ControllerNotFound;
1076 * @brief Initialize a specified endpoint.
1078 * The function is used to initialize a specified endpoint and the corresponding endpoint callback is also initialized.
1080 * @param handle The device handle got from USB_DeviceInit.
1081 * @param epInit Endpoint initizlization structure. Please refer to the structure usb_device_endpoint_init_struct_t.
1082 * @param epCallback Endpoint callback structure. Please refer to the structure
1083 * usb_device_endpoint_callback_struct_t.
1085 * @retval kStatus_USB_Success The endpoint is initialized successfully.
1086 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1087 * @retval kStatus_USB_InvalidParameter The epInit or epCallback is NULL pointer. Or the endpoint number is
1088 * more than USB_DEVICE_CONFIG_ENDPOINTS.
1089 * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver.
1090 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1092 usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle,
1093 usb_device_endpoint_init_struct_t *epInit,
1094 usb_device_endpoint_callback_struct_t *epCallback)
1096 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
1102 return kStatus_USB_InvalidHandle;
1105 if ((!epInit) || (!epCallback))
1107 return kStatus_USB_InvalidParameter;
1110 endpoint = epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK;
1111 direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1112 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
1114 if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS)
1116 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn = epCallback->callbackFn;
1117 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam =
1118 epCallback->callbackParam;
1119 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U;
1123 return kStatus_USB_InvalidParameter;
1125 return USB_DeviceControl(handle, kUSB_DeviceControlEndpointInit, epInit);
1129 * @brief De-initizlize a specified endpoint.
1131 * The function is used to de-initizlize a specified endpoint.
1133 * @param handle The device handle got from USB_DeviceInit.
1134 * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1136 * @retval kStatus_USB_Success The endpoint is de-initialized successfully.
1137 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1138 * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
1139 * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver.
1140 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1142 usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress)
1144 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
1145 uint8_t endpoint = endpointAddress & USB_ENDPOINT_NUMBER_MASK;
1146 uint8_t direction = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1147 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
1148 usb_status_t error = kStatus_USB_Error;
1149 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
1155 return kStatus_USB_InvalidHandle;
1157 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
1158 USB_OSA_ENTER_CRITICAL();
1159 deviceHandle->epCallbackDirectly = 1;
1160 USB_OSA_EXIT_CRITICAL();
1162 error = USB_DeviceControl(handle, kUSB_DeviceControlEndpointDeinit, &endpointAddress);
1163 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
1164 USB_OSA_ENTER_CRITICAL();
1165 deviceHandle->epCallbackDirectly = 0;
1166 USB_OSA_EXIT_CRITICAL();
1169 if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS)
1171 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn =
1172 (usb_device_endpoint_callback_t)NULL;
1173 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam = NULL;
1174 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U;
1178 return kStatus_USB_InvalidParameter;
1184 * @brief Stall a specified endpoint.
1186 * The function is used to stall a specified endpoint.
1188 * @param handle The device handle got from USB_DeviceInit.
1189 * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1191 * @retval kStatus_USB_Success The endpoint is stalled successfully.
1192 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1193 * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
1194 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1196 usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress)
1198 if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS)
1200 return USB_DeviceControl(handle, kUSB_DeviceControlEndpointStall, &endpointAddress);
1204 return kStatus_USB_InvalidParameter;
1209 * @brief Un-stall a specified endpoint.
1211 * The function is used to un-stall a specified endpoint.
1213 * @param handle The device handle got from USB_DeviceInit.
1214 * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1216 * @retval kStatus_USB_Success The endpoint is un-stalled successfully.
1217 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1218 * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
1219 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1221 usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress)
1223 if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS)
1225 return USB_DeviceControl(handle, kUSB_DeviceControlEndpointUnstall, &endpointAddress);
1229 return kStatus_USB_InvalidParameter;
1234 * @brief Get the status of the selected item.
1236 * The function is used to get the status of the selected item.
1238 * @param handle The device handle got from USB_DeviceInit.
1239 * @param type The selected item. Please refer to the structure usb_device_status_t.
1240 * @param param The param type is determined by the selected item.
1242 * @retval kStatus_USB_Success Get status successfully.
1243 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1244 * @retval kStatus_USB_InvalidParameter The param is NULL pointer.
1245 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1246 * @retval kStatus_USB_Error Unsupported type.
1248 usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param)
1251 usb_status_t error = kStatus_USB_Error;
1255 return kStatus_USB_InvalidParameter;
1259 case kUSB_DeviceStatusSpeed:
1260 error = USB_DeviceControl(handle, kUSB_DeviceControlGetSpeed, param);
1262 case kUSB_DeviceStatusOtg:
1263 error = USB_DeviceControl(handle, kUSB_DeviceControlGetOtgStatus, param);
1265 case kUSB_DeviceStatusDeviceState:
1266 temp8 = (uint8_t *)param;
1267 error = kStatus_USB_Success;
1268 *temp8 = ((usb_device_struct_t *)handle)->state;
1270 case kUSB_DeviceStatusAddress:
1271 temp8 = (uint8_t *)param;
1272 error = kStatus_USB_Success;
1273 *temp8 = ((usb_device_struct_t *)handle)->deviceAddress;
1275 case kUSB_DeviceStatusDevice:
1276 error = USB_DeviceControl(handle, kUSB_DeviceControlGetDeviceStatus, param);
1278 case kUSB_DeviceStatusEndpoint:
1279 error = USB_DeviceControl(handle, kUSB_DeviceControlGetEndpointStatus, param);
1281 case kUSB_DeviceStatusSynchFrame:
1282 error = USB_DeviceControl(handle, kUSB_DeviceControlGetSynchFrame, param);
1284 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1285 case kUSB_DeviceStatusRemoteWakeup:
1286 temp8 = (uint8_t *)param;
1287 error = kStatus_USB_Success;
1288 *temp8 = ((usb_device_struct_t *)handle)->remotewakeup;
1298 * @brief Set the status of the selected item.
1300 * The function is used to set the status of the selected item.
1302 * @param handle The device handle got from USB_DeviceInit.
1303 * @param type The selected item. Please refer to the structure usb_device_status_t.
1304 * @param param The param type is determined by the selected item.
1306 * @retval kStatus_USB_Success Set status successfully.
1307 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1308 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1309 * @retval kStatus_USB_Error Unsupported type, or the param is NULL pointer.
1311 usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param)
1313 usb_status_t error = kStatus_USB_Error;
1316 #if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) || \
1317 (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \
1318 (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U))
1319 case kUSB_DeviceStatusTestMode:
1320 error = USB_DeviceControl(handle, kUSB_DeviceControlSetTestMode, param);
1323 case kUSB_DeviceStatusOtg:
1324 error = USB_DeviceControl(handle, kUSB_DeviceControlSetOtgStatus, param);
1326 case kUSB_DeviceStatusDeviceState:
1329 error = kStatus_USB_Success;
1330 ((usb_device_struct_t *)handle)->state = (uint8_t)(*(uint8_t *)param);
1333 case kUSB_DeviceStatusAddress:
1334 if (kUSB_DeviceStateAddressing != ((usb_device_struct_t *)handle)->state)
1338 error = kStatus_USB_Success;
1339 ((usb_device_struct_t *)handle)->deviceAddress = (uint8_t)(*(uint8_t *)param);
1340 ((usb_device_struct_t *)handle)->state = kUSB_DeviceStateAddressing;
1345 error = USB_DeviceControl(handle, kUSB_DeviceControlSetDeviceAddress,
1346 &((usb_device_struct_t *)handle)->deviceAddress);
1349 case kUSB_DeviceStatusBusResume:
1350 error = USB_DeviceControl(handle, kUSB_DeviceControlResume, param);
1352 case kUSB_DeviceStatusBusSleepResume:
1353 error = USB_DeviceControl(handle, kUSB_DeviceControlSleepResume, param);
1355 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1356 case kUSB_DeviceStatusRemoteWakeup:
1359 error = kStatus_USB_Success;
1360 ((usb_device_struct_t *)handle)->remotewakeup = (uint8_t)(*(uint8_t *)param);
1364 case kUSB_DeviceStatusBusSuspend:
1365 error = USB_DeviceControl(handle, kUSB_DeviceControlSuspend, param);
1367 case kUSB_DeviceStatusBusSleep:
1368 error = USB_DeviceControl(handle, kUSB_DeviceControlSleep, param);
1376 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
1377 ((defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) || \
1378 (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
1380 * @brief Initializes the device dcd module.
1382 * The function initializes the device dcd module.
1384 * @param handle The device handle got from USB_DeviceInit.
1386 * @retval kStatus_USB_Success The device is run successfully.
1387 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1388 * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
1391 usb_status_t USB_DeviceDcdInitModule(usb_device_handle handle, void *time_param)
1393 return USB_DeviceControl(handle, kUSB_DeviceControlDcdInitModule, time_param);
1397 * @brief De-initializes the device dcd module.
1399 * The function de-intializes the device dcd module.
1401 * @param handle The device handle got from USB_DeviceInit.
1403 * @retval kStatus_USB_Success The device is run successfully.
1404 * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
1407 usb_status_t USB_DeviceDcdDeinitModule(usb_device_handle handle)
1409 return USB_DeviceControl(handle, kUSB_DeviceControlDcdDeinitModule, NULL);
1413 #if USB_DEVICE_CONFIG_USE_TASK
1415 * @brief Device task function.
1417 * The function is used to handle controller message.
1418 * This function should not be called in applicartion directly.
1420 * @param handle The device handle got from USB_DeviceInit.
1422 void USB_DeviceTaskFunction(void *deviceHandle)
1424 usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
1425 static usb_device_callback_message_struct_t message;
1429 /* Get the message from the queue */
1430 if (kStatus_USB_OSA_Success == USB_OsaMsgqRecv(handle->notificationQueue, (uint32_t *)&message, 0U))
1432 /* Handle the message */
1433 USB_DeviceNotification(handle, &message);
1440 * @brief Get dvice stack version function.
1442 * The function is used to get dvice stack version.
1444 * @param[out] version The version structure pointer to keep the device stack version.
1447 void USB_DeviceGetVersion(uint32_t *version)
1452 (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX);
1456 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1458 * @brief Update the hardware tick.
1460 * The function is used to update the hardware tick.
1462 * @param[in] handle The device handle got from #USB_DeviceInit.
1463 * @param[in] tick Current hardware tick.
1466 usb_status_t USB_DeviceUpdateHwTick(usb_device_handle handle, uint64_t tick)
1468 usb_device_struct_t *deviceHandle;
1469 usb_status_t status = kStatus_USB_Success;
1473 return kStatus_USB_InvalidHandle;
1475 deviceHandle = (usb_device_struct_t *)handle;
1477 deviceHandle->hwTick = tick;
1482 #endif /* USB_DEVICE_CONFIG_NUM */