1 /*
2 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2017 NXP
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * o Redistributions of source code must retain the above copyright notice, this list
9 * of conditions and the following disclaimer.
10 *
11 * o Redistributions in binary form must reproduce the above copyright notice, this
12 * list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * o Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include <usb/include/usb_device_config.h>
32 #include <usb/include/usb.h>
33
34 #include "usb_device.h"
35 #include "usb_device_dci.h"
36
37 #include "fsl_device_registers.h"
38
39 #if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U))
40
41 #if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
42 #include "usb_device_khci.h"
43 #endif
44
45 #if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
46 #include "usb_device_ehci.h"
47 #endif
48
49 #if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
50 ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
51 #include "usb_device_lpcip3511.h"
52 #endif
53
54 #if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
55 #include "fsl_cache.h"
56 #endif
57 /*******************************************************************************
58 * Definitions
59 ******************************************************************************/
60
61 /*******************************************************************************
62 * Prototypes
63 ******************************************************************************/
64 static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle);
65 static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle);
66 static usb_status_t USB_DeviceGetControllerInterface(
67 uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface);
68 static usb_status_t USB_DeviceTransfer(usb_device_handle handle,
69 uint8_t endpointAddress,
70 uint8_t *buffer,
71 uint32_t length);
72 static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param);
73 static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle,
74 usb_device_callback_message_struct_t *message);
75 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
76 static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle,
77 usb_device_callback_message_struct_t *message);
78 static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle,
79 usb_device_callback_message_struct_t *message);
80 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
81 static usb_status_t USB_DeviceSleepNotification(usb_device_struct_t *handle,
82 usb_device_callback_message_struct_t *message);
83
84 #endif
85 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
86 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
87 static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle,
88 usb_device_callback_message_struct_t *message);
89 static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle,
90 usb_device_callback_message_struct_t *message);
91 #endif
92 static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message);
93
94 /*******************************************************************************
95 * Variables
96 ******************************************************************************/
97
98 USB_GLOBAL static usb_device_struct_t s_UsbDevice[USB_DEVICE_CONFIG_NUM];
99
100 /*******************************************************************************
101 * Code
102 ******************************************************************************/
103
104 /*!
105 * @brief Allocate a device handle.
106 *
107 * This function allocates a device handle.
108 *
109 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
110 * @param handle It is out parameter, is used to return pointer of the device handle to the caller.
111 *
112 * @retval kStatus_USB_Success Get a device handle successfully.
113 * @retval kStatus_USB_Busy Cannot allocate a device handle.
114 * @retval kStatus_USB_Error The device has been initialized.
115 */
USB_DeviceAllocateHandle(uint8_t controllerId,usb_device_struct_t ** handle)116 static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle)
117 {
118 uint32_t count;
119 USB_OSA_SR_ALLOC();
120
121 USB_OSA_ENTER_CRITICAL();
122 /* Check the controller is initialized or not. */
123 for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
124 {
125 if ((NULL != s_UsbDevice[count].controllerHandle) && (controllerId == s_UsbDevice[count].controllerId))
126 {
127 USB_OSA_EXIT_CRITICAL();
128 return kStatus_USB_Error;
129 }
130 }
131 /* Get a free device handle. */
132 for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
133 {
134 if (NULL == s_UsbDevice[count].controllerHandle)
135 {
136 s_UsbDevice[count].controllerId = controllerId;
137 *handle = &s_UsbDevice[count];
138 USB_OSA_EXIT_CRITICAL();
139 return kStatus_USB_Success;
140 }
141 }
142 USB_OSA_EXIT_CRITICAL();
143 return kStatus_USB_Busy;
144 }
145
146 /*!
147 * @brief Free a device handle.
148 *
149 * This function frees a device handle.
150 *
151 * @param handle The device handle.
152 *
153 * @retval kStatus_USB_Success Free device handle successfully.
154 */
USB_DeviceFreeHandle(usb_device_struct_t * handle)155 static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle)
156 {
157 USB_OSA_SR_ALLOC();
158
159 USB_OSA_ENTER_CRITICAL();
160 handle->controllerHandle = NULL;
161 handle->controllerId = 0U;
162 USB_OSA_EXIT_CRITICAL();
163 return kStatus_USB_Success;
164 }
165
166 #if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
167 /* KHCI device driver interface */
168 static const usb_device_controller_interface_struct_t s_UsbDeviceKhciInterface = {
169 USB_DeviceKhciInit, USB_DeviceKhciDeinit, USB_DeviceKhciSend,
170 USB_DeviceKhciRecv, USB_DeviceKhciCancel, USB_DeviceKhciControl
171 };
172 #endif
173
174 #if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
175 /* EHCI device driver interface */
176 static const usb_device_controller_interface_struct_t s_UsbDeviceEhciInterface = {
177 USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend,
178 USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl
179 };
180 #endif
181
182 #if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
183 ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
184 /* EHCI device driver interface */
185 static const usb_device_controller_interface_struct_t s_UsbDeviceLpc3511IpInterface = {
186 USB_DeviceLpc3511IpInit, USB_DeviceLpc3511IpDeinit, USB_DeviceLpc3511IpSend,
187 USB_DeviceLpc3511IpRecv, USB_DeviceLpc3511IpCancel, USB_DeviceLpc3511IpControl
188 };
189 #endif
190
191 /*!
192 * @brief Get the controller interface handle.
193 *
194 * This function is used to get the controller interface handle.
195 *
196 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
197 * @param controllerInterface It is out parameter, is used to return pointer of the device controller handle to the
198 * caller.
199 *
200 * @retval kStatus_USB_Success Get a device handle successfully.
201 * @retval kStatus_USB_ControllerNotFound The controller id is invalided.
202 */
USB_DeviceGetControllerInterface(uint8_t controllerId,const usb_device_controller_interface_struct_t ** controllerInterface)203 static usb_status_t USB_DeviceGetControllerInterface(
204 uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface)
205 {
206 usb_status_t error = kStatus_USB_ControllerNotFound;
207 switch (controllerId)
208 {
209 #if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
210 /* Get the KHCI controller driver interface */
211 case kUSB_ControllerKhci0:
212 case kUSB_ControllerKhci1:
213 *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceKhciInterface;
214 error = kStatus_USB_Success;
215 break;
216 #endif
217 #if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
218 /* Get the EHCI controller driver interface */
219 case kUSB_ControllerEhci0:
220 case kUSB_ControllerEhci1:
221 error = kStatus_USB_Success;
222 *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceEhciInterface;
223 break;
224 #endif
225 #if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
226 ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
227 /* Get the EHCI controller driver interface */
228 case kUSB_ControllerLpcIp3511Fs0:
229 case kUSB_ControllerLpcIp3511Fs1:
230 case kUSB_ControllerLpcIp3511Hs0:
231 case kUSB_ControllerLpcIp3511Hs1:
232 error = kStatus_USB_Success;
233 *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceLpc3511IpInterface;
234 break;
235 #endif
236 default:
237 break;
238 }
239 return error;
240 }
241
242 /*!
243 * @brief Start a new transfer.
244 *
245 * This function is used to start a new transfer.
246 *
247 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
248 * @param endpointAddress Endpoint address. Bit7 is direction, 0U - USB_OUT, 1U - USB_IN.
249 * @param buffer The memory address to be transferred, or the memory address to hold the data need to be
250 * sent.
251 * @param length The length of the data.
252 *
253 * @retval kStatus_USB_Success Get a device handle successfully.
254 * @retval kStatus_USB_InvalidHandle The device handle is invalided.
255 * @retval kStatus_USB_ControllerNotFound The controller interface is not found.
256 * @retval kStatus_USB_Error The device is doing reset.
257 */
USB_DeviceTransfer(usb_device_handle handle,uint8_t endpointAddress,uint8_t * buffer,uint32_t length)258 static usb_status_t USB_DeviceTransfer(usb_device_handle handle,
259 uint8_t endpointAddress,
260 uint8_t *buffer,
261 uint32_t length)
262 {
263 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
264 usb_status_t error = kStatus_USB_Error;
265 uint8_t endpoint = endpointAddress & USB_ENDPOINT_NUMBER_MASK;
266 uint8_t direction = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
267 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
268 USB_OSA_SR_ALLOC();
269
270 if (NULL == deviceHandle)
271 {
272 return kStatus_USB_InvalidHandle;
273 }
274
275 if (NULL != deviceHandle->controllerInterface)
276 {
277 if (deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy)
278 {
279 return kStatus_USB_Busy;
280 }
281 USB_OSA_ENTER_CRITICAL();
282 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 1U;
283 USB_OSA_EXIT_CRITICAL();
284 if (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)
285 {
286 #if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
287 if (length)
288 {
289 DCACHE_CleanByRange((uint32_t)buffer, length);
290 }
291 #endif
292 /* Call the controller send interface. */
293 error = deviceHandle->controllerInterface->deviceSend(deviceHandle->controllerHandle, endpointAddress,
294 buffer, length);
295 }
296 else
297 {
298 #if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
299 if (length)
300 {
301 DCACHE_CleanInvalidateByRange((uint32_t)buffer, length);
302 }
303 #endif
304 /* Call the controller receive interface. */
305 error = deviceHandle->controllerInterface->deviceRecv(deviceHandle->controllerHandle, endpointAddress,
306 buffer, length);
307 }
308 if (kStatus_USB_Success != error)
309 {
310 USB_OSA_ENTER_CRITICAL();
311 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U;
312 USB_OSA_EXIT_CRITICAL();
313 }
314 }
315 else
316 {
317 error = kStatus_USB_ControllerNotFound;
318 }
319 return error;
320 }
321
322 /*!
323 * @brief Control the status of the selected item.
324 *
325 * This function is used to control the status of the selected item..
326 *
327 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
328 * @param type The control type, please refer to the enumeration usb_device_control_type_t.
329 * @param param The param type is determined by the selected item.
330 *
331 * @retval kStatus_USB_Success Get a device handle successfully.
332 * @retval kStatus_USB_InvalidHandle The device handle is invalided.
333 * @retval kStatus_USB_ControllerNotFound The controller interface is not found.
334 * @retval kStatus_USB_Error Unsupport type.
335 * Or, the param is NULL pointer.
336 */
USB_DeviceControl(usb_device_handle handle,usb_device_control_type_t type,void * param)337 static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param)
338 {
339 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
340 usb_status_t error = kStatus_USB_Error;
341
342 if (NULL == deviceHandle)
343 {
344 return kStatus_USB_InvalidHandle;
345 }
346
347 if (NULL != deviceHandle->controllerInterface)
348 {
349 /* Call the controller control interface. */
350 error = deviceHandle->controllerInterface->deviceControl(deviceHandle->controllerHandle, type, param);
351 }
352 else
353 {
354 error = kStatus_USB_ControllerNotFound;
355 }
356 return error;
357 }
358
359 /*!
360 * @brief Handle the reset notification.
361 *
362 * This function is used to handle the reset notification.
363 *
364 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
365 * @param message The device callback message handle.
366 *
367 * @retval kStatus_USB_Success Get a device handle successfully.
368 */
USB_DeviceResetNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)369 static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle,
370 usb_device_callback_message_struct_t *message)
371 {
372 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
373 USB_OSA_SR_ALLOC();
374 #endif
375
376 handle->isResetting = 1U;
377
378 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
379 /* Clear remote wakeup feature */
380 handle->remotewakeup = 0U;
381 #endif
382
383 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
384 USB_OSA_ENTER_CRITICAL();
385 handle->epCallbackDirectly = 1;
386 USB_OSA_EXIT_CRITICAL();
387 #endif
388 /* Set the controller to default status. */
389 USB_DeviceControl(handle, kUSB_DeviceControlSetDefaultStatus, NULL);
390 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
391 USB_OSA_ENTER_CRITICAL();
392 handle->epCallbackDirectly = 0;
393 USB_OSA_EXIT_CRITICAL();
394 #endif
395
396 handle->state = kUSB_DeviceStateDefault;
397 handle->deviceAddress = 0U;
398
399 for (uint32_t count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++)
400 {
401 handle->epCallback[count].callbackFn = (usb_device_endpoint_callback_t)NULL;
402 handle->epCallback[count].callbackParam = NULL;
403 handle->epCallback[count].isBusy = 0U;
404 }
405
406 /* Call device callback to notify the application that the USB bus reset signal detected. */
407 handle->deviceCallback(handle, kUSB_DeviceEventBusReset, NULL);
408
409 handle->isResetting = 0U;
410 return kStatus_USB_Success;
411 }
412
413 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
414 /*!
415 * @brief Handle the suspend notification.
416 *
417 * This function is used to handle the suspend notification.
418 *
419 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
420 * @param message The device callback message handle.
421 *
422 * @return A USB error code or kStatus_USB_Success.
423 */
USB_DeviceSuspendNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)424 static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle,
425 usb_device_callback_message_struct_t *message)
426 {
427 /* Call device callback to notify the application that the USB bus suspend signal detected. */
428 return handle->deviceCallback(handle, kUSB_DeviceEventSuspend, NULL);
429 }
430
431 /*!
432 * @brief Handle the resume notification.
433 *
434 * This function is used to handle the resume notification.
435 *
436 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
437 * @param message The device callback message handle.
438 *
439 * @return A USB error code or kStatus_USB_Success.
440 */
USB_DeviceResumeNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)441 static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle,
442 usb_device_callback_message_struct_t *message)
443 {
444 /* Call device callback to notify the application that the USB bus resume signal detected. */
445 return handle->deviceCallback(handle, kUSB_DeviceEventResume, NULL);
446 }
447 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
448 /*!
449 * @brief Handle the suspend notification.
450 *
451 * This function is used to handle the suspend notification.
452 *
453 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
454 * @param message The device callback message handle.
455 *
456 * @return A USB error code or kStatus_USB_Success.
457 */
USB_DeviceSleepNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)458 static usb_status_t USB_DeviceSleepNotification(usb_device_struct_t *handle,
459 usb_device_callback_message_struct_t *message)
460 {
461 /* Call device callback to notify the application that the USB bus suspend signal detected. */
462 return handle->deviceCallback(handle, kUSB_DeviceEventSleeped, NULL);
463 }
464 #endif
465 /*!
466 * @brief Handle the remotewakeup notification.
467 *
468 * This function is used to handle the remotewakeup notification.
469 *
470 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
471 * @param flag The buffer pointer to store remotewakeup flag.
472 *
473 * @return A USB error code or kStatus_USB_Success.
474 */
USB_DeviceGetRemoteWakeUp(usb_device_struct_t * handle,uint8_t ** flag)475 usb_status_t USB_DeviceGetRemoteWakeUp(usb_device_struct_t *handle, uint8_t **flag)
476 {
477 /* Call device callback to notify the application that the USB bus suspend signal detected. */
478 return USB_DeviceControl(handle, kUSB_DeviceControlGetRemoteWakeUp, flag);
479 }
480
481 #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
482
483 #if (defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U))
USB_DeviceErrorNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)484 usb_status_t USB_DeviceErrorNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message)
485 {
486 /* Call device callback to notify the application that the USB bus error signal detected. */
487 return handle->deviceCallback(handle, kUSB_DeviceEventError, NULL);
488 }
489 #endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */
490
491 #if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
492 /*!
493 * @brief Handle the detach notification.
494 *
495 * This function is used to handle the detach notification.
496 *
497 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
498 * @param message The device callback message handle.
499 *
500 * @return A USB error code or kStatus_USB_Success.
501 */
USB_DeviceDetachNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)502 static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle,
503 usb_device_callback_message_struct_t *message)
504 {
505 /* Call device callback to notify the application that the device is disconnected from a host. */
506 return handle->deviceCallback(handle, kUSB_DeviceEventDetach, NULL);
507 }
508
509 /*!
510 * @brief Handle the attach notification.
511 *
512 * This function is used to handle the attach notification.
513 *
514 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
515 * @param message The device callback message handle.
516 *
517 * @return A USB error code or kStatus_USB_Success.
518 */
USB_DeviceAttachNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)519 static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle,
520 usb_device_callback_message_struct_t *message)
521 {
522 /* Call device callback to notify the application that the device is connected to a host. */
523 return handle->deviceCallback(handle, kUSB_DeviceEventAttach, NULL);
524 }
525 #endif
526
527 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
528 ((defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) || \
529 (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
530 /*!
531 * @brief Handle the dcd module timeout notification.
532 *
533 * This function is used to handle the dcd module timeout notification.
534 *
535 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
536 * @param message The device callback message handle.
537 *
538 * @return A USB error code or kStatus_USB_Success.
539 */
USB_DeviceDcdTimeOutNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)540 static usb_status_t USB_DeviceDcdTimeOutNotification(usb_device_struct_t *handle,
541 usb_device_callback_message_struct_t *message)
542 {
543 /* Call device callback to notify the application that the device charger detect timeout happened. */
544 return handle->deviceCallback(handle, kUSB_DeviceEventDcdTimeOut, NULL);
545 }
546
547 /*!
548 * @brief Handle the dcd module unknown port type notification.
549 *
550 * This function is used to handle the dcd module unknown port type notification.
551 *
552 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
553 * @param message The device callback message handle.
554 *
555 * @return A USB error code or kStatus_USB_Success.
556 */
USB_DeviceDcdUnknownPortTypeNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)557 static usb_status_t USB_DeviceDcdUnknownPortTypeNotification(usb_device_struct_t *handle,
558 usb_device_callback_message_struct_t *message)
559 {
560 /* Call device callback to notify the application that the device charger detect unknown port type happened. */
561 return handle->deviceCallback(handle, kUSB_DeviceEventDcdUnknownType, NULL);
562 }
563
564 /*!
565 * @brief Handle the SDP facility is detected notification.
566 *
567 * This function is used to handle the SDP facility is detectednotification.
568 *
569 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
570 * @param message The device callback message handle.
571 *
572 * @return A USB error code or kStatus_USB_Success.
573 */
USB_DeviceDcdSDPDetectNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)574 static usb_status_t USB_DeviceDcdSDPDetectNotification(usb_device_struct_t *handle,
575 usb_device_callback_message_struct_t *message)
576 {
577 /* Call device callback to notify the application that the SDP facility is detected. */
578 return handle->deviceCallback(handle, kUSB_DeviceEventSDPDetected, NULL);
579 }
580
581 /*!
582 * @brief Handle the charging port is detected notification.
583 *
584 * This function is used to handle the charging port is detectednotification.
585 *
586 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
587 * @param message The device callback message handle.
588 *
589 * @return A USB error code or kStatus_USB_Success.
590 */
USB_DeviceDcdChargingPortDetectNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)591 static usb_status_t USB_DeviceDcdChargingPortDetectNotification(usb_device_struct_t *handle,
592 usb_device_callback_message_struct_t *message)
593 {
594 /* Call device callback to notify the application that the charing port is detected. */
595 return handle->deviceCallback(handle, kUSB_DeviceEventChargingPortDetected, NULL);
596 }
597
598 /*!
599 * @brief Handle the CDP facility is detected notification.
600 *
601 * This function is used to handle the CDP facility is detectednotification.
602 *
603 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
604 * @param message The device callback message handle.
605 *
606 * @return A USB error code or kStatus_USB_Success.
607 */
USB_DeviceDcdChargingHostDetectNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)608 static usb_status_t USB_DeviceDcdChargingHostDetectNotification(usb_device_struct_t *handle,
609 usb_device_callback_message_struct_t *message)
610 {
611 /* Call device callback to notify the application that the CDP facility is detected. */
612 return handle->deviceCallback(handle, kUSB_DeviceEventChargingHostDetected, NULL);
613 }
614
615 /*!
616 * @brief Handle the DCP facility is detected notification.
617 *
618 * This function is used to handle the DCP facility is detectednotification.
619 *
620 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
621 * @param message The device callback message handle.
622 *
623 * @return A USB error code or kStatus_USB_Success.
624 */
625
USB_DeviceDcdDedicatedChargerDetectNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)626 static usb_status_t USB_DeviceDcdDedicatedChargerDetectNotification(usb_device_struct_t *handle,
627 usb_device_callback_message_struct_t *message)
628 {
629 /* Call device callback to notify the application that the DCP facility is detected. */
630 return handle->deviceCallback(handle, kUSB_DeviceEventDedicatedChargerDetected, NULL);
631 }
632 #endif
633
634 /*!
635 * @brief Handle the attach notification.
636 *
637 * This function is used to handle the attach notification.
638 *
639 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
640 * @param message The device callback message handle.
641 *
642 * @return A USB error code or kStatus_USB_Success.
643 */
USB_DeviceNotification(usb_device_struct_t * handle,usb_device_callback_message_struct_t * message)644 static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message)
645 {
646 uint8_t endpoint = message->code & USB_ENDPOINT_NUMBER_MASK;
647 uint8_t direction = (message->code & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
648 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
649 usb_status_t error = kStatus_USB_Error;
650
651 switch (message->code)
652 {
653 case kUSB_DeviceNotifyBusReset:
654 error = USB_DeviceResetNotification(handle, message);
655 break;
656 #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
657 case kUSB_DeviceNotifySuspend:
658 error = USB_DeviceSuspendNotification(handle, message);
659 break;
660 case kUSB_DeviceNotifyResume:
661 error = USB_DeviceResumeNotification(handle, message);
662 break;
663 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
664 case kUSB_DeviceNotifyLPMSleep:
665 error = USB_DeviceSleepNotification(handle, message);
666 break;
667 #endif
668 #endif
669
670 #if (defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U))
671 case kUSB_DeviceNotifyError:
672 error = USB_DeviceErrorNotification(handle, message);
673 break;
674 #endif
675
676 #if USB_DEVICE_CONFIG_DETACH_ENABLE
677 case kUSB_DeviceNotifyDetach:
678 error = USB_DeviceDetachNotification(handle, message);
679 break;
680 case kUSB_DeviceNotifyAttach:
681 error = USB_DeviceAttachNotification(handle, message);
682 break;
683 #endif
684 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
685 ((defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) || \
686 (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
687 case kUSB_DeviceNotifyDcdTimeOut:
688 error = USB_DeviceDcdTimeOutNotification(handle, message);
689 break;
690 case kUSB_DeviceNotifyDcdUnknownPortType:
691 error = USB_DeviceDcdUnknownPortTypeNotification(handle, message);
692 break;
693 case kUSB_DeviceNotifySDPDetected:
694 error = USB_DeviceDcdSDPDetectNotification(handle, message);
695 break;
696 case kUSB_DeviceNotifyChargingPortDetected:
697 error = USB_DeviceDcdChargingPortDetectNotification(handle, message);
698 break;
699 case kUSB_DeviceNotifyChargingHostDetected:
700 error = USB_DeviceDcdChargingHostDetectNotification(handle, message);
701 break;
702 case kUSB_DeviceNotifyDedicatedChargerDetected:
703 error = USB_DeviceDcdDedicatedChargerDetectNotification(handle, message);
704 break;
705 #endif
706
707 default:
708 if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS)
709 {
710 if (handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn)
711 {
712 usb_device_endpoint_callback_message_struct_t endpointCallbackMessage;
713 endpointCallbackMessage.buffer = message->buffer;
714 endpointCallbackMessage.length = message->length;
715 endpointCallbackMessage.isSetup = message->isSetup;
716 if (message->isSetup)
717 {
718 handle->epCallback[0].isBusy = 0U;
719 handle->epCallback[1].isBusy = 0U;
720 }
721 else
722 {
723 handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U;
724 }
725 /* Call endpoint callback */
726 error = handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn(
727 handle, &endpointCallbackMessage,
728 handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam);
729 }
730 }
731 break;
732 }
733 return error;
734 }
735
736 /*!
737 * @brief Notify the device that the controller status changed.
738 *
739 * This function is used to notify the device that the controller status changed.
740 *
741 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
742 * @param message The device callback message handle.
743 *
744 * @return A USB error code or kStatus_USB_Success.
745 */
USB_DeviceNotificationTrigger(void * handle,void * msg)746 usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg)
747 {
748 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
749 usb_device_callback_message_struct_t *message = (usb_device_callback_message_struct_t *)msg;
750
751 if ((NULL == msg) || (NULL == handle))
752 {
753 return kStatus_USB_InvalidHandle;
754 }
755
756 /* The device callback is invalid or not. */
757 if (!deviceHandle->deviceCallback)
758 {
759 return kStatus_USB_Error;
760 }
761
762 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
763 if (deviceHandle->epCallbackDirectly)
764 {
765 if ((message->code & USB_ENDPOINT_NUMBER_MASK) && (!(message->code & 0x70U)))
766 {
767 return USB_DeviceNotification(deviceHandle, message);
768 }
769 }
770
771 /* Add the message to message queue when the device task is enabled. */
772 if (kStatus_USB_OSA_Success != USB_OsaMsgqSend(deviceHandle->notificationQueue, (void *)message))
773 {
774 return kStatus_USB_Busy;
775 }
776 return kStatus_USB_Success;
777 #else
778 /* Handle the notification by calling USB_DeviceNotification. */
779 return USB_DeviceNotification(deviceHandle, message);
780 #endif
781 }
782
783 /*!
784 * @brief Initialize the USB device stack.
785 *
786 * This function initializes the USB device module specified by the controllerId.
787 *
788 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
789 * @param deviceCallback Function pointer of the device callback.
790 * @param handle It is out parameter, is used to return pointer of the device handle to the caller.
791 *
792 * @retval kStatus_USB_Success The device is initialized successfully.
793 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer.
794 * @retval kStatus_USB_Busy Cannot allocate a device handle.
795 * @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller id.
796 * @retval kStatus_USB_InvalidControllerInterface The controller driver interfaces is invaild, There is an empty
797 * interface entity.
798 * @retval kStatus_USB_Error The macro USB_DEVICE_CONFIG_ENDPOINTS is more than IP's endpoint number.
799 * Or, the device has been initialized.
800 * Or, the message queue is created failed.
801 */
USB_DeviceInit(uint8_t controllerId,usb_device_callback_t deviceCallback,usb_device_handle * handle)802 usb_status_t USB_DeviceInit(uint8_t controllerId, usb_device_callback_t deviceCallback, usb_device_handle *handle)
803 {
804 usb_device_struct_t *deviceHandle = NULL;
805 usb_status_t error;
806 uint32_t count;
807
808 if (NULL == handle)
809 {
810 return kStatus_USB_InvalidHandle;
811 }
812
813 /* Allocate a device handle by using the controller id. */
814 error = USB_DeviceAllocateHandle(controllerId, &deviceHandle);
815
816 if (kStatus_USB_Success != error)
817 {
818 return error;
819 }
820
821 /* Save the device callback */
822 deviceHandle->deviceCallback = deviceCallback;
823 /* Save the controller id */
824 deviceHandle->controllerId = controllerId;
825 /* Clear the device address */
826 deviceHandle->deviceAddress = 0U;
827 /* Clear the device reset state */
828 deviceHandle->isResetting = 0U;
829
830 /* Initialize the enpoints */
831 for (count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++)
832 {
833 deviceHandle->epCallback[count].callbackFn = (usb_device_endpoint_callback_t)NULL;
834 deviceHandle->epCallback[count].callbackParam = NULL;
835 deviceHandle->epCallback[count].isBusy = 0U;
836 }
837
838 /* Get the controller interface according to the controller id */
839 error = USB_DeviceGetControllerInterface(controllerId, &deviceHandle->controllerInterface);
840 if (kStatus_USB_Success != error)
841 {
842 USB_DeviceFreeHandle(deviceHandle);
843 return error;
844 }
845 if (NULL == deviceHandle->controllerInterface)
846 {
847 USB_DeviceFreeHandle(deviceHandle);
848 return kStatus_USB_ControllerNotFound;
849 }
850 if (((usb_device_controller_init_t)NULL == deviceHandle->controllerInterface->deviceInit) ||
851 ((usb_device_controller_deinit_t)NULL == deviceHandle->controllerInterface->deviceDeinit) ||
852 ((usb_device_controller_send_t)NULL == deviceHandle->controllerInterface->deviceSend) ||
853 ((usb_device_controller_recv_t)NULL == deviceHandle->controllerInterface->deviceRecv) ||
854 ((usb_device_controller_cancel_t)NULL == deviceHandle->controllerInterface->deviceCancel) ||
855 ((usb_device_controller_control_t)NULL == deviceHandle->controllerInterface->deviceControl))
856 {
857 USB_DeviceFreeHandle(deviceHandle);
858 return kStatus_USB_InvalidControllerInterface;
859 }
860
861 #if USB_DEVICE_CONFIG_USE_TASK
862 /* Create a message queue when the device handle is enabled. */
863 if (kStatus_USB_OSA_Success !=
864 USB_OsaMsgqCreate(&deviceHandle->notificationQueue, USB_DEVICE_CONFIG_MAX_MESSAGES,
865 (1U + (sizeof(usb_device_callback_message_struct_t) - 1U) / sizeof(uint32_t))))
866 {
867 USB_DeviceDeinit(deviceHandle);
868 return kStatus_USB_Error;
869 }
870 #endif
871
872 *handle = deviceHandle;
873
874 /* Initialize the controller */
875 error = deviceHandle->controllerInterface->deviceInit(controllerId, deviceHandle, &deviceHandle->controllerHandle);
876 if (kStatus_USB_Success != error)
877 {
878 USB_DeviceDeinit(deviceHandle);
879 *handle = NULL;
880 return error;
881 }
882 /* Set the device to deafult state */
883 deviceHandle->state = kUSB_DeviceStateDefault;
884
885 return error;
886 }
887
888 /*!
889 * @brief Enable the device functionality.
890 *
891 * The function enables the device functionality, so that the device can be recognized by the host when the device
892 * detects that it has been connected to a host.
893 *
894 * @param handle The device handle got from USB_DeviceInit.
895 *
896 * @retval kStatus_USB_Success The device is run successfully.
897 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
898 * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
899 *
900 */
USB_DeviceRun(usb_device_handle handle)901 usb_status_t USB_DeviceRun(usb_device_handle handle)
902 {
903 return USB_DeviceControl(handle, kUSB_DeviceControlRun, NULL);
904 }
905 /*!
906 * @brief Disable the device functionality.
907 *
908 * The function disables the device functionality, after this function called, even the device is detached to the host,
909 * and the device can't work.
910 *
911 * @param handle The device handle got from USB_DeviceInit.
912 *
913 * @retval kStatus_USB_Success The device is stopped successfully.
914 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
915 * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
916 */
USB_DeviceStop(usb_device_handle handle)917 usb_status_t USB_DeviceStop(usb_device_handle handle)
918 {
919 return USB_DeviceControl(handle, kUSB_DeviceControlStop, NULL);
920 }
921 /*!
922 * @brief De-initialize the device controller.
923 *
924 * The function de-initializes the device controller specified by the handle.
925 *
926 * @param handle The device handle got from USB_DeviceInit.
927 *
928 * @retval kStatus_USB_Success The device is stopped successfully.
929 * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
930 */
USB_DeviceDeinit(usb_device_handle handle)931 usb_status_t USB_DeviceDeinit(usb_device_handle handle)
932 {
933 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
934
935 if (NULL == deviceHandle)
936 {
937 return kStatus_USB_InvalidHandle;
938 }
939 /* De-initialize the controller */
940 if (NULL != deviceHandle->controllerInterface)
941 {
942 deviceHandle->controllerInterface->deviceDeinit(deviceHandle->controllerHandle);
943 deviceHandle->controllerInterface = (usb_device_controller_interface_struct_t *)NULL;
944 }
945
946 #if USB_DEVICE_CONFIG_USE_TASK
947 /* Destroy the message queue. */
948 if (NULL != deviceHandle->notificationQueue)
949 {
950 USB_OsaMsgqDestroy(deviceHandle->notificationQueue);
951 deviceHandle->notificationQueue = NULL;
952 }
953 #endif
954
955 /* Free the device handle. */
956 USB_DeviceFreeHandle(deviceHandle);
957 return kStatus_USB_Success;
958 }
959
960 /*!
961 * @brief Send data through a specified endpoint.
962 *
963 * The function is used to send data through a specified endpoint.
964 *
965 * @param handle The device handle got from USB_DeviceInit.
966 * @param endpointAddress Endpoint index.
967 * @param buffer The memory address to hold the data need to be sent.
968 * @param length The data length need to be sent.
969 *
970 * @retval kStatus_USB_Success The send request is sent successfully.
971 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
972 * @retval kStatus_USB_Busy Cannot allocate dtds for current tansfer in EHCI driver.
973 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
974 * @retval kStatus_USB_Error The device is doing reset.
975 *
976 * @note The return value just means if the sending request is successful or not; the transfer done is notified by the
977 * corresponding callback function.
978 * Currently, only one transfer request can be supported for one specific endpoint.
979 * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
980 * should implement a queue in the application level.
981 * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
982 * callback).
983 */
USB_DeviceSendRequest(usb_device_handle handle,uint8_t endpointAddress,uint8_t * buffer,uint32_t length)984 usb_status_t USB_DeviceSendRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length)
985 {
986 return USB_DeviceTransfer(handle, (endpointAddress & USB_ENDPOINT_NUMBER_MASK) |
987 (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
988 buffer, length);
989 }
990
991 /*!
992 * @brief Receive data through a specified endpoint.
993 *
994 * The function is used to receive data through a specified endpoint.
995 *
996 * @param handle The device handle got from USB_DeviceInit.
997 * @param endpointAddress Endpoint index.
998 * @param buffer The memory address to save the received data.
999 * @param length The data length want to be received.
1000 *
1001 * @retval kStatus_USB_Success The receive request is sent successfully.
1002 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1003 * @retval kStatus_USB_Busy Cannot allocate dtds for current tansfer in EHCI driver.
1004 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1005 * @retval kStatus_USB_Error The device is doing reset.
1006 *
1007 * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the
1008 * corresponding callback function.
1009 * Currently, only one transfer request can be supported for one specific endpoint.
1010 * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1011 * should implement a queue in the application level.
1012 * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1013 * callback).
1014 */
USB_DeviceRecvRequest(usb_device_handle handle,uint8_t endpointAddress,uint8_t * buffer,uint32_t length)1015 usb_status_t USB_DeviceRecvRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length)
1016 {
1017 return USB_DeviceTransfer(handle, (endpointAddress & USB_ENDPOINT_NUMBER_MASK) |
1018 (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
1019 buffer, length);
1020 }
1021
1022 /*!
1023 * @brief Cancel the pending transfer in a specified endpoint.
1024 *
1025 * The function is used to cancel the pending transfer in a specified endpoint.
1026 *
1027 * @param handle The device handle got from USB_DeviceInit.
1028 * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1029 *
1030 * @retval kStatus_USB_Success The transfer is cancelled.
1031 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1032 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1033 */
USB_DeviceCancel(usb_device_handle handle,uint8_t endpointAddress)1034 usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress)
1035 {
1036 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
1037 usb_status_t error = kStatus_USB_Error;
1038
1039 if (NULL == deviceHandle)
1040 {
1041 return kStatus_USB_InvalidHandle;
1042 }
1043
1044 if (NULL != deviceHandle->controllerInterface)
1045 {
1046 error = deviceHandle->controllerInterface->deviceCancel(deviceHandle->controllerHandle, endpointAddress);
1047 }
1048 else
1049 {
1050 error = kStatus_USB_ControllerNotFound;
1051 }
1052 return error;
1053 }
1054
1055 /*!
1056 * @brief Initialize a specified endpoint.
1057 *
1058 * The function is used to initialize a specified endpoint and the corresponding endpoint callback is also initialized.
1059 *
1060 * @param handle The device handle got from USB_DeviceInit.
1061 * @param epInit Endpoint initizlization structure. Please refer to the structure usb_device_endpoint_init_struct_t.
1062 * @param epCallback Endpoint callback structure. Please refer to the structure
1063 * usb_device_endpoint_callback_struct_t.
1064 *
1065 * @retval kStatus_USB_Success The endpoint is initialized successfully.
1066 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1067 * @retval kStatus_USB_InvalidParameter The epInit or epCallback is NULL pointer. Or the endpoint number is
1068 * more than USB_DEVICE_CONFIG_ENDPOINTS.
1069 * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver.
1070 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1071 */
USB_DeviceInitEndpoint(usb_device_handle handle,usb_device_endpoint_init_struct_t * epInit,usb_device_endpoint_callback_struct_t * epCallback)1072 usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle,
1073 usb_device_endpoint_init_struct_t *epInit,
1074 usb_device_endpoint_callback_struct_t *epCallback)
1075 {
1076 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
1077 uint8_t endpoint;
1078 uint8_t direction;
1079
1080 if (!deviceHandle)
1081 {
1082 return kStatus_USB_InvalidHandle;
1083 }
1084
1085 if ((!epInit) || (!epCallback))
1086 {
1087 return kStatus_USB_InvalidParameter;
1088 }
1089
1090 endpoint = epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK;
1091 direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1092 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
1093
1094 if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS)
1095 {
1096 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn = epCallback->callbackFn;
1097 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam =
1098 epCallback->callbackParam;
1099 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U;
1100 }
1101 else
1102 {
1103 return kStatus_USB_InvalidParameter;
1104 }
1105 return USB_DeviceControl(handle, kUSB_DeviceControlEndpointInit, epInit);
1106 }
1107
1108 /*!
1109 * @brief De-initizlize a specified endpoint.
1110 *
1111 * The function is used to de-initizlize a specified endpoint.
1112 *
1113 * @param handle The device handle got from USB_DeviceInit.
1114 * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1115 *
1116 * @retval kStatus_USB_Success The endpoint is de-initialized successfully.
1117 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1118 * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
1119 * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver.
1120 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1121 */
USB_DeviceDeinitEndpoint(usb_device_handle handle,uint8_t endpointAddress)1122 usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress)
1123 {
1124 usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
1125 uint8_t endpoint = endpointAddress & USB_ENDPOINT_NUMBER_MASK;
1126 uint8_t direction = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
1127 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
1128 usb_status_t error = kStatus_USB_Error;
1129 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
1130 USB_OSA_SR_ALLOC();
1131 #endif
1132
1133 if (!deviceHandle)
1134 {
1135 return kStatus_USB_InvalidHandle;
1136 }
1137 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
1138 USB_OSA_ENTER_CRITICAL();
1139 deviceHandle->epCallbackDirectly = 1;
1140 USB_OSA_EXIT_CRITICAL();
1141 #endif
1142 error = USB_DeviceControl(handle, kUSB_DeviceControlEndpointDeinit, &endpointAddress);
1143 #if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U))
1144 USB_OSA_ENTER_CRITICAL();
1145 deviceHandle->epCallbackDirectly = 0;
1146 USB_OSA_EXIT_CRITICAL();
1147 #endif
1148
1149 if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS)
1150 {
1151 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn =
1152 (usb_device_endpoint_callback_t)NULL;
1153 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam = NULL;
1154 deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U;
1155 }
1156 else
1157 {
1158 return kStatus_USB_InvalidParameter;
1159 }
1160 return error;
1161 }
1162
1163 /*!
1164 * @brief Stall a specified endpoint.
1165 *
1166 * The function is used to stall a specified endpoint.
1167 *
1168 * @param handle The device handle got from USB_DeviceInit.
1169 * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1170 *
1171 * @retval kStatus_USB_Success The endpoint is stalled successfully.
1172 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1173 * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
1174 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1175 */
USB_DeviceStallEndpoint(usb_device_handle handle,uint8_t endpointAddress)1176 usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress)
1177 {
1178 if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS)
1179 {
1180 return USB_DeviceControl(handle, kUSB_DeviceControlEndpointStall, &endpointAddress);
1181 }
1182 else
1183 {
1184 return kStatus_USB_InvalidParameter;
1185 }
1186 }
1187
1188 /*!
1189 * @brief Un-stall a specified endpoint.
1190 *
1191 * The function is used to un-stall a specified endpoint.
1192 *
1193 * @param handle The device handle got from USB_DeviceInit.
1194 * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
1195 *
1196 * @retval kStatus_USB_Success The endpoint is un-stalled successfully.
1197 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1198 * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
1199 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1200 */
USB_DeviceUnstallEndpoint(usb_device_handle handle,uint8_t endpointAddress)1201 usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress)
1202 {
1203 if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS)
1204 {
1205 return USB_DeviceControl(handle, kUSB_DeviceControlEndpointUnstall, &endpointAddress);
1206 }
1207 else
1208 {
1209 return kStatus_USB_InvalidParameter;
1210 }
1211 }
1212
1213 /*!
1214 * @brief Get the status of the selected item.
1215 *
1216 * The function is used to get the status of the selected item.
1217 *
1218 * @param handle The device handle got from USB_DeviceInit.
1219 * @param type The selected item. Please refer to the structure usb_device_status_t.
1220 * @param param The param type is determined by the selected item.
1221 *
1222 * @retval kStatus_USB_Success Get status successfully.
1223 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1224 * @retval kStatus_USB_InvalidParameter The param is NULL pointer.
1225 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1226 * @retval kStatus_USB_Error Unsupported type.
1227 */
USB_DeviceGetStatus(usb_device_handle handle,usb_device_status_t type,void * param)1228 usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param)
1229 {
1230 uint8_t *temp8;
1231 usb_status_t error = kStatus_USB_Error;
1232
1233 if (NULL == param)
1234 {
1235 return kStatus_USB_InvalidParameter;
1236 }
1237 switch (type)
1238 {
1239 case kUSB_DeviceStatusSpeed:
1240 error = USB_DeviceControl(handle, kUSB_DeviceControlGetSpeed, param);
1241 break;
1242 case kUSB_DeviceStatusOtg:
1243 error = USB_DeviceControl(handle, kUSB_DeviceControlGetOtgStatus, param);
1244 break;
1245 case kUSB_DeviceStatusDeviceState:
1246 temp8 = (uint8_t *)param;
1247 error = kStatus_USB_Success;
1248 *temp8 = ((usb_device_struct_t *)handle)->state;
1249 break;
1250 case kUSB_DeviceStatusAddress:
1251 temp8 = (uint8_t *)param;
1252 error = kStatus_USB_Success;
1253 *temp8 = ((usb_device_struct_t *)handle)->deviceAddress;
1254 break;
1255 case kUSB_DeviceStatusDevice:
1256 error = USB_DeviceControl(handle, kUSB_DeviceControlGetDeviceStatus, param);
1257 break;
1258 case kUSB_DeviceStatusEndpoint:
1259 error = USB_DeviceControl(handle, kUSB_DeviceControlGetEndpointStatus, param);
1260 break;
1261 case kUSB_DeviceStatusSynchFrame:
1262 error = USB_DeviceControl(handle, kUSB_DeviceControlGetSynchFrame, param);
1263 break;
1264 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1265 case kUSB_DeviceStatusRemoteWakeup:
1266 temp8 = (uint8_t *)param;
1267 error = kStatus_USB_Success;
1268 *temp8 = ((usb_device_struct_t *)handle)->remotewakeup;
1269 break;
1270 #endif
1271 default:
1272 break;
1273 }
1274 return error;
1275 }
1276
1277 /*!
1278 * @brief Set the status of the selected item.
1279 *
1280 * The function is used to set the status of the selected item.
1281 *
1282 * @param handle The device handle got from USB_DeviceInit.
1283 * @param type The selected item. Please refer to the structure usb_device_status_t.
1284 * @param param The param type is determined by the selected item.
1285 *
1286 * @retval kStatus_USB_Success Set status successfully.
1287 * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
1288 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1289 * @retval kStatus_USB_Error Unsupported type, or the param is NULL pointer.
1290 */
USB_DeviceSetStatus(usb_device_handle handle,usb_device_status_t type,void * param)1291 usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param)
1292 {
1293 usb_status_t error = kStatus_USB_Error;
1294 switch (type)
1295 {
1296 #if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) || \
1297 (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \
1298 (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U))
1299 case kUSB_DeviceStatusTestMode:
1300 error = USB_DeviceControl(handle, kUSB_DeviceControlSetTestMode, param);
1301 break;
1302 #endif
1303 case kUSB_DeviceStatusOtg:
1304 error = USB_DeviceControl(handle, kUSB_DeviceControlSetOtgStatus, param);
1305 break;
1306 case kUSB_DeviceStatusDeviceState:
1307 if (NULL != param)
1308 {
1309 error = kStatus_USB_Success;
1310 ((usb_device_struct_t *)handle)->state = (uint8_t)(*(uint8_t *)param);
1311 }
1312 break;
1313 case kUSB_DeviceStatusAddress:
1314 if (kUSB_DeviceStateAddressing != ((usb_device_struct_t *)handle)->state)
1315 {
1316 if (NULL != param)
1317 {
1318 error = kStatus_USB_Success;
1319 ((usb_device_struct_t *)handle)->deviceAddress = (uint8_t)(*(uint8_t *)param);
1320 ((usb_device_struct_t *)handle)->state = kUSB_DeviceStateAddressing;
1321 }
1322 }
1323 else
1324 {
1325 error = USB_DeviceControl(handle, kUSB_DeviceControlSetDeviceAddress,
1326 &((usb_device_struct_t *)handle)->deviceAddress);
1327 }
1328 break;
1329 case kUSB_DeviceStatusBusResume:
1330 error = USB_DeviceControl(handle, kUSB_DeviceControlResume, param);
1331 break;
1332 case kUSB_DeviceStatusBusSleepResume:
1333 error = USB_DeviceControl(handle, kUSB_DeviceControlSleepResume, param);
1334 break;
1335 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1336 case kUSB_DeviceStatusRemoteWakeup:
1337 if (NULL != param)
1338 {
1339 error = kStatus_USB_Success;
1340 ((usb_device_struct_t *)handle)->remotewakeup = (uint8_t)(*(uint8_t *)param);
1341 }
1342 break;
1343 #endif
1344 case kUSB_DeviceStatusBusSuspend:
1345 error = USB_DeviceControl(handle, kUSB_DeviceControlSuspend, param);
1346 break;
1347 case kUSB_DeviceStatusBusSleep:
1348 error = USB_DeviceControl(handle, kUSB_DeviceControlSleep, param);
1349 break;
1350 default:
1351 break;
1352 }
1353 return error;
1354 }
1355
1356 #if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \
1357 ((defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) || \
1358 (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
1359 /*!
1360 * @brief Initializes the device dcd module.
1361 *
1362 * The function initializes the device dcd module.
1363 *
1364 * @param handle The device handle got from USB_DeviceInit.
1365 *
1366 * @retval kStatus_USB_Success The device is run successfully.
1367 * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
1368 * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
1369 *
1370 */
USB_DeviceDcdInitModule(usb_device_handle handle,void * time_param)1371 usb_status_t USB_DeviceDcdInitModule(usb_device_handle handle, void *time_param)
1372 {
1373 return USB_DeviceControl(handle, kUSB_DeviceControlDcdInitModule, time_param);
1374 }
1375
1376 /*!
1377 * @brief De-initializes the device dcd module.
1378 *
1379 * The function de-intializes the device dcd module.
1380 *
1381 * @param handle The device handle got from USB_DeviceInit.
1382 *
1383 * @retval kStatus_USB_Success The device is run successfully.
1384 * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
1385 *
1386 */
USB_DeviceDcdDeinitModule(usb_device_handle handle)1387 usb_status_t USB_DeviceDcdDeinitModule(usb_device_handle handle)
1388 {
1389 return USB_DeviceControl(handle, kUSB_DeviceControlDcdDeinitModule, NULL);
1390 }
1391 #endif
1392
1393 #if USB_DEVICE_CONFIG_USE_TASK
1394 /*!
1395 * @brief Device task function.
1396 *
1397 * The function is used to handle controller message.
1398 * This function should not be called in applicartion directly.
1399 *
1400 * @param handle The device handle got from USB_DeviceInit.
1401 */
USB_DeviceTaskFunction(void * deviceHandle)1402 void USB_DeviceTaskFunction(void *deviceHandle)
1403 {
1404 usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
1405 static usb_device_callback_message_struct_t message;
1406
1407 if (deviceHandle)
1408 {
1409 /* Get the message from the queue */
1410 if (kStatus_USB_OSA_Success == USB_OsaMsgqRecv(handle->notificationQueue, (uint32_t *)&message, 0U))
1411 {
1412 /* Handle the message */
1413 USB_DeviceNotification(handle, &message);
1414 }
1415 }
1416 }
1417 #endif
1418
1419 /*!
1420 * @brief Get dvice stack version function.
1421 *
1422 * The function is used to get dvice stack version.
1423 *
1424 * @param[out] version The version structure pointer to keep the device stack version.
1425 *
1426 */
USB_DeviceGetVersion(uint32_t * version)1427 void USB_DeviceGetVersion(uint32_t *version)
1428 {
1429 if (version)
1430 {
1431 *version =
1432 (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX);
1433 }
1434 }
1435
1436 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
1437 /*!
1438 * @brief Update the hardware tick.
1439 *
1440 * The function is used to update the hardware tick.
1441 *
1442 * @param[in] handle The device handle got from #USB_DeviceInit.
1443 * @param[in] tick Current hardware tick.
1444 *
1445 */
USB_DeviceUpdateHwTick(usb_device_handle handle,uint64_t tick)1446 usb_status_t USB_DeviceUpdateHwTick(usb_device_handle handle, uint64_t tick)
1447 {
1448 usb_device_struct_t *deviceHandle;
1449 usb_status_t status = kStatus_USB_Success;
1450
1451 if (handle == NULL)
1452 {
1453 return kStatus_USB_InvalidHandle;
1454 }
1455 deviceHandle = (usb_device_struct_t *)handle;
1456
1457 deviceHandle->hwTick = tick;
1458
1459 return status;
1460 }
1461 #endif
1462 #endif /* USB_DEVICE_CONFIG_NUM */
1463