usb_device_dci.c 57 KB

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