usb_device_dci.c 59 KB

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