Starting with ESP32-P4 we can have targets that have more than 1 USB-OTG peripheral.
This commit adds an option to choose which peripherals will be used by USB Host lib.
Internally, we will still have only 1 Root HUB but with multiple Root ports.
Introduce a new HAL API `usb_dwc_hal_set_fifo_config()` that allows advanced users
to manually configure RX, Non-Periodic TX, and Periodic TX FIFO sizes. This offers
fine-grained control beyond the previous bias-based sizing approach.
The HAL function no longer returns `esp_err_t`, and internal validations are enforced
via `HAL_ASSERT()`. Responsibility for input validation has been moved to the HCD layer.
FIFO configuration must be applied before any USB pipes are created or activated.
This feature is intended for use during `usb_host_install()`.
If no custom FIFO configuration is provided (i.e., all values are zero),
the driver falls back to a bias-based default layout based on Kconfig settings
(`CONFIG_USB_HOST_HW_BUFFER_BIAS_*`). Bias resolution is done inside `hcd_port_init()`.
The `port_obj_t` structure has been extended with a `fifo_config` field, which stores
the configuration to allow re-application after a USB port reset.
Obsolete FIFO bias enums (`usb_hal_fifo_bias_t`, `hcd_port_fifo_bias_t`) and related
APIs (`hcd_port_set_fifo_bias()`) have been removed in favor of the new structure-based mechanism.
The HCD initialization and port reset flow has been updated to use the explicit
FIFO configuration.
USB Host maintainer documentation (`maintainers.md`) has been updated accordingly.
Test cases were updated to remove the usage of removed bias API and now rely on default
or custom FIFO configuration.
Changed error code from ESP_ERR_INVALID_STATE to ESP_ERR_NOT_FOUND
when the client never opened the device.
Updated function documentation to correctly reflect return values.
If you call *usb_host_device_close()* for a device that isn't open, the function exits early,
without giving back the semaphore it took, which causes any other call that tries to take
that semaphore to hang indefinitely.
Strangely, there's redundant handling of this condition, with two checks in a row that both handle
the case where `_check_client_opened_device(client_obj, dev_addr)` returns `false`:
```c
HOST_CHECK_FROM_CRIT(_check_client_opened_device(client_obj, dev_addr), ESP_ERR_NOT_FOUND);
if (!_check_client_opened_device(client_obj, dev_addr)) {
// Client never opened this device
ret = ESP_ERR_INVALID_STATE;
HOST_EXIT_CRITICAL();
goto exit;
}
…
exit:
xSemaphoreGive(p_host_lib_obj->constant.mux_lock);
return ret;
```
The first line is the one that exits early, as HOST_CHECK_FROM_CRIT returns its second parameter
if its first parameter is false, without giving back the semaphore (although it does exit
the critical section).
The subsequent block handles the exact same case, except that it ensures the semaphore is given
back before returning. Currently, this block is never reached.
Perhaps the first check was added, then someone noticed the issue and added the second check,
but they forgot to remove the first one.
In any case, this PR removes the first check, so the second check can properly handle this case
by giving back the semaphore before returning.
This bug appears to have been present in the initial commit of the USB Host library to the ESP-IDF
repo: accbaee57c
Of course, if you never try to close a non-opened device, then you won't encounter it!
Unfortunately, I have some code that tried to do that, which is how I found the issue.
Fixes issue where ESP_ERR_NO_MEM was being silently discarded after
cleaning up after a failed malloc in usb_host_client_register.
Signed-off-by: Daniel Mangum <georgedanielmangum@gmail.com>
This commit adds the usb_host_lib_set_root_port_power() function. This provides
a public API for users to power the root port OFF or ON at runtime, thus trigger
a disconnection or allow connections respectively.
In addition, the usb_host_config_t.root_port_unpowered install configuration is
provided to allow users to install the USB Host Library without automatically
powering ON the root port.
- usb host reads device's configuration on request
- a control transfer is sent
- memory is allocated for a new descriptor
- user must manually free the memory
This commit updates how the USBH handles device creation and enumeration so that
upper layers (such as the Hub driver) can use the USBH API for enumeration instead
of calling the HCD.
USBH Updates:
USBH now creates unenumerated devices set to address 0 with no device/config
descriptor. A newly created device can be opened and communicated with immediately
(using control transfers). This allows the Hub driver to call the USBH instead of
the HCD. Summary of USBH changes:
- Added new APIs to add/remove a device. Devices are now created as unenumerated
and can be immediately opened and communicated with.
- Added new APIs to enumerate a device (see 'usbh_dev_set_...()' functions). Device
must be locked (see 'usbh_dev_enum_lock()') before enumeration functions can be called.
- Added UID for each device. This allows the particular USBH without needing to
use the device's handle (which implies opening the device).
Hub Driver Updates:
Hub driver now calls the USBH for enumeration. Summary of USBH changes:
- Replace all 'hcd_pipe_...()' calls with 'usbh_dev_...()' calls
- Refactored port event handling to fit with new USBH API
- Updated to use UID to uniquely identify devices without opening them
USB Host Updates:
- Reroute USBH control transfers to clients and hub driver
This commit renames the following APIs and variables in the USBH:
- Rename the prefix of device pool functions from 'usbh_dev_...' to
'usbh_devs_...'.
- Rename 'ref_count' to 'open_count'. This variable tracks the number of times
a device has been opened.
Previously, on a device disconnection, the USBH and Hub would the require the
following 2-way interaction:
- Hub -> usbh_hub_pass_event() -> USBH to indicate a port error
- USBH -> usbh_hub_req_cb_t -> Hub to request port recovery after the device
has been freed.
The 2-way interaction has been simplified:
- USBH now nofities upper layers of devices being freed via the
USBH_EVENT_DEV_FREE event
- Hub now handles port recovery only after a device has been freed
This commit does the following:
- Updates the USBH event callback arguments to now pass a usbh_event_data_t
which can contain different data for each event
- Updated event names
- user callback funciton to set device configuration
as a part of usb_host_install
- callback provides device descriptor of a device being enumerated
- user can set which cfg descriptor the USB device will be set with
- user can filter device enumeration
- Kconfig menu to enable callback function
- usb_host_lib example demonstration
This commit removes internal event flags in the USB Host Library event handling
functions (i.e., usb_host_lib_handle_events() and usb_host_client_handle_events()).
Previously, these flags were added to reduce the number of times semaphores
were given. However, these flags were removed as the performance gain is
negligible and made the logic more complicated.
For usb_host_client_handle_events(), the following flags were removed:
- Remove 'events_pending' flag. The semaphore is now always given
- Remove 'blocked' flag. The 'handling_events' flag is already sufficient
- Critical sections are now shortened due to simplication of semaphore usage.
For usb_host_lib_handle_events(), the following flags were removed:
- Remove 'process_pending' flag. The semaphore is now always given
- Renamed 'blocked' flag to 'handling_events'
This commit removes the ability to reserve a header in the data buffer of an
allocated URB. The header was required for a now defunct implementation of a
synchronous USB Host library API. Thus, headers are no longer required in
URB data buffers.
This commit refactors the USBH and the USB Host Library in the following ways:
- USBH now presents an abstraction of an endpoint (via usbh_ep_handle_t)
- Added separate functions to enqueue/dequeue URBs to a particular endpoint
- USB Host Library no longer calls HCD API directly. Calls USBH endpoint API
instead.
- Renamed "notif_cb" to "proc_req_cb" (Processing Request Callback)
- This is to avoid confusion with FreerTOS task notifications and Host
Library client event notifications.
- The processing functions of each layer (i.e., "xxx_process()") request
calls via the "proc_req_cb"
- The main handling function (i.e., usb_host_lib_handle_events()) is
responsible for calling the required "xxx_process()" of each layer
usb_host_transfer_submit_control() uses the incorrect bmRequestType direction
flag. Therefore, when doing a transfer check, all transfers were mistakenly
treated as OUT transfers (only affects transfer check and not actual transfer).
This commit adds a simple flag/check in the USB Host Library that prevents
users from submitting a transfer that is already inflight.
- A transfer is considered inflight as soon as it is submitted by calling
usb_host_transfer_submit() or usb_host_transfer_submit_control()
- An inflight transfer remains inflight up until right before its callback
is called by one of the USB Host Library handler functions.
Closes https://github.com/espressif/esp-idf/issues/8748
This commit updates the USB Host Library as follows:
- usb_helpers.h
- Removed dependency on USB Host Library API
- Added function to print string descriptors
- usbh
- Fixed bug where an interface/endpoint could be claimed/allocated multiple times
- Removed redundant device ref_count change
- Added unit test for USB Host Library API usage
Hub Driver is refactored as follows:
This commit update and refactors the Hub Driver as follows:
- Refactored enumeration state machine and stage functions
- Enumeration stage is now incremented
- Combined transfer stages of enumeration into common functions
- Comments updated
- Fixed usbh_hal_disable_debounce_lock() that would cause root_port_handle_events()
to fail the HCD_PORT_CMD_RESET call because the previous port connection interrupt
was not cleared.
The following features were added to the Hub Driver
- Enumeration config descriptor is now fetched in two separate stages
- Header is fetched first to determine the wTotalLength of the descriptor
- Fetching the full descriptor will request exactly wTotalLength bytes
- This works around some non-compliant devices that will babble/return zero
when requesting a length > wTotalLength
- Closes https://github.com/espressif/esp-idf/issues/7799
- Enumeration now stores string descriptors
- The Manufacturer, Product, and Serial Number string descriptors are
now read and stored during enumeration
- String descriptors are now part of usb_device_info_t
- Added unit test to test enumeration
This commit updates the USB Host stack to use the USB PHY driver. The
USB PHY and the OTG Controller should now both be setup/deleted using
usb_new_phy() and usb_del_phy() respectively.
- The hcd_install() now expects the USB PHY and OTG Contorller to be
already setup before it is called
- usb_host_install() now has an option to skip calling usb_del_phy() if
the user wants to setup their own USB PHY (e.g., in the case of using
and external PHY).
- CDC-ACM and MSC examples/test updated to use internal PHY
Closes https://github.com/espressif/esp-idf/issues/8061
This commit updates the USB Host Library API in the following wasy:
- usb_host_client_handle_t and usb_device_handle_t made into struct pointers
to generate compiler warnings about conflicting handle types
- usb_host_client_config_t changed to future proof API for Synchronous Clients
- Added usb_host_lib_unblock()
- Added usb_host_device_addr_list_fill()
- Return of usb_host_device_free_all() updated to indicate whether there
are still devices yet to be freed.
- Blockg APIs are now marked explicitly
- Fixed a bug in usb_host_transfer_submit_control() when checking the bEndpointAddress
of a control transfer.
Tests are also refactored to move some common macros into shared headers
Closes https://github.com/espressif/esp-idf/issues/7786
- This commit adds the API documentation for the USB Host Library.
- Warnings about the beta API are also added.
- usb_host_misc.h renamed to usb_helpers.h
This commit adds the preliminary version of the USB Host Library. This commit contains:
- USBH (USB Host Driver)
- Hub Driver that only supports a single device and device enumeration
- USB Host Library (asychronous API)
- Test cases for USB Host Library asychronous API
The following changes were made to the existing HCD:
- Removed HCD_PIPE_STATE_INVALID. Pipes are no longer invalidated
- Changed pipe commands to halt, flush, and clear. Pipes need to be manually
halted, flush, and cleared.
- Halting and flushing a pipe will execute the pipe callback if it causes a
HCD_PIPE_EVENT_URB_DONE event