usbh.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #pragma once
  7. #include <stdint.h>
  8. #include <sys/queue.h>
  9. #include "freertos/FreeRTOS.h"
  10. #include "freertos/task.h"
  11. #include "hcd.h"
  12. #include "usb/usb_types_ch9.h"
  13. #include "usb/usb_types_stack.h"
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17. // ------------------------------------------------------ Types --------------------------------------------------------
  18. // ----------------------- Handles -------------------------
  19. /**
  20. * @brief Handle of a allocated endpoint
  21. */
  22. typedef struct usbh_ep_handle_s *usbh_ep_handle_t;
  23. // ----------------------- Events --------------------------
  24. typedef enum {
  25. USBH_EVENT_DEV_NEW, /**< A new device has been enumerated and added to the device pool */
  26. USBH_EVENT_DEV_GONE, /**< A device is gone. Clients should close the device */
  27. USBH_EVENT_DEV_ALL_FREE, /**< All devices have been freed */
  28. } usbh_event_t;
  29. /**
  30. * @brief Endpoint events
  31. *
  32. * @note Optimization: Keep this identical to hcd_pipe_event_t
  33. */
  34. typedef enum {
  35. USBH_EP_EVENT_NONE, /**< The EP has no events (used to indicate no events when polling) */
  36. USBH_EP_EVENT_URB_DONE, /**< The EP has completed a URB. The URB can be dequeued */
  37. USBH_EP_EVENT_ERROR_XFER, /**< The EP encountered excessive errors when transferring a URB i.e., three three consecutive transaction errors (e.g., no ACK, bad CRC etc) */
  38. USBH_EP_EVENT_ERROR_URB_NOT_AVAIL, /**< The EP tried to execute a transfer but no URB was available */
  39. USBH_EP_EVENT_ERROR_OVERFLOW, /**< The EP received more data than requested. Usually a Packet babble error (i.e., an IN packet has exceeded the EP's MPS) */
  40. USBH_EP_EVENT_ERROR_STALL, /**< EP received a STALL response */
  41. } usbh_ep_event_t;
  42. /**
  43. * @brief Hub driver events for the USBH
  44. *
  45. * These events as passed by the Hub driver to the USBH via usbh_hub_pass_event()
  46. *
  47. * USBH_HUB_EVENT_PORT_ERROR:
  48. * - The port has encountered an error (such as a sudden disconnection). The device connected to that port is no longer valid.
  49. * - The USBH should:
  50. * - Trigger a USBH_EVENT_DEV_GONE
  51. * - Prevent further transfers to the device
  52. * - Trigger the device's cleanup if it is already closed
  53. * - When the last client closes the device via usbh_dev_close(), free the device object and issue a USBH_HUB_REQ_PORT_RECOVER request
  54. *
  55. * USBH_HUB_EVENT_PORT_DISABLED:
  56. * - A previous USBH_HUB_REQ_PORT_DISABLE has completed.
  57. * - The USBH should free the device object
  58. */
  59. typedef enum {
  60. USBH_HUB_EVENT_PORT_ERROR, /**< The port has encountered an error (such as a sudden disconnection). The device
  61. connected to that port should be marked gone. */
  62. USBH_HUB_EVENT_PORT_DISABLED, /**< Previous USBH_HUB_REQ_PORT_DISABLE request completed */
  63. } usbh_hub_event_t;
  64. // ------------------ Requests/Commands --------------------
  65. /**
  66. * @brief Hub driver requests
  67. *
  68. * Various requests of the Hub driver that the USBH can make.
  69. */
  70. typedef enum {
  71. USBH_HUB_REQ_PORT_DISABLE, /**< Request that the Hub driver disable a particular port (occurs after a device
  72. has been freed). Hub driver should respond with a USBH_HUB_EVENT_PORT_DISABLED */
  73. USBH_HUB_REQ_PORT_RECOVER, /**< Request that the Hub driver recovers a particular port (occurs after a gone
  74. device has been freed). */
  75. } usbh_hub_req_t;
  76. /**
  77. * @brief Endpoint commands
  78. *
  79. * @note Optimization: Keep this identical to hcd_pipe_cmd_t
  80. */
  81. typedef enum {
  82. USBH_EP_CMD_HALT, /**< Halt an active endpoint. Any currently executing URB will be canceled. Enqueued URBs are left untouched */
  83. USBH_EP_CMD_FLUSH, /**< Can only be called when halted. Will cause all enqueued URBs to be canceled */
  84. USBH_EP_CMD_CLEAR, /**< Causes a halted endpoint to become active again. Any enqueued URBs will being executing.*/
  85. } usbh_ep_cmd_t;
  86. // ---------------------- Callbacks ------------------------
  87. /**
  88. * @brief Callback used to indicate completion of control transfers submitted usbh_dev_submit_ctrl_urb()
  89. * @note This callback is called from within usbh_process()
  90. */
  91. typedef void (*usbh_ctrl_xfer_cb_t)(usb_device_handle_t dev_hdl, urb_t *urb, void *arg);
  92. /**
  93. * @brief Callback used to indicate that the USBH has an event
  94. *
  95. * @note This callback is called from within usbh_process()
  96. * @note On a USBH_EVENT_DEV_ALL_FREE event, the dev_hdl argument is set to NULL
  97. */
  98. typedef void (*usbh_event_cb_t)(usb_device_handle_t dev_hdl, usbh_event_t usbh_event, void *arg);
  99. /**
  100. * @brief Callback used by the USBH to request actions from the Hub driver
  101. *
  102. * The Hub Request Callback allows the USBH to request the Hub actions on a particular port. Conversely, the Hub driver
  103. * will indicate completion of some of these requests to the USBH via the usbh_hub_event() funtion.
  104. */
  105. typedef void (*usbh_hub_req_cb_t)(hcd_port_handle_t port_hdl, usbh_hub_req_t hub_req, void *arg);
  106. /**
  107. * @brief Callback used to indicate an event on an endpoint
  108. *
  109. * Return whether to yield or not if called from an ISR. Always return false if not called from an ISR
  110. */
  111. typedef bool (*usbh_ep_cb_t)(usbh_ep_handle_t ep_hdl, usbh_ep_event_t ep_event, void *arg, bool in_isr);
  112. // ----------------------- Objects -------------------------
  113. /**
  114. * @brief Configuration for an endpoint being allocated using usbh_ep_alloc()
  115. */
  116. typedef struct {
  117. uint8_t bInterfaceNumber; /**< Interface number */
  118. uint8_t bAlternateSetting; /**< Alternate setting number of the interface */
  119. uint8_t bEndpointAddress; /**< Endpoint address */
  120. usbh_ep_cb_t ep_cb; /**< Endpoint event callback */
  121. void *ep_cb_arg; /**< Endpoint callback argument */
  122. void *context; /**< Endpoint context */
  123. } usbh_ep_config_t;
  124. /**
  125. * @brief USBH configuration used in usbh_install()
  126. */
  127. typedef struct {
  128. usb_proc_req_cb_t proc_req_cb; /**< Processing request callback */
  129. void *proc_req_cb_arg; /**< Processing request callback argument */
  130. usbh_ctrl_xfer_cb_t ctrl_xfer_cb; /**< Control transfer callback */
  131. void *ctrl_xfer_cb_arg; /**< Control transfer callback argument */
  132. usbh_event_cb_t event_cb; /**< USBH event callback */
  133. void *event_cb_arg; /**< USBH event callback argument */
  134. } usbh_config_t;
  135. // ------------------------------------------------- USBH Functions ----------------------------------------------------
  136. /**
  137. * @brief Installs the USBH driver
  138. *
  139. * - This function will internally install the HCD
  140. * - This must be called before calling any Hub driver functions
  141. *
  142. * @note Before calling this function, the Host Controller must already be un-clock gated and reset. The USB PHY
  143. * (internal or external, and associated GPIOs) must already be configured.
  144. * @param usbh_config USBH driver configuration
  145. * @return esp_err_t
  146. */
  147. esp_err_t usbh_install(const usbh_config_t *usbh_config);
  148. /**
  149. * @brief Uninstall the USBH driver
  150. *
  151. * - This function will uninstall the HCD
  152. * - The Hub driver must be uninstalled before calling this function
  153. *
  154. * @note This function will simply free the resources used by the USBH. The underlying Host Controller and USB PHY will
  155. * not be disabled.
  156. * @return esp_err_t
  157. */
  158. esp_err_t usbh_uninstall(void);
  159. /**
  160. * @brief USBH processing function
  161. *
  162. * - USBH processing function that must be called repeatedly to process USBH events
  163. * - If blocking, the caller can block until the proc_req_cb() is called with USB_PROC_REQ_SOURCE_USBH as the request
  164. * source. The USB_PROC_REQ_SOURCE_USBH source indicates that this function should be called.
  165. *
  166. * @note This function can block
  167. * @return esp_err_t
  168. */
  169. esp_err_t usbh_process(void);
  170. /**
  171. * @brief Get the current number of devices
  172. *
  173. * @note This function can block
  174. * @param[out] num_devs_ret Current number of devices
  175. * @return esp_err_t
  176. */
  177. esp_err_t usbh_num_devs(int *num_devs_ret);
  178. // ------------------------------------------------ Device Functions ---------------------------------------------------
  179. // --------------------- Device Pool -----------------------
  180. /**
  181. * @brief Fill list with address of currently connected devices
  182. *
  183. * - This function fills the provided list with the address of current connected devices
  184. * - Device address can then be used in usbh_dev_open()
  185. * - If there are more devices than the list_len, this function will only fill
  186. * up to list_len number of devices.
  187. *
  188. * @param[in] list_len Length of empty list
  189. * @param[inout] dev_addr_list Empty list to be filled
  190. * @param[out] num_dev_ret Number of devices filled into list
  191. * @return esp_err_t
  192. */
  193. esp_err_t usbh_dev_addr_list_fill(int list_len, uint8_t *dev_addr_list, int *num_dev_ret);
  194. /**
  195. * @brief Open a device by address
  196. *
  197. * A device must be opened before it can be used
  198. *
  199. * @param[in] dev_addr Device address
  200. * @param[out] dev_hdl Device handle
  201. * @return esp_err_t
  202. */
  203. esp_err_t usbh_dev_open(uint8_t dev_addr, usb_device_handle_t *dev_hdl);
  204. /**
  205. * @brief CLose a device
  206. *
  207. * Device can be opened by calling usbh_dev_open()
  208. *
  209. * @param[in] dev_hdl Device handle
  210. * @return esp_err_t
  211. */
  212. esp_err_t usbh_dev_close(usb_device_handle_t dev_hdl);
  213. /**
  214. * @brief Mark that all devices should be freed at the next possible opportunity
  215. *
  216. * A device marked as free will not be freed until the last client using the device has called usbh_dev_close()
  217. *
  218. * @return
  219. * - ESP_OK: There were no devices to free to begin with. Current state is all free
  220. * - ESP_ERR_NOT_FINISHED: One or more devices still need to be freed (but have been marked "to be freed")
  221. */
  222. esp_err_t usbh_dev_mark_all_free(void);
  223. // ------------------- Single Device ----------------------
  224. /**
  225. * @brief Get a device's address
  226. *
  227. * @note Can be called without opening the device
  228. *
  229. * @param[in] dev_hdl Device handle
  230. * @param[out] dev_addr Device's address
  231. * @return esp_err_t
  232. */
  233. esp_err_t usbh_dev_get_addr(usb_device_handle_t dev_hdl, uint8_t *dev_addr);
  234. /**
  235. * @brief Get a device's information
  236. *
  237. * @note This function can block
  238. * @param[in] dev_hdl Device handle
  239. * @param[out] dev_info Device information
  240. * @return esp_err_t
  241. */
  242. esp_err_t usbh_dev_get_info(usb_device_handle_t dev_hdl, usb_device_info_t *dev_info);
  243. /**
  244. * @brief Get a device's device descriptor
  245. *
  246. * - The device descriptor is cached when the device is created by the Hub driver
  247. *
  248. * @param[in] dev_hdl Device handle
  249. * @param[out] dev_desc_ret Device descriptor
  250. * @return esp_err_t
  251. */
  252. esp_err_t usbh_dev_get_desc(usb_device_handle_t dev_hdl, const usb_device_desc_t **dev_desc_ret);
  253. /**
  254. * @brief Get a device's active configuration descriptor
  255. *
  256. * Simply returns a reference to the internally cached configuration descriptor
  257. *
  258. * @note This function can block
  259. * @param[in] dev_hdl Device handle
  260. * @param config_desc_ret
  261. * @return esp_err_t
  262. */
  263. esp_err_t usbh_dev_get_config_desc(usb_device_handle_t dev_hdl, const usb_config_desc_t **config_desc_ret);
  264. /**
  265. * @brief Submit a control transfer (URB) to a device
  266. *
  267. * @param[in] dev_hdl Device handle
  268. * @param[in] urb URB
  269. * @return esp_err_t
  270. */
  271. esp_err_t usbh_dev_submit_ctrl_urb(usb_device_handle_t dev_hdl, urb_t *urb);
  272. // ----------------------------------------------- Endpoint Functions -------------------------------------------------
  273. /**
  274. * @brief Allocate an endpoint on a device
  275. *
  276. * This function allows clients to allocate a non-default endpoint (i.e., not EP0) on a connected device
  277. *
  278. * - A client must have opened the device using usbh_dev_open() before attempting to allocate an endpoint on the device
  279. * - A client should call this function to allocate all endpoints in an interface that the client has claimed.
  280. * - A client must allocate an endpoint using this function before attempting to communicate with it
  281. * - Once the client allocates an endpoint, the client is now owns/manages the endpoint. No other client should use or
  282. * deallocate the endpoint.
  283. *
  284. * @note This function can block
  285. * @note Default endpoints (EP0) are owned by the USBH. For control transfers, use usbh_dev_submit_ctrl_urb() instead
  286. *
  287. * @param[in] dev_hdl Device handle
  288. * @param[in] ep_config Endpoint configuration
  289. * @param[out] ep_hdl_ret Endpoint handle
  290. * @return esp_err_t
  291. */
  292. esp_err_t usbh_ep_alloc(usb_device_handle_t dev_hdl, usbh_ep_config_t *ep_config, usbh_ep_handle_t *ep_hdl_ret);
  293. /**
  294. * @brief Free and endpoint on a device
  295. *
  296. * This function frees an endpoint previously allocated by the client using usbh_ep_alloc()
  297. *
  298. * - Only the client that allocated the endpoint should free it
  299. * - The client must have halted and flushed the endpoint using usbh_ep_command() before attempting to free it
  300. * - The client must ensure that there are no more function calls to the endpoint before freeing it
  301. *
  302. * @note This function can block
  303. * @param[in] ep_hdl Endpoint handle
  304. * @return esp_err_t
  305. */
  306. esp_err_t usbh_ep_free(usbh_ep_handle_t ep_hdl);
  307. /**
  308. * @brief Get the handle of an endpoint using its address
  309. *
  310. * The endpoint must have been previously allocated using usbh_ep_alloc()
  311. *
  312. * @param[in] dev_hdl Device handle
  313. * @param[in] bEndpointAddress Endpoint address
  314. * @param[out] ep_hdl_ret Endpoint handle
  315. * @return esp_err_t
  316. */
  317. esp_err_t usbh_ep_get_handle(usb_device_handle_t dev_hdl, uint8_t bEndpointAddress, usbh_ep_handle_t *ep_hdl_ret);
  318. /**
  319. * @brief Enqueue a URB to an endpoint
  320. *
  321. * The URB will remain enqueued until it completes (successfully or errors out). Use usbh_ep_dequeue_urb() to dequeue
  322. * a completed URB.
  323. *
  324. * @param[in] ep_hdl Endpoint handle
  325. * @param[in] urb URB to enqueue
  326. * @return esp_err_t
  327. */
  328. esp_err_t usbh_ep_enqueue_urb(usbh_ep_handle_t ep_hdl, urb_t *urb);
  329. /**
  330. * @brief Dequeue a URB from an endpoint
  331. *
  332. * Dequeue a completed URB from an endpoint. The USBH_EP_EVENT_URB_DONE indicates that URBs can be dequeued
  333. *
  334. * @param[in] ep_hdl Endpoint handle
  335. * @param[out] urb_ret Dequeued URB, or NULL if no more URBs to dequeue
  336. * @return esp_err_t
  337. */
  338. esp_err_t usbh_ep_dequeue_urb(usbh_ep_handle_t ep_hdl, urb_t **urb_ret);
  339. /**
  340. * @brief Execute a command on a particular endpoint
  341. *
  342. * Endpoint commands allows executing a certain action on an endpoint (e.g., halting, flushing, clearing etc)
  343. *
  344. * @param[in] ep_hdl Endpoint handle
  345. * @param[in] command Endpoint command
  346. * @return esp_err_t
  347. */
  348. esp_err_t usbh_ep_command(usbh_ep_handle_t ep_hdl, usbh_ep_cmd_t command);
  349. /**
  350. * @brief Get the context of an endpoint
  351. *
  352. * Get the context variable assigned to and endpoint on allocation.
  353. *
  354. * @note This function can block
  355. * @param[in] ep_hdl Endpoint handle
  356. * @return Endpoint context
  357. */
  358. void *usbh_ep_get_context(usbh_ep_handle_t ep_hdl);
  359. // -------------------------------------------------- Hub Functions ----------------------------------------------------
  360. // ------------------- Device Related ----------------------
  361. /**
  362. * @brief Indicates to USBH that the Hub driver is installed
  363. *
  364. * - The Hub driver must call this function in its installation to indicate the the USBH that it has been installed.
  365. * - This should only be called after the USBH has already be installed
  366. *
  367. * @note Hub Driver only
  368. * @param[in] hub_req_callback Hub request callback
  369. * @param[in] callback_arg Callback argument
  370. * @return esp_err_t
  371. */
  372. esp_err_t usbh_hub_is_installed(usbh_hub_req_cb_t hub_req_callback, void *callback_arg);
  373. /**
  374. * @brief Indicates to USBH the start of enumeration for a device
  375. *
  376. * - The Hub driver calls this function before it starts enumerating a new device.
  377. * - The USBH will allocate a new device that will be initialized by the Hub driver using the remaining hub enumeration
  378. * functions.
  379. * - The new device's default pipe handle is returned to all the Hub driver to be used during enumeration.
  380. *
  381. * @note Hub Driver only
  382. * @param[in] port_hdl Handle of the port that the device is connected to
  383. * @param[in] dev_speed Device's speed
  384. * @param[out] new_dev_hdl Device's handle
  385. * @param[out] default_pipe_hdl Device's default pipe handle
  386. * @return esp_err_t
  387. */
  388. esp_err_t usbh_hub_add_dev(hcd_port_handle_t port_hdl, usb_speed_t dev_speed, usb_device_handle_t *new_dev_hdl, hcd_pipe_handle_t *default_pipe_hdl);
  389. /**
  390. * @brief Indicates to the USBH that a hub event has occurred for a particular device
  391. *
  392. * @param dev_hdl Device handle
  393. * @param hub_event Hub event
  394. * @return esp_err_t
  395. */
  396. esp_err_t usbh_hub_pass_event(usb_device_handle_t dev_hdl, usbh_hub_event_t hub_event);
  397. // ----------------- Enumeration Related -------------------
  398. /**
  399. * @brief Assign the enumerating device's address
  400. *
  401. * @note Hub Driver only
  402. * @note Must call in sequence
  403. * @param[in] dev_hdl Device handle
  404. * @param dev_addr
  405. * @return esp_err_t
  406. */
  407. esp_err_t usbh_hub_enum_fill_dev_addr(usb_device_handle_t dev_hdl, uint8_t dev_addr);
  408. /**
  409. * @brief Fill the enumerating device's descriptor
  410. *
  411. * @note Hub Driver only
  412. * @note Must call in sequence
  413. * @param[in] dev_hdl Device handle
  414. * @param device_desc
  415. * @return esp_err_t
  416. */
  417. esp_err_t usbh_hub_enum_fill_dev_desc(usb_device_handle_t dev_hdl, const usb_device_desc_t *device_desc);
  418. /**
  419. * @brief Fill the enumerating device's active configuration descriptor
  420. *
  421. * @note Hub Driver only
  422. * @note Must call in sequence
  423. * @note This function can block
  424. * @param[in] dev_hdl Device handle
  425. * @param config_desc_full
  426. * @return esp_err_t
  427. */
  428. esp_err_t usbh_hub_enum_fill_config_desc(usb_device_handle_t dev_hdl, const usb_config_desc_t *config_desc_full);
  429. /**
  430. * @brief Fill one of the string descriptors of the enumerating device
  431. *
  432. * @note Hub Driver only
  433. * @note Must call in sequence
  434. * @param dev_hdl Device handle
  435. * @param str_desc Pointer to string descriptor
  436. * @param select Select which string descriptor. 0/1/2 for Manufacturer/Product/Serial Number string descriptors respectively
  437. * @return esp_err_t
  438. */
  439. esp_err_t usbh_hub_enum_fill_str_desc(usb_device_handle_t dev_hdl, const usb_str_desc_t *str_desc, int select);
  440. /**
  441. * @brief Indicate the device enumeration is completed
  442. *
  443. * This will all the device to be opened by clients, and also trigger a USBH_EVENT_DEV_NEW event.
  444. *
  445. * @note Hub Driver only
  446. * @note Must call in sequence
  447. * @note This function can block
  448. * @param[in] dev_hdl Device handle
  449. * @return esp_err_t
  450. */
  451. esp_err_t usbh_hub_enum_done(usb_device_handle_t dev_hdl);
  452. /**
  453. * @brief Indicate that device enumeration has failed
  454. *
  455. * This will cause the enumerating device's resources to be cleaned up
  456. * The Hub Driver must guarantee that the enumerating device's default pipe is already halted, flushed, and dequeued.
  457. *
  458. * @note Hub Driver only
  459. * @note Must call in sequence
  460. * @note This function can block
  461. * @param[in] dev_hdl Device handle
  462. * @return esp_err_t
  463. */
  464. esp_err_t usbh_hub_enum_failed(usb_device_handle_t dev_hdl);
  465. #ifdef __cplusplus
  466. }
  467. #endif