1 /* 2 * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /* 8 Warning: The USB Host Library API is still a beta version and may be subject to change 9 */ 10 11 #pragma once 12 13 #include <stdint.h> 14 #include "freertos/FreeRTOS.h" 15 #include "esp_err.h" 16 #include "esp_intr_alloc.h" 17 //Include the other USB Host Library headers as well 18 #include "usb/usb_helpers.h" 19 #include "usb/usb_types_ch9.h" 20 #include "usb/usb_types_stack.h" 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 // ------------------------------------------------- Macros and Types -------------------------------------------------- 27 28 // ----------------------- Handles ------------------------- 29 30 /** 31 * @brief Handle to a USB Host Library asynchronous client 32 * 33 * An asynchronous client can be registered using usb_host_client_register() 34 * 35 * @note Asynchronous API 36 */ 37 typedef struct usb_host_client_handle_s * usb_host_client_handle_t; 38 39 // ----------------------- Events -------------------------- 40 41 #define USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS 0x01 /**< All clients have been deregistered from the USB Host Library */ 42 #define USB_HOST_LIB_EVENT_FLAGS_ALL_FREE 0x02 /**< The USB Host Library has freed all devices */ 43 44 /** 45 * @brief The type event in a client event message 46 */ 47 typedef enum { 48 USB_HOST_CLIENT_EVENT_NEW_DEV, /**< A new device has been enumerated and added to the USB Host Library */ 49 USB_HOST_CLIENT_EVENT_DEV_GONE, /**< A device opened by the client is now gone */ 50 } usb_host_client_event_t; 51 52 /** 53 * @brief Client event message 54 * 55 * Client event messages are sent to each client of the USB Host Library in order to notify them of various 56 * USB Host Library events such as: 57 * - Addition of new devices 58 * - Removal of existing devices 59 * 60 * @note The event message structure has a union with members corresponding to each particular event. Based on the event 61 * type, only the relevant member field should be accessed. 62 */ 63 typedef struct { 64 usb_host_client_event_t event; /**< Type of event */ 65 union { 66 struct { 67 uint8_t address; /**< New device's address */ 68 } new_dev; 69 struct { 70 usb_device_handle_t dev_hdl; /**< The handle of the device that was gone */ 71 } dev_gone; 72 }; 73 } usb_host_client_event_msg_t; 74 75 // ------------------------ Info --------------------------- 76 77 /** 78 * @brief Current information about the USB Host Library obtained via usb_host_lib_info() 79 */ 80 typedef struct { 81 int num_devices; /**< Current number of connected (and enumerated) devices */ 82 int num_clients; /**< Current number of registered clients */ 83 } usb_host_lib_info_t; 84 85 // ---------------------- Callbacks ------------------------ 86 87 /** 88 * @brief Client event callback 89 * 90 * - Each client of the USB Host Library must register an event callback to receive event messages from the USB Host 91 * Library. 92 * - The client event callback is run from the context of the clients usb_host_client_handle_events() function 93 */ 94 typedef void (*usb_host_client_event_cb_t)(const usb_host_client_event_msg_t *event_msg, void *arg); 95 96 // -------------------- Configurations --------------------- 97 98 /** 99 * @brief USB Host Library configuration 100 * 101 * Configuration structure of the USB Host Library. Provided in the usb_host_install() function 102 */ 103 typedef struct { 104 bool skip_phy_setup; /**< If set, the USB Host Library will not configure the USB PHY thus allowing the user 105 to manually configure the USB PHY before calling usb_host_install(). Users should 106 set this if they want to use an external USB PHY. Otherwise, the USB Host Library 107 will automatically configure the internal USB PHY */ 108 int intr_flags; /**< Interrupt flags for the underlying ISR used by the USB Host stack */ 109 } usb_host_config_t; 110 111 /** 112 * @brief USB Host Library Client configuration 113 * 114 * Configuration structure for a USB Host Library client. Provided in usb_host_client_register() 115 */ 116 typedef struct { 117 bool is_synchronous; /**< Whether the client is asynchronous or synchronous or not. Set to false for now. */ 118 int max_num_event_msg; /**< Maximum number of event messages that can be stored (e.g., 3) */ 119 union { //Note: Made into union or future expansion 120 struct { 121 usb_host_client_event_cb_t client_event_callback; /**< Client's event callback function */ 122 void *callback_arg; /**< Event callback function argument */ 123 } async; 124 }; 125 } usb_host_client_config_t; 126 127 // ------------------------------------------------ Library Functions -------------------------------------------------- 128 129 /** 130 * @brief Install the USB Host Library 131 * 132 * - This function should only once to install the USB Host Library 133 * - This function should be called before any other USB Host Library functions are called 134 * 135 * @note If skip_phy_setup is set in the install configuration, the user is responsible for ensuring that the underlying 136 * Host Controller is enabled and the USB PHY (internal or external) is already setup before this function is 137 * called. 138 * @param[in] config USB Host Library configuration 139 * @return esp_err_t 140 */ 141 esp_err_t usb_host_install(const usb_host_config_t *config); 142 143 /** 144 * @brief Uninstall the USB Host Library 145 * 146 * - This function should be called to uninstall the USB Host Library, thereby freeing its resources 147 * - All clients must have been deregistered before calling this function 148 * - All devices must have been freed by calling usb_host_device_free_all() and receiving the 149 * USB_HOST_LIB_EVENT_FLAGS_ALL_FREE event flag 150 * 151 * @note If skip_phy_setup was set when the Host Library was installed, the user is responsible for disabling the 152 * underlying Host Controller and USB PHY (internal or external). 153 * @return esp_err_t 154 */ 155 esp_err_t usb_host_uninstall(void); 156 157 /** 158 * @brief Handle USB Host Library events 159 * 160 * - This function handles all of the USB Host Library's processing and should be called repeatedly in a loop 161 * - Check event_flags_ret to see if an flags are set indicating particular USB Host Library events 162 * - This function should never be called by multiple threads simultaneously 163 * 164 * @note This function can block 165 * @param[in] timeout_ticks Timeout in ticks to wait for an event to occur 166 * @param[out] event_flags_ret Event flags that indicate what USB Host Library event occurred. 167 * @return esp_err_t 168 */ 169 esp_err_t usb_host_lib_handle_events(TickType_t timeout_ticks, uint32_t *event_flags_ret); 170 171 /** 172 * @brief Unblock the USB Host Library handler 173 * 174 * - This function simply unblocks the USB Host Library event handling function (usb_host_lib_handle_events()) 175 * 176 * @return esp_err_t 177 */ 178 esp_err_t usb_host_lib_unblock(void); 179 180 /** 181 * @brief Get current information about the USB Host Library 182 * 183 * @param[out] info_ret USB Host Library Information 184 * @return esp_err_t 185 */ 186 esp_err_t usb_host_lib_info(usb_host_lib_info_t *info_ret); 187 188 // ------------------------------------------------ Client Functions --------------------------------------------------- 189 190 /** 191 * @brief Register a client of the USB Host Library 192 * 193 * - This function registers a client of the USB Host Library 194 * - Once a client is registered, its processing function usb_host_client_handle_events() should be called repeatedly 195 * 196 * @param[in] client_config Client configuration 197 * @param[out] client_hdl_ret Client handle 198 * @return esp_err_t 199 */ 200 esp_err_t usb_host_client_register(const usb_host_client_config_t *client_config, usb_host_client_handle_t *client_hdl_ret); 201 202 /** 203 * @brief Deregister a USB Host Library client 204 * 205 * - This function deregisters a client of the USB Host Library 206 * - The client must have closed all previously opened devices before attempting to deregister 207 * 208 * @param[in] client_hdl Client handle 209 * @return esp_err_t 210 */ 211 esp_err_t usb_host_client_deregister(usb_host_client_handle_t client_hdl); 212 213 /** 214 * @brief USB Host Library client processing function 215 * 216 * - This function handles all of a client's processing and should be called repeatedly in a loop 217 * - For a particular client, this function should never be called by multiple threads simultaneously 218 * 219 * @note This function can block 220 * @param[in] client_hdl Client handle 221 * @param[in] timeout_ticks Timeout in ticks to wait for an event to occur 222 * @return esp_err_t 223 */ 224 esp_err_t usb_host_client_handle_events(usb_host_client_handle_t client_hdl, TickType_t timeout_ticks); 225 226 /** 227 * @brief Unblock a client 228 * 229 * - This function simply unblocks a client if it is blocked on the usb_host_client_handle_events() function. 230 * - This function is useful when need to unblock a client in order to deregister it. 231 * 232 * @param[in] client_hdl Client handle 233 * @return esp_err_t 234 */ 235 esp_err_t usb_host_client_unblock(usb_host_client_handle_t client_hdl); 236 237 // ------------------------------------------------- Device Handling --------------------------------------------------- 238 239 /** 240 * @brief Open a device 241 * 242 * - This function allows a client to open a device 243 * - A client must open a device first before attempting to use it (e.g., sending transfers, device requests etc.) 244 * 245 * @param[in] client_hdl Client handle 246 * @param[in] dev_addr Device's address 247 * @param[out] dev_hdl_ret Device's handle 248 * @return esp_err_t 249 */ 250 esp_err_t usb_host_device_open(usb_host_client_handle_t client_hdl, uint8_t dev_addr, usb_device_handle_t *dev_hdl_ret); 251 252 /** 253 * @brief Close a device 254 * 255 * - This function allows a client to close a device 256 * - A client must close a device after it has finished using the device (claimed interfaces must also be released) 257 * - A client must close all devices it has opened before deregistering 258 * 259 * @note This function can block 260 * @param[in] client_hdl Client handle 261 * @param[in] dev_hdl Device handle 262 * @return esp_err_t 263 */ 264 esp_err_t usb_host_device_close(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl); 265 266 /** 267 * @brief Indicate that all devices can be freed when possible 268 * 269 * - This function marks all devices as waiting to be freed 270 * - If a device is not opened by any clients, it will be freed immediately 271 * - If a device is opened by at least one client, the device will be free when the last client closes that device. 272 * - Wait for the USB_HOST_LIB_EVENT_FLAGS_ALL_FREE flag to be set by usb_host_lib_handle_events() in order to know 273 * when all devices have been freed 274 * - This function is useful when cleaning up devices before uninstalling the USB Host Library 275 * 276 * @return 277 * - ESP_ERR_NOT_FINISHED: There are one or more devices that still need to be freed. Wait for USB_HOST_LIB_EVENT_FLAGS_ALL_FREE event 278 * - ESP_OK: All devices already freed (i.e., there were no devices) 279 * - Other: Error 280 */ 281 esp_err_t usb_host_device_free_all(void); 282 283 /** 284 * @brief Fill a list of device address 285 * 286 * - This function fills an empty list with the address of connected devices 287 * - The Device addresses can then used in usb_host_device_open() 288 * - If there are more devices than the list_len, this function will only fill up to list_len number of devices. 289 * 290 * @param[in] list_len Length of the empty list 291 * @param[inout] dev_addr_list Empty list to be filled 292 * @param[out] num_dev_ret Number of devices 293 * @return esp_err_t 294 */ 295 esp_err_t usb_host_device_addr_list_fill(int list_len, uint8_t *dev_addr_list, int *num_dev_ret); 296 297 // ------------------------------------------------- Device Requests --------------------------------------------------- 298 299 // ------------------- Cached Requests --------------------- 300 301 /** 302 * @brief Get device's information 303 * 304 * - This function gets some basic information of a device 305 * - The device must be opened first before attempting to get its information 306 * 307 * @note This function can block 308 * @param[in] dev_hdl Device handle 309 * @param[out] dev_info Device information 310 * @return esp_err_t 311 */ 312 esp_err_t usb_host_device_info(usb_device_handle_t dev_hdl, usb_device_info_t *dev_info); 313 314 // ----------------------------------------------- Descriptor Requests ------------------------------------------------- 315 316 // ----------------- Cached Descriptors -------------------- 317 318 /** 319 * @brief Get device's device descriptor 320 * 321 * - A client must call usb_host_device_open() first 322 * - No control transfer is sent. The device's descriptor is cached on enumeration 323 * - This function simple returns a pointer to the cached descriptor 324 * 325 * @note No control transfer is sent. The device's descriptor is cached on enumeration 326 * @param[in] dev_hdl Device handle 327 * @param[out] device_desc Device descriptor 328 * @return esp_err_t 329 */ 330 esp_err_t usb_host_get_device_descriptor(usb_device_handle_t dev_hdl, const usb_device_desc_t **device_desc); 331 332 /** 333 * @brief Get device's active configuration descriptor 334 * 335 * - A client must call usb_host_device_open() first 336 * - No control transfer is sent. The device's active configuration descriptor is cached on enumeration 337 * - This function simple returns a pointer to the cached descriptor 338 * 339 * @note This function can block 340 * @note No control transfer is sent. A device's active configuration descriptor is cached on enumeration 341 * @param[in] dev_hdl Device handle 342 * @param[out] config_desc Configuration descriptor 343 * @return esp_err_t 344 */ 345 esp_err_t usb_host_get_active_config_descriptor(usb_device_handle_t dev_hdl, const usb_config_desc_t **config_desc); 346 347 // ----------------------------------------------- Interface Functions ------------------------------------------------- 348 349 /** 350 * @brief Function for a client to claim a device's interface 351 * 352 * - A client must claim a device's interface before attempting to communicate with any of its endpoints 353 * - Once an interface is claimed by a client, it cannot be claimed by any other client. 354 * 355 * @note This function can block 356 * @param[in] client_hdl Client handle 357 * @param[in] dev_hdl Device handle 358 * @param[in] bInterfaceNumber Interface number 359 * @param[in] bAlternateSetting Interface alternate setting number 360 * @return esp_err_t 361 */ 362 esp_err_t usb_host_interface_claim(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl, uint8_t bInterfaceNumber, uint8_t bAlternateSetting); 363 364 /** 365 * @brief Function for a client to release a previously claimed interface 366 * 367 * - A client should release a device's interface after it no longer needs to communicate with the interface 368 * - A client must release all of its interfaces of a device it has claimed before being able to close the device 369 * 370 * @note This function can block 371 * @param[in] client_hdl Client handle 372 * @param[in] dev_hdl Device handle 373 * @param[in] bInterfaceNumber Interface number 374 * @return esp_err_t 375 */ 376 esp_err_t usb_host_interface_release(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl, uint8_t bInterfaceNumber); 377 378 /** 379 * @brief Halt a particular endpoint 380 * 381 * - The device must have been opened by a client 382 * - The endpoint must be part of an interface claimed by a client 383 * - Once halted, the endpoint must be cleared using usb_host_endpoint_clear() before it can communicate again 384 * 385 * @note This function can block 386 * @param dev_hdl Device handle 387 * @param bEndpointAddress Endpoint address 388 * @return esp_err_t 389 */ 390 esp_err_t usb_host_endpoint_halt(usb_device_handle_t dev_hdl, uint8_t bEndpointAddress); 391 392 /** 393 * @brief Flush a particular endpoint 394 * 395 * - The device must have been opened by a client 396 * - The endpoint must be part of an interface claimed by a client 397 * - The endpoint must have been halted (either through a transfer error, or usb_host_endpoint_halt()) 398 * - Flushing an endpoint will caused an queued up transfers to be canceled 399 * 400 * @note This function can block 401 * @param dev_hdl Device handle 402 * @param bEndpointAddress Endpoint address 403 * @return esp_err_t 404 */ 405 esp_err_t usb_host_endpoint_flush(usb_device_handle_t dev_hdl, uint8_t bEndpointAddress); 406 407 /** 408 * @brief Clear a halt on a particular endpoint 409 * 410 * - The device must have been opened by a client 411 * - The endpoint must be part of an interface claimed by a client 412 * - The endpoint must have been halted (either through a transfer error, or usb_host_endpoint_halt()) 413 * - If the endpoint has any queued up transfers, clearing a halt will resume their execution 414 * 415 * @note This function can block 416 * @param dev_hdl Device handle 417 * @param bEndpointAddress Endpoint address 418 * @return esp_err_t 419 */ 420 esp_err_t usb_host_endpoint_clear(usb_device_handle_t dev_hdl, uint8_t bEndpointAddress); 421 422 // ------------------------------------------------ Asynchronous I/O --------------------------------------------------- 423 424 /** 425 * @brief Allocate a transfer object 426 * 427 * - This function allocates a transfer object 428 * - Each transfer object has a fixed sized buffer specified on allocation 429 * - A transfer object can be re-used indefinitely 430 * - A transfer can be submitted using usb_host_transfer_submit() or usb_host_transfer_submit_control() 431 * 432 * @param[in] data_buffer_size Size of the transfer's data buffer 433 * @param[in] num_isoc_packets Number of isochronous packets in transfer (set to 0 for non-isochronous transfers) 434 * @param[out] transfer Transfer object 435 * @return esp_err_t 436 */ 437 esp_err_t usb_host_transfer_alloc(size_t data_buffer_size, int num_isoc_packets, usb_transfer_t **transfer); 438 439 /** 440 * @brief Free a transfer object 441 * 442 * - Free a transfer object previously allocated using usb_host_transfer_alloc() 443 * - The transfer must not be in-flight when attempting to free it 444 * - If a NULL pointer is passed, this function will simply return ESP_OK 445 * 446 * @param[in] transfer Transfer object 447 * @return esp_err_t 448 */ 449 esp_err_t usb_host_transfer_free(usb_transfer_t *transfer); 450 451 /** 452 * @brief Submit a non-control transfer 453 * 454 * - Submit a transfer to a particular endpoint. The device and endpoint number is specified inside the transfer 455 * - The transfer must be properly initialized before submitting 456 * - On completion, the transfer's callback will be called from the client's usb_host_client_handle_events() function. 457 * 458 * @param[in] transfer Initialized transfer object 459 * @return esp_err_t 460 */ 461 esp_err_t usb_host_transfer_submit(usb_transfer_t *transfer); 462 463 /** 464 * @brief Submit a control transfer 465 * 466 * - Submit a control transfer to a particular device. The client must have opened the device first 467 * - The transfer must be properly initialized before submitting. The first 8 bytes of the transfer's data buffer should 468 * contain the control transfer setup packet 469 * - On completion, the transfer's callback will be called from the client's usb_host_client_handle_events() function. 470 * 471 * @param[in] client_hdl Client handle 472 * @param[in] transfer Initialized transfer object 473 * @return esp_err_t 474 */ 475 esp_err_t usb_host_transfer_submit_control(usb_host_client_handle_t client_hdl, usb_transfer_t *transfer); 476 477 #ifdef __cplusplus 478 } 479 #endif 480