usb_host_hci.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071
  1. /*
  2. * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016 - 2019 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include <usb/include/usb_host_config.h>
  9. #include "fsl_common.h"
  10. #include "usb_host.h"
  11. #include "usb_host_hci.h"
  12. #include "usb_host_devices.h"
  13. #include "fsl_device_registers.h"
  14. #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
  15. #include "fsl_cache.h"
  16. #endif
  17. /*******************************************************************************
  18. * Definitions
  19. ******************************************************************************/
  20. /* Component ID definition, used by tools. */
  21. #ifndef FSL_COMPONENT_ID
  22. #define FSL_COMPONENT_ID "middleware.usb.host_stack"
  23. #endif
  24. #if defined __CORTEX_M && (__CORTEX_M == 7U)
  25. #if (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
  26. #warning USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE is not supported.
  27. #endif
  28. #endif
  29. /*******************************************************************************
  30. * Prototypes
  31. ******************************************************************************/
  32. #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
  33. #include "usb_host_hub.h"
  34. #include "usb_host_hub_app.h"
  35. #endif
  36. /*!
  37. * @brief get the idle host instance.
  38. *
  39. * @return host instance pointer.
  40. */
  41. static usb_host_instance_t *USB_HostGetInstance(void);
  42. /*!
  43. * @brief release host instance.
  44. *
  45. * @param hostInstance host instance pointer.
  46. */
  47. static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance);
  48. /*!
  49. * @brief get the khci/ehci interface.
  50. *
  51. * @param controllerId controller id.
  52. * @param controllerTable return controller interface structure.
  53. */
  54. static void USB_HostGetControllerInterface(uint8_t controllerId,
  55. const usb_host_controller_interface_t **controllerTable);
  56. /*******************************************************************************
  57. * Variables
  58. ******************************************************************************/
  59. /*! @brief USB host instance resource */
  60. usb_host_instance_t g_UsbHostInstance[USB_HOST_CONFIG_MAX_HOST];
  61. #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
  62. #include "usb_host_ehci.h"
  63. static const usb_host_controller_interface_t s_EhciInterface = {
  64. USB_HostEhciCreate, USB_HostEhciDestory, USB_HostEhciOpenPipe, USB_HostEhciClosePipe,
  65. USB_HostEhciWritePipe, USB_HostEhciReadpipe, USB_HostEhciIoctl,
  66. };
  67. #endif /* USB_HOST_CONFIG_EHCI */
  68. #if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
  69. #include "usb_host_khci.h"
  70. static const usb_host_controller_interface_t s_KhciInterface = {
  71. USB_HostKhciCreate, USB_HostKhciDestory, USB_HostKhciOpenPipe, USB_HostKhciClosePipe,
  72. USB_HostKhciWritePipe, USB_HostKhciReadpipe, USB_HostKciIoctl,
  73. };
  74. #endif /* USB_HOST_CONFIG_KHCI */
  75. #if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
  76. #include "usb_host_ohci.h"
  77. static const usb_host_controller_interface_t s_OhciInterface = {
  78. USB_HostOhciCreate, USB_HostOhciDestory, USB_HostOhciOpenPipe, USB_HostOhciClosePipe,
  79. USB_HostOhciWritePipe, USB_HostOhciReadPipe, USB_HostOhciIoctl,
  80. };
  81. #endif /* USB_HOST_CONFIG_OHCI */
  82. #if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
  83. #include "usb_host_ip3516hs.h"
  84. static const usb_host_controller_interface_t s_Ip3516HsInterface = {
  85. USB_HostIp3516HsCreate, USB_HostIp3516HsDestory, USB_HostIp3516HsOpenPipe, USB_HostIp3516HsClosePipe,
  86. USB_HostIp3516HsWritePipe, USB_HostIp3516HsReadPipe, USB_HostIp3516HsIoctl,
  87. };
  88. #endif /* USB_HOST_CONFIG_IP3516HS */
  89. USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
  90. static uint8_t s_Setupbuffer[USB_HOST_CONFIG_MAX_HOST][USB_HOST_CONFIG_MAX_TRANSFERS][USB_DATA_ALIGN_SIZE_MULTIPLE(8)];
  91. /*******************************************************************************
  92. * Code
  93. ******************************************************************************/
  94. #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
  95. /*FUNCTION*----------------------------------------------------------------
  96. *
  97. * Function Name : usb_test_mode_init
  98. * Returned Value : None
  99. * Comments :
  100. * This function is called by common class to initialize the class driver. It
  101. * is called in response to a select interface call by application
  102. *
  103. *END*--------------------------------------------------------------------*/
  104. usb_status_t USB_HostTestModeInit(usb_device_handle deviceHandle)
  105. {
  106. #if (((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) || \
  107. ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS)))
  108. usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
  109. usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
  110. #endif
  111. uint32_t productId;
  112. uint32_t vendorId;
  113. (void)usb_echo("usb host test init\r\n");
  114. (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDevicePID, &productId);
  115. (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceVID, &vendorId);
  116. (void)usb_echo(" vendor id :0x%x product id:0x%x \r\n", vendorId, productId);
  117. if ((productId != 0x0200U) && (productId != 0x0101U) && (productId != 0x0102U) && (productId != 0x0103U) &&
  118. (productId != 0x0104U) && (productId != 0x0105U) && (productId != 0x0106U) && (productId != 0x0107U) &&
  119. (productId != 0x0108U))
  120. {
  121. (void)usb_echo("Unsupported Device\r\n");
  122. }
  123. if (productId == 0x0200U)
  124. {
  125. (void)usb_echo("PET test device attached\r\n");
  126. }
  127. else
  128. {
  129. #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
  130. if (hostInstance->controllerTable == &s_EhciInterface)
  131. {
  132. (void)hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostTestModeInit,
  133. (void *)deviceHandle);
  134. }
  135. #elif ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS))
  136. if (hostInstance->controllerTable == &s_Ip3516HsInterface)
  137. {
  138. (void)hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostTestModeInit,
  139. (void *)deviceHandle);
  140. }
  141. #endif
  142. }
  143. return kStatus_USB_Success;
  144. }
  145. #endif
  146. static usb_host_instance_t *USB_HostGetInstance(void)
  147. {
  148. uint8_t i = 0;
  149. uint32_t index = 0;
  150. void *temp;
  151. OSA_SR_ALLOC();
  152. OSA_ENTER_CRITICAL();
  153. for (; i < (uint8_t)USB_HOST_CONFIG_MAX_HOST; i++)
  154. {
  155. if (g_UsbHostInstance[i].occupied != 1U)
  156. {
  157. uint8_t *buffer = (uint8_t *)&g_UsbHostInstance[i];
  158. for (uint32_t j = 0U; j < sizeof(usb_host_instance_t); j++)
  159. {
  160. buffer[j] = 0x00U;
  161. }
  162. g_UsbHostInstance[i].occupied = 1;
  163. OSA_EXIT_CRITICAL();
  164. for (index = 0; index < (uint32_t)USB_HOST_CONFIG_MAX_TRANSFERS; ++index)
  165. {
  166. temp = (void *)&(s_Setupbuffer[i][index][0]);
  167. g_UsbHostInstance[i].transferList[index].setupPacket = (usb_setup_struct_t *)temp;
  168. }
  169. return &g_UsbHostInstance[i];
  170. }
  171. }
  172. OSA_EXIT_CRITICAL();
  173. return NULL;
  174. }
  175. static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance)
  176. {
  177. OSA_SR_ALLOC();
  178. OSA_ENTER_CRITICAL();
  179. hostInstance->occupied = 0;
  180. OSA_EXIT_CRITICAL();
  181. }
  182. static void USB_HostGetControllerInterface(uint8_t controllerId,
  183. const usb_host_controller_interface_t **controllerTable)
  184. {
  185. #if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
  186. if (controllerId == (uint8_t)kUSB_ControllerKhci0)
  187. {
  188. *controllerTable = &s_KhciInterface;
  189. }
  190. #endif /* USB_HOST_CONFIG_KHCI */
  191. #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
  192. if ((controllerId == (uint8_t)kUSB_ControllerEhci0) || (controllerId == (uint8_t)kUSB_ControllerEhci1))
  193. {
  194. *controllerTable = &s_EhciInterface;
  195. }
  196. #endif /* USB_HOST_CONFIG_EHCI */
  197. #if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
  198. if (controllerId == (uint8_t)kUSB_ControllerOhci0)
  199. {
  200. *controllerTable = &s_OhciInterface;
  201. }
  202. #endif /* USB_HOST_CONFIG_OHCI */
  203. #if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
  204. if (controllerId == (uint8_t)kUSB_ControllerIp3516Hs0)
  205. {
  206. *controllerTable = &s_Ip3516HsInterface;
  207. }
  208. #endif /* USB_HOST_CONFIG_IP3516HS */
  209. }
  210. usb_status_t USB_HostInit(uint8_t controllerId, usb_host_handle *hostHandle, host_callback_t callbackFn)
  211. {
  212. usb_status_t status = kStatus_USB_Success;
  213. usb_host_instance_t *hostInstance = NULL;
  214. usb_host_transfer_t *transferPrev = NULL;
  215. uint8_t i = 0;
  216. hostInstance = USB_HostGetInstance(); /* get one host instance */
  217. if (hostInstance == NULL)
  218. {
  219. return kStatus_USB_InvalidHandle;
  220. }
  221. /* get khci/ehci API table */
  222. USB_HostGetControllerInterface(controllerId, &hostInstance->controllerTable);
  223. if (hostInstance->controllerTable == NULL)
  224. {
  225. USB_HostReleaseInstance(hostInstance);
  226. return kStatus_USB_ControllerNotFound;
  227. }
  228. /* judge the controller interface one time at here */
  229. if ((hostInstance->controllerTable->controllerCreate == NULL) ||
  230. (hostInstance->controllerTable->controllerDestory == NULL) ||
  231. (hostInstance->controllerTable->controllerOpenPipe == NULL) ||
  232. (hostInstance->controllerTable->controllerClosePipe == NULL) ||
  233. (hostInstance->controllerTable->controllerWritePipe == NULL) ||
  234. (hostInstance->controllerTable->controllerReadPipe == NULL) ||
  235. (hostInstance->controllerTable->controllerIoctl == NULL))
  236. {
  237. return kStatus_USB_Error;
  238. }
  239. /* HOST instance init*/
  240. hostInstance->controllerId = controllerId;
  241. hostInstance->deviceCallback = callbackFn;
  242. hostInstance->deviceList = NULL;
  243. hostInstance->hostMutex = (osa_mutex_handle_t)(&hostInstance->mutexBuffer[0]);
  244. if (KOSA_StatusSuccess != OSA_MutexCreate(hostInstance->hostMutex))
  245. {
  246. USB_HostReleaseInstance(hostInstance);
  247. #ifdef HOST_ECHO
  248. usb_echo("host init: create host mutex fail\r\n");
  249. #endif
  250. return kStatus_USB_Error;
  251. }
  252. /* initialize transfer list */
  253. hostInstance->transferHead = &hostInstance->transferList[0];
  254. transferPrev = hostInstance->transferHead;
  255. for (i = 1; i < USB_HOST_CONFIG_MAX_TRANSFERS; ++i)
  256. {
  257. transferPrev->next = &hostInstance->transferList[i];
  258. transferPrev = transferPrev->next;
  259. }
  260. /* controller create, the callbackFn is initialized in USB_HostGetControllerInterface */
  261. status =
  262. hostInstance->controllerTable->controllerCreate(controllerId, hostInstance, &(hostInstance->controllerHandle));
  263. if ((status != kStatus_USB_Success) || (hostInstance->controllerHandle == NULL))
  264. {
  265. (void)OSA_MutexDestroy(hostInstance->hostMutex);
  266. USB_HostReleaseInstance(hostInstance);
  267. #ifdef HOST_ECHO
  268. usb_echo("host init: controller init fail\r\n");
  269. #endif
  270. return kStatus_USB_Error;
  271. }
  272. *hostHandle = hostInstance;
  273. return kStatus_USB_Success;
  274. }
  275. usb_status_t USB_HostDeinit(usb_host_handle hostHandle)
  276. {
  277. usb_status_t status = kStatus_USB_Success;
  278. usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
  279. usb_host_device_instance_t *deviceInstance = NULL;
  280. if (hostHandle == NULL)
  281. {
  282. return kStatus_USB_InvalidHandle;
  283. }
  284. /* device list detach */
  285. deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
  286. while (deviceInstance != NULL)
  287. {
  288. deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
  289. (void)USB_HostDetachDeviceInternal(hostHandle, deviceInstance);
  290. }
  291. /* controller instance destroy, the callbackFn is initialized in USB_HostGetControllerInterface */
  292. status = hostInstance->controllerTable->controllerDestory(hostInstance->controllerHandle);
  293. hostInstance->controllerHandle = NULL;
  294. if (status != kStatus_USB_Success)
  295. {
  296. #ifdef HOST_ECHO
  297. usb_echo("host controller destroy fail\r\n");
  298. #endif
  299. }
  300. /* resource release */
  301. if (NULL != hostInstance->hostMutex)
  302. {
  303. (void)OSA_MutexDestroy(hostInstance->hostMutex);
  304. hostInstance->hostMutex = NULL;
  305. }
  306. USB_HostReleaseInstance(hostInstance);
  307. return status;
  308. }
  309. usb_status_t USB_HostOpenPipe(usb_host_handle hostHandle,
  310. usb_host_pipe_handle *pipeHandle,
  311. usb_host_pipe_init_t *pipeInit)
  312. {
  313. usb_status_t status = kStatus_USB_Success;
  314. usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
  315. if ((hostHandle == NULL) || (pipeInit == NULL))
  316. {
  317. return kStatus_USB_InvalidHandle;
  318. }
  319. /* call controller open pipe interface, the callbackFn is initialized in USB_HostGetControllerInterface */
  320. status = hostInstance->controllerTable->controllerOpenPipe(hostInstance->controllerHandle, pipeHandle, pipeInit);
  321. return status;
  322. }
  323. usb_status_t USB_HostClosePipe(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle)
  324. {
  325. usb_status_t status = kStatus_USB_Success;
  326. usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
  327. if ((hostHandle == NULL) || (pipeHandle == NULL))
  328. {
  329. return kStatus_USB_InvalidHandle;
  330. }
  331. /* call controller close pipe interface, the callbackFn is initialized in USB_HostGetControllerInterface */
  332. status = hostInstance->controllerTable->controllerClosePipe(hostInstance->controllerHandle, pipeHandle);
  333. return status;
  334. }
  335. usb_status_t USB_HostSend(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer)
  336. {
  337. usb_status_t status = kStatus_USB_Success;
  338. usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
  339. if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
  340. {
  341. return kStatus_USB_InvalidHandle;
  342. }
  343. /* initialize transfer */
  344. transfer->transferSofar = 0;
  345. transfer->direction = USB_OUT;
  346. (void)USB_HostLock(); /* This api can be called by host task and app task */
  347. /* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
  348. */
  349. #if 0
  350. if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
  351. {
  352. USB_HostUnlock();
  353. return status;
  354. }
  355. #endif
  356. /* call controller write pipe interface */
  357. #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
  358. if (transfer->transferLength > 0)
  359. {
  360. DCACHE_CleanByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
  361. }
  362. #endif
  363. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  364. status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer);
  365. (void)USB_HostUnlock();
  366. return status;
  367. }
  368. usb_status_t USB_HostSendSetup(usb_host_handle hostHandle,
  369. usb_host_pipe_handle pipeHandle,
  370. usb_host_transfer_t *transfer)
  371. {
  372. usb_status_t status = kStatus_USB_Success;
  373. usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
  374. if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
  375. {
  376. return kStatus_USB_InvalidHandle;
  377. }
  378. /* initialize transfer */
  379. transfer->transferSofar = 0;
  380. transfer->next = NULL;
  381. transfer->setupStatus = 0;
  382. if ((transfer->setupPacket->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN)
  383. {
  384. transfer->direction = USB_IN;
  385. }
  386. else
  387. {
  388. transfer->direction = USB_OUT;
  389. }
  390. (void)USB_HostLock(); /* This API can be called by host task and application task */
  391. /* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
  392. */
  393. #if 0
  394. if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
  395. {
  396. USB_HostUnlock();
  397. return status;
  398. }
  399. #endif
  400. /* call controller write pipe interface */
  401. #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
  402. DCACHE_CleanByRange((uint32_t)&transfer->setupPacket->bmRequestType, sizeof(usb_setup_struct_t));
  403. if (transfer->transferLength > 0)
  404. {
  405. DCACHE_CleanInvalidateByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
  406. }
  407. #endif
  408. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  409. status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer);
  410. (void)USB_HostUnlock();
  411. return status;
  412. }
  413. usb_status_t USB_HostRecv(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer)
  414. {
  415. usb_status_t status = kStatus_USB_Success;
  416. usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
  417. if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
  418. {
  419. return kStatus_USB_InvalidHandle;
  420. }
  421. /* initialize transfer */
  422. transfer->transferSofar = 0;
  423. transfer->direction = USB_IN;
  424. (void)USB_HostLock(); /* This API can be called by host task and application task */
  425. /* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
  426. */
  427. #if 0
  428. if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
  429. {
  430. USB_HostUnlock();
  431. return status;
  432. }
  433. #endif
  434. #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
  435. if (transfer->transferLength > 0)
  436. {
  437. DCACHE_CleanInvalidateByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
  438. }
  439. #endif
  440. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  441. status = hostInstance->controllerTable->controllerReadPipe(hostInstance->controllerHandle, pipeHandle, transfer);
  442. (void)USB_HostUnlock();
  443. return status;
  444. }
  445. usb_status_t USB_HostCancelTransfer(usb_host_handle hostHandle,
  446. usb_host_pipe_handle pipeHandle,
  447. usb_host_transfer_t *transfer)
  448. {
  449. usb_status_t status = kStatus_USB_Success;
  450. usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
  451. usb_host_cancel_param_t cancelParam;
  452. if ((hostHandle == NULL) || (pipeHandle == NULL))
  453. {
  454. return kStatus_USB_InvalidHandle;
  455. }
  456. /* initialize cancel parameter */
  457. cancelParam.pipeHandle = pipeHandle;
  458. cancelParam.transfer = transfer;
  459. /* USB_HostLock(); This api can be called by host task and app task */
  460. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  461. status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostCancelTransfer,
  462. &cancelParam);
  463. /* USB_HostUnlock(); */
  464. return status;
  465. }
  466. usb_status_t USB_HostMallocTransfer(usb_host_handle hostHandle, usb_host_transfer_t **transfer)
  467. {
  468. usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
  469. if ((hostHandle == NULL) || (transfer == NULL))
  470. {
  471. return kStatus_USB_InvalidHandle;
  472. }
  473. /* get one from the transfer_head */
  474. (void)USB_HostLock();
  475. if (hostInstance->transferHead != NULL)
  476. {
  477. *transfer = hostInstance->transferHead;
  478. hostInstance->transferHead = hostInstance->transferHead->next;
  479. (void)USB_HostUnlock();
  480. return kStatus_USB_Success;
  481. }
  482. else
  483. {
  484. *transfer = NULL;
  485. (void)USB_HostUnlock();
  486. return kStatus_USB_Error;
  487. }
  488. }
  489. usb_status_t USB_HostFreeTransfer(usb_host_handle hostHandle, usb_host_transfer_t *transfer)
  490. {
  491. usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
  492. if (hostHandle == NULL)
  493. {
  494. return kStatus_USB_InvalidHandle;
  495. }
  496. if (transfer == NULL)
  497. {
  498. return kStatus_USB_Success;
  499. }
  500. /* release one to the transfer_head */
  501. (void)USB_HostLock();
  502. transfer->next = hostInstance->transferHead;
  503. hostInstance->transferHead = transfer;
  504. (void)USB_HostUnlock();
  505. return kStatus_USB_Success;
  506. }
  507. usb_status_t USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHandle,
  508. uint32_t infoCode,
  509. uint32_t *infoValue)
  510. {
  511. usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
  512. uint32_t *temp;
  513. usb_host_dev_info_t devInfo;
  514. if ((deviceHandle == NULL) || (infoValue == NULL))
  515. {
  516. return kStatus_USB_InvalidParameter;
  517. }
  518. devInfo = (usb_host_dev_info_t)infoCode;
  519. switch (devInfo)
  520. {
  521. case kUSB_HostGetDeviceAddress: /* device address */
  522. *infoValue = (uint32_t)deviceInstance->setAddress;
  523. break;
  524. case kUSB_HostGetDeviceControlPipe: /* device control pipe */
  525. temp = (uint32_t *)deviceInstance->controlPipe;
  526. *infoValue = (uint32_t)temp;
  527. break;
  528. case kUSB_HostGetHostHandle: /* device host handle */
  529. temp = (uint32_t *)deviceInstance->hostHandle;
  530. *infoValue = (uint32_t)temp;
  531. break;
  532. #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
  533. case kUSB_HostGetDeviceHubNumber: /* device hub address */
  534. *infoValue = (uint32_t)deviceInstance->hubNumber;
  535. break;
  536. case kUSB_HostGetDevicePortNumber: /* device port no */
  537. *infoValue = (uint32_t)deviceInstance->portNumber;
  538. break;
  539. case kUSB_HostGetDeviceLevel: /* device level */
  540. *infoValue = (uint32_t)deviceInstance->level;
  541. break;
  542. case kUSB_HostGetDeviceHSHubNumber: /* device high-speed hub address */
  543. *infoValue = (uint32_t)deviceInstance->hsHubNumber;
  544. break;
  545. case kUSB_HostGetDeviceHSHubPort: /* device high-speed hub port no */
  546. *infoValue = (uint32_t)deviceInstance->hsHubPort;
  547. break;
  548. case kUSB_HostGetHubThinkTime: /* device hub think time */
  549. *infoValue = USB_HostHubGetTotalThinkTime(deviceInstance->hostHandle, deviceInstance->hubNumber);
  550. break;
  551. #else
  552. case kUSB_HostGetDeviceHubNumber: /* device hub address */
  553. case kUSB_HostGetDevicePortNumber: /* device port no */
  554. case kUSB_HostGetDeviceHSHubNumber: /* device high-speed hub address */
  555. case kUSB_HostGetDeviceHSHubPort: /* device high-speed hub port no */
  556. case kUSB_HostGetHubThinkTime: /* device hub think time */
  557. *infoValue = 0;
  558. break;
  559. case kUSB_HostGetDeviceLevel: /* device level */
  560. *infoValue = 1;
  561. break;
  562. #endif /* USB_HOST_CONFIG_HUB */
  563. case kUSB_HostGetDeviceSpeed: /* device speed */
  564. *infoValue = (uint32_t)deviceInstance->speed;
  565. break;
  566. case kUSB_HostGetDevicePID: /* device pid */
  567. *infoValue = (uint32_t)USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(deviceInstance->deviceDescriptor->idProduct);
  568. break;
  569. case kUSB_HostGetDeviceVID: /* device vid */
  570. *infoValue = (uint32_t)USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(deviceInstance->deviceDescriptor->idVendor);
  571. break;
  572. case kUSB_HostGetDeviceConfigIndex: /* device config index */
  573. *infoValue = (uint32_t)deviceInstance->configurationValue - 1U;
  574. break;
  575. case kUSB_HostGetConfigurationDes: /* configuration descriptor pointer */
  576. *infoValue = (uint32_t)deviceInstance->configurationDesc;
  577. break;
  578. case kUSB_HostGetConfigurationLength: /* configuration descriptor length */
  579. *infoValue = (uint32_t)deviceInstance->configurationLen;
  580. break;
  581. default:
  582. /*no action*/
  583. break;
  584. }
  585. return kStatus_USB_Success;
  586. }
  587. usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle interfaceHandle,
  588. uint8_t alternateSetting,
  589. usb_host_interface_t *interface)
  590. {
  591. uint32_t endPosition;
  592. usb_descriptor_union_t *unionDes;
  593. usb_host_ep_t *epParse;
  594. void *temp;
  595. if (interfaceHandle == NULL)
  596. {
  597. return kStatus_USB_InvalidHandle;
  598. }
  599. if (alternateSetting == 0U)
  600. {
  601. return kStatus_USB_InvalidParameter;
  602. }
  603. /* parse configuration descriptor */
  604. #ifdef SOC_IMXRT1170_SERIES
  605. temp = (void *)((usb_host_interface_t *)interfaceHandle)->interfaceExtension;
  606. #else
  607. temp = (void *)((usb_host_interface_t *)interfaceHandle)->interfaceDesc;
  608. #endif
  609. unionDes = (usb_descriptor_union_t *)temp; /* interface extend descriptor start */
  610. endPosition =
  611. (uint32_t)unionDes +
  612. ((usb_host_interface_t *)interfaceHandle)->interfaceExtensionLength; /* interface extend descriptor end */
  613. #if !defined(SOC_IMXRT1170_SERIES)
  614. unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
  615. #endif
  616. /* search for the alternate setting interface descriptor */
  617. while ((uint32_t)unionDes < endPosition)
  618. {
  619. if (unionDes->interface.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE)
  620. {
  621. if (unionDes->interface.bAlternateSetting == alternateSetting)
  622. {
  623. break;
  624. }
  625. else
  626. {
  627. unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
  628. }
  629. }
  630. else
  631. {
  632. unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
  633. }
  634. }
  635. if ((uint32_t)unionDes >= endPosition)
  636. {
  637. return kStatus_USB_Error;
  638. }
  639. /* initialize interface handle structure instance */
  640. interface->interfaceDesc = &unionDes->interface;
  641. interface->alternateSettingNumber = 0U;
  642. interface->epCount = 0U;
  643. interface->interfaceExtension = NULL;
  644. interface->interfaceExtensionLength = 0U;
  645. interface->interfaceIndex = unionDes->interface.bInterfaceNumber;
  646. /* search for endpoint descriptor start position */
  647. unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
  648. while ((uint32_t)unionDes < endPosition)
  649. {
  650. if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) &&
  651. (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
  652. {
  653. if (interface->interfaceExtension == NULL)
  654. {
  655. interface->interfaceExtension = (uint8_t *)unionDes;
  656. }
  657. interface->interfaceExtensionLength += unionDes->common.bLength;
  658. unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
  659. }
  660. else
  661. {
  662. break;
  663. }
  664. }
  665. /* parse endpoint descriptor */
  666. if (interface->interfaceDesc->bNumEndpoints != 0U)
  667. {
  668. if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) ||
  669. (interface->interfaceDesc->bNumEndpoints > USB_HOST_CONFIG_INTERFACE_MAX_EP))
  670. {
  671. #ifdef HOST_ECHO
  672. usb_echo("interface descriptor error\n");
  673. #endif
  674. return kStatus_USB_Error;
  675. }
  676. for (; interface->epCount < interface->interfaceDesc->bNumEndpoints; (interface->epCount)++)
  677. {
  678. if (((uint32_t)unionDes >= endPosition) ||
  679. (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
  680. {
  681. #ifdef HOST_ECHO
  682. usb_echo("endpoint descriptor error\n");
  683. #endif
  684. return kStatus_USB_Error;
  685. }
  686. epParse = (usb_host_ep_t *)&interface->epList[interface->epCount];
  687. temp = (void *)unionDes;
  688. epParse->epDesc = (usb_descriptor_endpoint_t *)temp;
  689. epParse->epExtensionLength = 0;
  690. epParse->epExtension = NULL;
  691. unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
  692. while ((uint32_t)unionDes < endPosition)
  693. {
  694. if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) &&
  695. (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
  696. {
  697. if (epParse->epExtension == NULL)
  698. {
  699. epParse->epExtension = (uint8_t *)unionDes;
  700. }
  701. epParse->epExtensionLength += unionDes->common.bLength;
  702. unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
  703. }
  704. else
  705. {
  706. break;
  707. }
  708. }
  709. }
  710. }
  711. return kStatus_USB_Success;
  712. }
  713. void USB_HostGetVersion(uint32_t *version)
  714. {
  715. if (NULL != version)
  716. {
  717. *version =
  718. (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX);
  719. }
  720. }
  721. #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  722. /* Send BUS or specific device suspend request */
  723. usb_status_t USB_HostSuspendDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle)
  724. {
  725. usb_host_instance_t *hostInstance;
  726. usb_host_device_instance_t *deviceInstance;
  727. usb_status_t status = kStatus_USB_Error;
  728. usb_host_bus_control_t type = kUSB_HostBusSuspend;
  729. if (hostHandle == NULL)
  730. {
  731. return kStatus_USB_InvalidHandle;
  732. }
  733. hostInstance = (usb_host_instance_t *)hostHandle;
  734. hostInstance->suspendedDevice = (void *)deviceHandle;
  735. if (NULL == deviceHandle)
  736. {
  737. #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
  738. status = USB_HostHubSuspendDevice(hostInstance);
  739. #else
  740. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  741. status =
  742. hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
  743. #endif
  744. }
  745. else
  746. {
  747. #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
  748. deviceInstance = (usb_host_device_instance_t *)deviceHandle;
  749. if (0U == deviceInstance->hubNumber)
  750. {
  751. #endif
  752. if (hostInstance->deviceList == deviceHandle)
  753. {
  754. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  755. status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle,
  756. kUSB_HostBusControl, &type);
  757. }
  758. #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
  759. }
  760. else
  761. {
  762. if (kStatus_USB_Success == USB_HostValidateDevice(hostInstance, deviceHandle))
  763. {
  764. status = USB_HostHubSuspendDevice(hostInstance);
  765. }
  766. }
  767. #endif
  768. }
  769. if (kStatus_USB_Error == status)
  770. {
  771. hostInstance->suspendedDevice = NULL;
  772. }
  773. return status;
  774. }
  775. /* Send BUS or specific device resume request */
  776. usb_status_t USB_HostResumeDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle)
  777. {
  778. usb_host_instance_t *hostInstance;
  779. usb_host_device_instance_t *deviceInstance;
  780. usb_status_t status = kStatus_USB_Error;
  781. usb_host_bus_control_t type = kUSB_HostBusResume;
  782. if (hostHandle == NULL)
  783. {
  784. return kStatus_USB_InvalidHandle;
  785. }
  786. hostInstance = (usb_host_instance_t *)hostHandle;
  787. if (hostInstance->suspendedDevice != deviceHandle)
  788. {
  789. return kStatus_USB_InvalidParameter;
  790. }
  791. hostInstance->suspendedDevice = (void *)deviceHandle;
  792. if (NULL == deviceHandle)
  793. {
  794. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  795. status =
  796. hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
  797. }
  798. else
  799. {
  800. #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
  801. deviceInstance = (usb_host_device_instance_t *)deviceHandle;
  802. if (0U == deviceInstance->hubNumber)
  803. {
  804. #endif
  805. if (hostInstance->deviceList == deviceHandle)
  806. {
  807. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  808. status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle,
  809. kUSB_HostBusControl, &type);
  810. }
  811. #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
  812. }
  813. else
  814. {
  815. if (kStatus_USB_Success == USB_HostValidateDevice(hostInstance, deviceHandle))
  816. {
  817. status = USB_HostHubResumeDevice(hostInstance);
  818. }
  819. }
  820. #endif
  821. }
  822. return status;
  823. }
  824. #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
  825. /* Send BUS or specific device suspend request */
  826. usb_status_t USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle,
  827. usb_device_handle deviceHandle,
  828. uint8_t sleepType)
  829. {
  830. usb_host_instance_t *hostInstance;
  831. usb_status_t status = kStatus_USB_Error;
  832. usb_host_bus_control_t type = kUSB_HostBusL1Sleep;
  833. if (hostHandle == NULL)
  834. {
  835. return kStatus_USB_InvalidHandle;
  836. }
  837. hostInstance = (usb_host_instance_t *)hostHandle;
  838. hostInstance->suspendedDevice = (void *)deviceHandle;
  839. if (1U == sleepType)
  840. {
  841. /*#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))*/
  842. /*To do, incomplete hub L1 suspend device*/
  843. /*#else*/
  844. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  845. status =
  846. hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
  847. /*#endif*/
  848. }
  849. else
  850. {
  851. #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
  852. /*To do, if device hub number is 0, need suspend the bus ,else suspend the corresponding device*/
  853. #endif
  854. if (hostInstance->deviceList == deviceHandle)
  855. {
  856. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  857. status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
  858. &type);
  859. }
  860. }
  861. if (kStatus_USB_Error == status)
  862. {
  863. hostInstance->suspendedDevice = NULL;
  864. }
  865. return status;
  866. }
  867. /* Send BUS or specific device suspend request */
  868. usb_status_t USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle, uint8_t *lpmParam)
  869. {
  870. usb_host_instance_t *hostInstance;
  871. usb_status_t status = kStatus_USB_Error;
  872. if (hostHandle == NULL)
  873. {
  874. return kStatus_USB_InvalidHandle;
  875. }
  876. hostInstance = (usb_host_instance_t *)hostHandle;
  877. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  878. status =
  879. hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostL1Config, lpmParam);
  880. return status;
  881. }
  882. /* Send BUS or specific device resume request */
  883. usb_status_t USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle,
  884. usb_device_handle deviceHandle,
  885. uint8_t sleepType)
  886. {
  887. usb_host_instance_t *hostInstance;
  888. usb_status_t status = kStatus_USB_Error;
  889. usb_host_bus_control_t type = kUSB_HostBusL1Resume;
  890. if (hostHandle == NULL)
  891. {
  892. return kStatus_USB_InvalidHandle;
  893. }
  894. hostInstance = (usb_host_instance_t *)hostHandle;
  895. if (1U == sleepType)
  896. {
  897. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  898. status =
  899. hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
  900. }
  901. else
  902. {
  903. #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
  904. /*To do, if device hub number is 0, need suspend the bus ,else suspend the corresponding device*/
  905. #endif
  906. if (hostInstance->deviceList == deviceHandle)
  907. {
  908. /* the callbackFn is initialized in USB_HostGetControllerInterface */
  909. status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
  910. &type);
  911. }
  912. }
  913. return status;
  914. }
  915. #endif
  916. /* Update HW tick(unit is ms) */
  917. usb_status_t USB_HostUpdateHwTick(usb_host_handle hostHandle, uint64_t tick)
  918. {
  919. usb_host_instance_t *hostInstance;
  920. usb_status_t status = kStatus_USB_Success;
  921. if (hostHandle == NULL)
  922. {
  923. return kStatus_USB_InvalidHandle;
  924. }
  925. hostInstance = (usb_host_instance_t *)hostHandle;
  926. hostInstance->hwTick = tick;
  927. return status;
  928. }
  929. #endif
  930. #if ((defined(USB_HOST_CONFIG_BATTERY_CHARGER)) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U))
  931. usb_status_t USB_HostSetChargerType(usb_host_handle hostHandle, uint8_t type)
  932. {
  933. usb_host_instance_t *hostInstance;
  934. if (hostHandle == NULL)
  935. {
  936. return kStatus_USB_InvalidHandle;
  937. }
  938. hostInstance = (usb_host_instance_t *)hostHandle;
  939. return hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostSetChargerType,
  940. &type);
  941. }
  942. #endif