drv_usbh.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2017-10-30 ZYH the first version
  9. * 2019-12-19 tyustli port to stm32 series
  10. * 2021-01-19 Leslie Lee port to imxrt series
  11. */
  12. #include <rtthread.h>
  13. #if defined(BSP_USB0_HOST) || defined(BSP_USB1_HOST)
  14. #include "drv_usbh.h"
  15. #include <usb/include/usb_host_config.h>
  16. #include <usb/include/usb.h>
  17. #include <usb/phy/usb_phy.h>
  18. #include <usb/host/usb_host.h>
  19. #include <usb/host/usb_host_hci.h>
  20. #include <usb/host/usb_host_ehci.h>
  21. #include <rtdevice.h>
  22. /* USB PHY configuration */
  23. #ifndef BOARD_USB_PHY_D_CAL
  24. #ifdef SOC_IMXRT1170_SERIES
  25. #define BOARD_USB_PHY_D_CAL (0x07U)
  26. #else
  27. #define BOARD_USB_PHY_D_CAL (0x0CU)
  28. #endif
  29. #endif
  30. #ifndef BOARD_USB_PHY_TXCAL45DP
  31. #define BOARD_USB_PHY_TXCAL45DP (0x06U)
  32. #endif
  33. #ifndef BOARD_USB_PHY_TXCAL45DM
  34. #define BOARD_USB_PHY_TXCAL45DM (0x06U)
  35. #endif
  36. #define USB_HOST_INTERRUPT_PRIORITY 6
  37. /* Allocate the memory for the heap. */
  38. #if defined(configAPPLICATION_ALLOCATED_HEAP) && (configAPPLICATION_ALLOCATED_HEAP)
  39. USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) uint8_t ucHeap[configTOTAL_HEAP_SIZE];
  40. #endif
  41. enum
  42. {
  43. #ifdef BSP_USB0_HOST
  44. USBH0_INDEX,
  45. #endif
  46. #ifdef BSP_USB1_HOST
  47. USBH1_INDEX,
  48. #endif
  49. };
  50. struct imxrt_usb_host_pipe
  51. {
  52. usb_host_pipe_handle pipe_handle;
  53. struct rt_completion urb_completion;
  54. usb_status_t transfer_status;
  55. };
  56. struct imxrt_usb_host
  57. {
  58. struct uhcd uhcd;
  59. usb_host_handle host_handle;
  60. usb_device_handle device_handle;
  61. struct imxrt_usb_host_pipe pipes[16];
  62. volatile rt_bool_t connect_status;
  63. char *name;
  64. };
  65. static struct imxrt_usb_host imxrt_usb_host_obj[] =
  66. {
  67. #ifdef BSP_USB0_HOST
  68. {
  69. .connect_status = RT_FALSE,
  70. .name = "usbh0"
  71. },
  72. #endif
  73. #ifdef BSP_USB1_HOST
  74. {
  75. .connect_status = RT_FALSE,
  76. .name = "usbh1"
  77. },
  78. #endif
  79. };
  80. static void _imxrt_usb_host_send_callback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
  81. {
  82. struct imxrt_usb_host_pipe *pipe = (struct imxrt_usb_host_pipe *)param;
  83. pipe->transfer_status = status;
  84. rt_completion_done(&pipe->urb_completion);
  85. }
  86. /*!
  87. * @brief Initializes USB specific setting that was not set by the Clocks tool.
  88. */
  89. static void USB_HostClockInit(usb_controller_index_t controller_id)
  90. {
  91. uint32_t usbClockFreq;
  92. usb_phy_config_struct_t phyConfig = {
  93. BOARD_USB_PHY_D_CAL, BOARD_USB_PHY_TXCAL45DP, BOARD_USB_PHY_TXCAL45DM,
  94. };
  95. usbClockFreq = 24000000;
  96. if (controller_id == kUSB_ControllerEhci0)
  97. {
  98. CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, usbClockFreq);
  99. CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, usbClockFreq);
  100. }
  101. else
  102. {
  103. CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, usbClockFreq);
  104. CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, usbClockFreq);
  105. }
  106. USB_EhciPhyInit(controller_id, 24000000U, &phyConfig);
  107. }
  108. /*!
  109. * @brief Enables interrupt service routines for device.
  110. */
  111. void USB_HostIsrEnable(usb_controller_index_t controller_id)
  112. {
  113. uint8_t irqNumber;
  114. #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI > 0U))
  115. IRQn_Type usbHOSTEhciIrq[] = USBHS_IRQS;
  116. irqNumber = usbHOSTEhciIrq[controller_id - kUSB_ControllerEhci0];
  117. #endif
  118. /* Install isr, set priority, and enable IRQ. */
  119. #if defined(__GIC_PRIO_BITS)
  120. GIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY);
  121. #else
  122. NVIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY);
  123. #endif
  124. EnableIRQ((IRQn_Type)irqNumber);
  125. }
  126. #ifdef BSP_USB0_HOST
  127. void USB_OTG1_IRQHandler(void)
  128. {
  129. /* enter interrupt */
  130. rt_interrupt_enter();
  131. USB_HostEhciIsrFunction(imxrt_usb_host_obj[USBH0_INDEX].host_handle);
  132. /* leave interrupt */
  133. rt_interrupt_leave();
  134. }
  135. static rt_err_t _ehci0_reset_port(rt_uint8_t port)
  136. {
  137. // No reset port function available
  138. return RT_EOK;
  139. }
  140. static uint8_t _ehci0_pipe_buf[64];
  141. static uint8_t _ehci0_pipe_idx;
  142. static int _ehci0_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeouts)
  143. {
  144. // int timeout = timeouts;
  145. if (!imxrt_usb_host_obj[USBH0_INDEX].connect_status)
  146. {
  147. return -1;
  148. }
  149. usb_host_transfer_t *transfer;
  150. if (imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].pipe_handle == NULL)
  151. {
  152. RT_DEBUG_LOG(RT_DEBUG_USB, ("error operation on null pipe\n"));
  153. return -1;
  154. }
  155. if (USB_HostMallocTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, &transfer) != kStatus_USB_Success)
  156. {
  157. RT_DEBUG_LOG(RT_DEBUG_USB, ("error to get transfer\n"));
  158. return -1;
  159. }
  160. transfer->transferBuffer = buffer;
  161. transfer->transferLength = nbytes;
  162. transfer->transferSofar = 0;
  163. transfer->callbackFn = _imxrt_usb_host_send_callback;
  164. transfer->callbackParam = &(imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index]);
  165. transfer->direction = (pipe->ep.bEndpointAddress & USB_DIR_IN) ? USB_IN : USB_OUT;
  166. if (pipe->ep.bmAttributes == USB_ENDPOINT_CONTROL)
  167. {
  168. if (token == USBH_PID_SETUP)
  169. {
  170. struct urequest *setup = (struct urequest *)buffer;
  171. transfer->setupStatus = 0;
  172. transfer->setupPacket->bmRequestType = setup->request_type;
  173. transfer->setupPacket->bRequest = setup->bRequest;
  174. transfer->setupPacket->wIndex = setup->wIndex;
  175. transfer->setupPacket->wLength = setup->wLength;
  176. transfer->setupPacket->wValue = setup->wValue;
  177. transfer->transferBuffer = RT_NULL;
  178. transfer->transferLength = 0;
  179. transfer->next = RT_NULL;
  180. if ((transfer->setupPacket->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN)
  181. {
  182. transfer->direction = USB_IN;
  183. transfer->transferBuffer = _ehci0_pipe_buf;
  184. transfer->transferLength = setup->wLength;
  185. _ehci0_pipe_idx = 0;
  186. }
  187. else
  188. {
  189. transfer->direction = USB_OUT;
  190. }
  191. }
  192. else
  193. {
  194. rt_memcpy(buffer, _ehci0_pipe_buf + _ehci0_pipe_idx, nbytes);
  195. imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].transfer_status = kStatus_USB_Success;
  196. transfer->transferSofar = nbytes;
  197. _ehci0_pipe_idx += nbytes;
  198. if (_ehci0_pipe_idx >= 64)
  199. {
  200. _ehci0_pipe_idx = 0;
  201. }
  202. goto _ehci0_pipe_xfer_finish;
  203. }
  204. }
  205. rt_completion_init(&(imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].urb_completion));
  206. if (USB_HostEhciWritePipe(((usb_host_instance_t *)imxrt_usb_host_obj[USBH0_INDEX].host_handle)->controllerHandle, imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].pipe_handle, transfer) != kStatus_USB_Success)
  207. {
  208. RT_DEBUG_LOG(RT_DEBUG_USB, ("usb host failed to send\n"));
  209. (void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
  210. return -1;
  211. }
  212. if (-RT_ETIMEOUT == rt_completion_wait(&(imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].urb_completion), RT_WAITING_FOREVER))
  213. {
  214. RT_DEBUG_LOG(RT_DEBUG_USB, ("usb transfer timeout\n"));
  215. (void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
  216. return -1;
  217. }
  218. _ehci0_pipe_xfer_finish:
  219. switch (imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].transfer_status)
  220. {
  221. case kStatus_USB_Success:
  222. {
  223. RT_DEBUG_LOG(RT_DEBUG_USB, ("ok\n"));
  224. pipe->status = UPIPE_STATUS_OK;
  225. if (pipe->callback != RT_NULL)
  226. {
  227. pipe->callback(pipe);
  228. }
  229. size_t size = transfer->transferSofar;
  230. (void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
  231. if (pipe->ep.bEndpointAddress & 0x80)
  232. {
  233. return size;
  234. }
  235. else if (pipe->ep.bEndpointAddress & 0x00)
  236. {
  237. return size;
  238. }
  239. return nbytes;
  240. break;
  241. }
  242. case kStatus_USB_TransferStall:
  243. {
  244. RT_DEBUG_LOG(RT_DEBUG_USB, ("stall\n"));
  245. pipe->status = UPIPE_STATUS_STALL;
  246. if (pipe->callback != RT_NULL)
  247. {
  248. pipe->callback(pipe);
  249. }
  250. (void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
  251. return -1;
  252. break;
  253. }
  254. case kStatus_USB_TransferFailed:
  255. default:
  256. {
  257. RT_DEBUG_LOG(RT_DEBUG_USB, ("error\n"));
  258. pipe->status = UPIPE_STATUS_ERROR;
  259. if (pipe->callback != RT_NULL)
  260. {
  261. pipe->callback(pipe);
  262. }
  263. (void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
  264. return -1;
  265. break;
  266. }
  267. }
  268. }
  269. static rt_uint16_t _ehci0_pipe_index = 0;
  270. static rt_uint8_t _ehci0_get_free_pipe_index(void)
  271. {
  272. rt_uint8_t idx;
  273. for (idx = 1; idx < 16; idx++)
  274. {
  275. if (!(_ehci0_pipe_index & (0x01 << idx)))
  276. {
  277. _ehci0_pipe_index |= (0x01 << idx);
  278. return idx;
  279. }
  280. }
  281. return 0xff;
  282. }
  283. static void _ehci0_free_pipe_index(rt_uint8_t index)
  284. {
  285. _ehci0_pipe_index &= ~(0x01 << index);
  286. }
  287. static rt_err_t _ehci0_open_pipe(upipe_t pipe)
  288. {
  289. pipe->pipe_index = _ehci0_get_free_pipe_index();
  290. if (pipe->pipe_index == 0xFF)
  291. {
  292. return -RT_ERROR;
  293. }
  294. usb_host_pipe_init_t pipe_init =
  295. {
  296. .devInstance = imxrt_usb_host_obj[USBH0_INDEX].device_handle,
  297. .pipeType = pipe->ep.bmAttributes,
  298. .direction = (pipe->ep.bEndpointAddress & USB_DIR_IN) ? USB_IN : USB_OUT,
  299. .endpointAddress = (pipe->ep.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK),
  300. .interval = pipe->ep.bInterval,
  301. .maxPacketSize = (uint16_t)(pipe->ep.wMaxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK),
  302. .numberPerUframe = (uint8_t)(pipe->ep.wMaxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK),
  303. .nakCount = USB_HOST_CONFIG_MAX_NAK,
  304. };
  305. USB_HostOpenPipe(imxrt_usb_host_obj[USBH0_INDEX].host_handle, &imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].pipe_handle, &pipe_init);
  306. return RT_EOK;
  307. }
  308. static rt_err_t _ehci0_close_pipe(upipe_t pipe)
  309. {
  310. (void)USB_HostClosePipe(imxrt_usb_host_obj[USBH0_INDEX].host_handle, imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].pipe_handle);
  311. _ehci0_free_pipe_index(pipe->pipe_index);
  312. return RT_EOK;
  313. }
  314. static struct uhcd_ops _ehci0_uhcd_ops =
  315. {
  316. _ehci0_reset_port,
  317. _ehci0_pipe_xfer,
  318. _ehci0_open_pipe,
  319. _ehci0_close_pipe,
  320. };
  321. static usb_status_t usb0_host_callback(usb_device_handle handle, usb_host_configuration_handle config_handle, rt_uint32_t event_code)
  322. {
  323. usb_status_t status = kStatus_USB_Success;
  324. switch (event_code)
  325. {
  326. case kUSB_HostEventAttach:
  327. if (!imxrt_usb_host_obj[USBH0_INDEX].connect_status)
  328. {
  329. imxrt_usb_host_obj[USBH0_INDEX].connect_status = RT_TRUE;
  330. imxrt_usb_host_obj[USBH0_INDEX].device_handle = handle;
  331. RT_DEBUG_LOG(RT_DEBUG_USB, ("usb connected\n"));
  332. rt_usbh_root_hub_connect_handler(&(imxrt_usb_host_obj[USBH0_INDEX].uhcd), OTG_PORT, RT_TRUE);
  333. }
  334. break;
  335. case kUSB_HostEventNotSupported:
  336. RT_DEBUG_LOG(RT_DEBUG_USB, ("usb device not supported\n"));
  337. break;
  338. case kUSB_HostEventEnumerationDone:
  339. RT_DEBUG_LOG(RT_DEBUG_USB, ("enumeration done\n"));
  340. break;
  341. case kUSB_HostEventDetach:
  342. if (imxrt_usb_host_obj[USBH0_INDEX].connect_status)
  343. {
  344. imxrt_usb_host_obj[USBH0_INDEX].connect_status = RT_FALSE;
  345. imxrt_usb_host_obj[USBH0_INDEX].device_handle = handle;
  346. RT_DEBUG_LOG(RT_DEBUG_USB, ("usb disconnnect\n"));
  347. rt_usbh_root_hub_disconnect_handler(&(imxrt_usb_host_obj[USBH0_INDEX].uhcd), OTG_PORT);
  348. (void)USB_HostCloseDeviceInterface(handle, NULL);
  349. }
  350. break;
  351. default:
  352. break;
  353. }
  354. return status;
  355. }
  356. rt_thread_t usbh0_thread;
  357. static void _ehci0_usbh_thread(void* param)
  358. {
  359. while (1)
  360. {
  361. USB_HostEhciTaskFunction(imxrt_usb_host_obj[USBH0_INDEX].host_handle);
  362. }
  363. }
  364. static rt_err_t _ehci0_usbh_init(rt_device_t device)
  365. {
  366. USB_HostClockInit(kUSB_ControllerEhci0);
  367. if (kStatus_USB_Success == USB_HostInit(kUSB_ControllerEhci0, &imxrt_usb_host_obj[USBH0_INDEX].host_handle, usb0_host_callback))
  368. {
  369. usbh0_thread = rt_thread_create("ehci0", _ehci0_usbh_thread, RT_NULL, 500, 4, 9999999);
  370. rt_thread_startup(usbh0_thread);
  371. USB_HostIsrEnable(kUSB_ControllerEhci0);
  372. }
  373. else
  374. {
  375. rt_kprintf("USB_HostInit ehci0 error\r\n");
  376. return -RT_ERROR;
  377. }
  378. return RT_EOK;
  379. }
  380. #endif
  381. #ifdef BSP_USB1_HOST
  382. void USB_OTG2_IRQHandler(void)
  383. {
  384. /* enter interrupt */
  385. rt_interrupt_enter();
  386. USB_HostEhciIsrFunction(imxrt_usb_host_obj[USBH1_INDEX].host_handle);
  387. /* leave interrupt */
  388. rt_interrupt_leave();
  389. }
  390. static rt_err_t _ehci1_reset_port(rt_uint8_t port)
  391. {
  392. // No reset port function available
  393. return RT_EOK;
  394. }
  395. static uint8_t _ehci1_pipe_buf[64];
  396. static uint8_t _ehci1_pipe_idx;
  397. static int _ehci1_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeouts)
  398. {
  399. int timeout = timeouts;
  400. if (!imxrt_usb_host_obj[USBH1_INDEX].connect_status)
  401. {
  402. return -1;
  403. }
  404. usb_host_transfer_t *transfer;
  405. if (imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].pipe_handle == NULL)
  406. {
  407. RT_DEBUG_LOG(RT_DEBUG_USB, ("error operation on null pipe\n"));
  408. return -1;
  409. }
  410. if (USB_HostMallocTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, &transfer) != kStatus_USB_Success)
  411. {
  412. RT_DEBUG_LOG(RT_DEBUG_USB, ("error to get transfer\n"));
  413. return -1;
  414. }
  415. transfer->transferBuffer = buffer;
  416. transfer->transferLength = nbytes;
  417. transfer->transferSofar = 0;
  418. transfer->callbackFn = _imxrt_usb_host_send_callback;
  419. transfer->callbackParam = &(imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index]);
  420. transfer->direction = (pipe->ep.bEndpointAddress & USB_DIR_IN) ? USB_IN : USB_OUT;
  421. if (pipe->ep.bmAttributes == USB_ENDPOINT_CONTROL)
  422. {
  423. if (token == USBH_PID_SETUP)
  424. {
  425. struct urequest *setup = (struct urequest *)buffer;
  426. transfer->setupStatus = 0;
  427. transfer->setupPacket->bmRequestType = setup->request_type;
  428. transfer->setupPacket->bRequest = setup->bRequest;
  429. transfer->setupPacket->wIndex = setup->wIndex;
  430. transfer->setupPacket->wLength = setup->wLength;
  431. transfer->setupPacket->wValue = setup->wValue;
  432. transfer->transferBuffer = RT_NULL;
  433. transfer->transferLength = 0;
  434. transfer->next = RT_NULL;
  435. if ((transfer->setupPacket->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN)
  436. {
  437. transfer->direction = USB_IN;
  438. transfer->transferBuffer = _ehci1_pipe_buf;
  439. transfer->transferLength = setup->wLength;
  440. _ehci1_pipe_idx = 0;
  441. }
  442. else
  443. {
  444. transfer->direction = USB_OUT;
  445. }
  446. }
  447. else
  448. {
  449. rt_memcpy(buffer, _ehci1_pipe_buf + _ehci1_pipe_idx, nbytes);
  450. imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].transfer_status = kStatus_USB_Success;
  451. transfer->transferSofar = nbytes;
  452. _ehci1_pipe_idx += nbytes;
  453. if (_ehci1_pipe_idx >= 64)
  454. {
  455. _ehci1_pipe_idx = 0;
  456. }
  457. goto _ehci1_pipe_xfer_finish;
  458. }
  459. }
  460. rt_completion_init(&(imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].urb_completion));
  461. if (USB_HostEhciWritePipe(((usb_host_instance_t *)imxrt_usb_host_obj[USBH1_INDEX].host_handle)->controllerHandle, imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].pipe_handle, transfer) != kStatus_USB_Success)
  462. {
  463. RT_DEBUG_LOG(RT_DEBUG_USB, ("usb host failed to send\n"));
  464. (void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
  465. return -1;
  466. }
  467. if (-RT_ETIMEOUT == rt_completion_wait(&(imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].urb_completion), RT_WAITING_FOREVER))
  468. {
  469. RT_DEBUG_LOG(RT_DEBUG_USB, ("usb transfer timeout\n"));
  470. (void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
  471. return -1;
  472. }
  473. // rt_thread_mdelay(1);
  474. _ehci1_pipe_xfer_finish:
  475. switch (imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].transfer_status)
  476. {
  477. case kStatus_USB_Success:
  478. {
  479. RT_DEBUG_LOG(RT_DEBUG_USB, ("ok\n"));
  480. pipe->status = UPIPE_STATUS_OK;
  481. if (pipe->callback != RT_NULL)
  482. {
  483. pipe->callback(pipe);
  484. }
  485. size_t size = transfer->transferSofar;
  486. (void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
  487. if (pipe->ep.bEndpointAddress & 0x80)
  488. {
  489. return size;
  490. }
  491. else if (pipe->ep.bEndpointAddress & 0x00)
  492. {
  493. return size;
  494. }
  495. return nbytes;
  496. break;
  497. }
  498. case kStatus_USB_TransferStall:
  499. {
  500. RT_DEBUG_LOG(RT_DEBUG_USB, ("stall\n"));
  501. pipe->status = UPIPE_STATUS_STALL;
  502. if (pipe->callback != RT_NULL)
  503. {
  504. pipe->callback(pipe);
  505. }
  506. (void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
  507. return -1;
  508. break;
  509. }
  510. case kStatus_USB_TransferFailed:
  511. default:
  512. {
  513. RT_DEBUG_LOG(RT_DEBUG_USB, ("error\n"));
  514. pipe->status = UPIPE_STATUS_ERROR;
  515. if (pipe->callback != RT_NULL)
  516. {
  517. pipe->callback(pipe);
  518. }
  519. (void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
  520. return -1;
  521. break;
  522. }
  523. }
  524. }
  525. static rt_uint16_t _ehci1_pipe_index = 0;
  526. static rt_uint8_t _ehci1_get_free_pipe_index(void)
  527. {
  528. rt_uint8_t idx;
  529. for (idx = 1; idx < 16; idx++)
  530. {
  531. if (!(_ehci1_pipe_index & (0x01 << idx)))
  532. {
  533. _ehci1_pipe_index |= (0x01 << idx);
  534. return idx;
  535. }
  536. }
  537. return 0xff;
  538. }
  539. static void _ehci1_free_pipe_index(rt_uint8_t index)
  540. {
  541. _ehci1_pipe_index &= ~(0x01 << index);
  542. }
  543. static rt_err_t _ehci1_open_pipe(upipe_t pipe)
  544. {
  545. pipe->pipe_index = _ehci1_get_free_pipe_index();
  546. if (pipe->pipe_index == 0xFF)
  547. {
  548. return -RT_ERROR;
  549. }
  550. usb_host_pipe_init_t pipe_init =
  551. {
  552. .devInstance = imxrt_usb_host_obj[USBH1_INDEX].device_handle,
  553. .pipeType = pipe->ep.bmAttributes,
  554. .direction = (pipe->ep.bEndpointAddress & USB_DIR_IN) ? USB_IN : USB_OUT,
  555. .endpointAddress = (pipe->ep.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK),
  556. .interval = pipe->ep.bInterval,
  557. .maxPacketSize = (uint16_t)(pipe->ep.wMaxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK),
  558. .numberPerUframe = (uint8_t)(pipe->ep.wMaxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK),
  559. .nakCount = USB_HOST_CONFIG_MAX_NAK,
  560. };
  561. USB_HostOpenPipe(imxrt_usb_host_obj[USBH1_INDEX].host_handle, &imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].pipe_handle, &pipe_init);
  562. return RT_EOK;
  563. }
  564. static rt_err_t _ehci1_close_pipe(upipe_t pipe)
  565. {
  566. (void)USB_HostClosePipe(imxrt_usb_host_obj[USBH1_INDEX].host_handle, imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].pipe_handle);
  567. _ehci1_free_pipe_index(pipe->pipe_index);
  568. return RT_EOK;
  569. }
  570. static struct uhcd_ops _ehci1_uhcd_ops =
  571. {
  572. _ehci1_reset_port,
  573. _ehci1_pipe_xfer,
  574. _ehci1_open_pipe,
  575. _ehci1_close_pipe,
  576. };
  577. static usb_status_t usb1_host_callback(usb_device_handle handle, usb_host_configuration_handle config_handle, rt_uint32_t event_code)
  578. {
  579. usb_status_t status = kStatus_USB_Success;
  580. switch (event_code)
  581. {
  582. case kUSB_HostEventAttach:
  583. if (!imxrt_usb_host_obj[USBH1_INDEX].connect_status)
  584. {
  585. imxrt_usb_host_obj[USBH1_INDEX].connect_status = RT_TRUE;
  586. imxrt_usb_host_obj[USBH1_INDEX].device_handle = handle;
  587. RT_DEBUG_LOG(RT_DEBUG_USB, ("usb connected\n"));
  588. rt_usbh_root_hub_connect_handler(&(imxrt_usb_host_obj[USBH1_INDEX].uhcd), OTG_PORT, RT_TRUE);
  589. }
  590. break;
  591. case kUSB_HostEventNotSupported:
  592. RT_DEBUG_LOG(RT_DEBUG_USB, ("usb device not supported\n"));
  593. break;
  594. case kUSB_HostEventEnumerationDone:
  595. RT_DEBUG_LOG(RT_DEBUG_USB, ("enumeration done\n"));
  596. break;
  597. case kUSB_HostEventDetach:
  598. if (imxrt_usb_host_obj[USBH1_INDEX].connect_status)
  599. {
  600. imxrt_usb_host_obj[USBH1_INDEX].connect_status = RT_FALSE;
  601. imxrt_usb_host_obj[USBH1_INDEX].device_handle = handle;
  602. RT_DEBUG_LOG(RT_DEBUG_USB, ("usb disconnnect\n"));
  603. rt_usbh_root_hub_disconnect_handler(&(imxrt_usb_host_obj[USBH1_INDEX].uhcd), OTG_PORT);
  604. (void)USB_HostCloseDeviceInterface(handle, NULL);
  605. }
  606. break;
  607. default:
  608. break;
  609. }
  610. return status;
  611. }
  612. rt_thread_t usbh1_thread;
  613. static void _ehci1_usbh_thread(void* param)
  614. {
  615. while (1)
  616. {
  617. USB_HostEhciTaskFunction(imxrt_usb_host_obj[USBH1_INDEX].host_handle);
  618. }
  619. }
  620. static rt_err_t _ehci1_usbh_init(rt_device_t device)
  621. {
  622. USB_HostClockInit(kUSB_ControllerEhci1);
  623. if (kStatus_USB_Success == USB_HostInit(kUSB_ControllerEhci1, &imxrt_usb_host_obj[USBH1_INDEX].host_handle, usb1_host_callback))
  624. {
  625. usbh1_thread = rt_thread_create("ehci1", _ehci1_usbh_thread, RT_NULL, 500, 4, 9999999);
  626. rt_thread_startup(usbh1_thread);
  627. USB_HostIsrEnable(kUSB_ControllerEhci1);
  628. }
  629. else
  630. {
  631. rt_kprintf("USB_HostInit ehci1 error\r\n");
  632. return -RT_ERROR;
  633. }
  634. return RT_EOK;
  635. }
  636. #endif
  637. int imxrt_usbh_register(void)
  638. {
  639. rt_err_t res = -RT_ERROR;
  640. struct imxrt_usb_host *usb_host_obj;
  641. #ifdef BSP_USB0_HOST
  642. usb_host_obj = &(imxrt_usb_host_obj[USBH0_INDEX]);
  643. rt_memset((void *)(&(usb_host_obj->uhcd)), 0, sizeof(struct uhcd));
  644. usb_host_obj->uhcd.parent.type = RT_Device_Class_USBHost;
  645. usb_host_obj->uhcd.parent.init = _ehci0_usbh_init;
  646. usb_host_obj->uhcd.parent.user_data = usb_host_obj;
  647. usb_host_obj->uhcd.ops = &_ehci0_uhcd_ops;
  648. usb_host_obj->uhcd.num_ports = OTG_PORT;
  649. res = rt_device_register(&(usb_host_obj->uhcd.parent), usb_host_obj->name, RT_DEVICE_FLAG_DEACTIVATE);
  650. if (res != RT_EOK)
  651. {
  652. rt_kprintf("register usb0 host failed res = %d\r\n", res);
  653. return -RT_ERROR;
  654. }
  655. rt_usb_host_init(usb_host_obj->name);
  656. #endif
  657. #ifdef BSP_USB1_HOST
  658. usb_host_obj = &(imxrt_usb_host_obj[USBH1_INDEX]);
  659. rt_memset((void *)(&(usb_host_obj->uhcd)), 0, sizeof(struct uhcd));
  660. usb_host_obj->uhcd.parent.type = RT_Device_Class_USBHost;
  661. usb_host_obj->uhcd.parent.init = _ehci1_usbh_init;
  662. usb_host_obj->uhcd.parent.user_data = usb_host_obj;
  663. usb_host_obj->uhcd.ops = &_ehci1_uhcd_ops;
  664. usb_host_obj->uhcd.num_ports = OTG_PORT;
  665. res = rt_device_register(&(usb_host_obj->uhcd.parent), usb_host_obj->name, RT_DEVICE_FLAG_DEACTIVATE);
  666. if (res != RT_EOK)
  667. {
  668. rt_kprintf("register usb0 host failed res = %d\r\n", res);
  669. return -RT_ERROR;
  670. }
  671. rt_usb_host_init(usb_host_obj->name);
  672. #endif
  673. return RT_EOK;
  674. }
  675. INIT_DEVICE_EXPORT(imxrt_usbh_register);
  676. #endif