Add a USB Video Class (UVC) host class implementation that enables
Zephyr-based systems to act as USB hosts for standard UVC cameras.
This allows applications to capture video streams from USB cameras
using the standard Zephyr video API.
The implementation follows the UVC specification for device enumeration,
format negotiation, and stream control. It handles the complexity of UVC
descriptor parsing, bandwidth management, and isochronous transfer
scheduling, presenting a clean video device interface to applications.
Support for common camera controls such as brightness, contrast,
exposure, focus, and zoom allows applications to adjust camera settings
at runtime. Dynamic format and frame rate changes are also supported,
making it suitable for various use cases from simple video capture to
more advanced computer vision applications.
Signed-off-by: Aiden Hu <weiwei.hu@nxp.com>
Preallocate and keep reusing the same buffer for SETUP data. This
ensures that USB stack will always be able to handle SETUP stage
regardless of UDC memory pool usage.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Allocating buffer in response to control transfer is part of processing
and therefore should not be done in UDC driver but rather in the stack.
Simplify UDC driver design by moving all control transfer buffer
allocations and processing to USB stack.
New control transfer handling flow is as follows:
1. USB stack allocates and queues buffer for Setup stage. This informs
UDC driver that USB stack is ready to process new transfer.
2. UDC driver completes enqueued Setup buffer. SETUP data may have
been received by device before Setup buffer was enqueued.
If multiple SETUP data was received, UDC driver must complete
request using last received SETUP data.
3. USB stack processes request. USB stack is responsible for:
* Stalling control endpoint when request cannot be processed
* Allocating and enqueueing Data stage buffer if necessary
- Depending on enqueued endpoint (IN/OUT), UDC driver is
expected to complete the transfer. If host sends new SETUP
data for any reason (e.g. timeout), then Data stage buffer
must be completed with -ECONNRESET code.
- UDC driver may postpone processing Data IN until USB stack
enqueues new Setup stage buffer.
* Handling status stage if applicable
- If Data IN was enqueued, stack immediately allocates and
enqueues Status OUT stage buffer.
- If Data OUT was enqueued, stack waits for Data OUT buffer
completion before doing any further processing.
- If control transfer handling fails, stack is expected to
STALL control endpoint.
* Allocating and enqueuing Setup buffer.
- This informs UDC driver that stack has finished processing
control transfer. UDC driver may choose to start processing
Data IN and/or Status OUT only after new Setup buffer is
enqueued.
4. UDC driver must fail (complete with -ECONNRESET) any enqueued and
not completed Data and Status buffers if host sends new SETUP data.
UDC driver must be able to buffer last received SETUP data until
USB stack is ready (enqueues Setup buffer).
5. UDC driver must complete all Data and Status buffers before it
completes Setup buffer.
6. UDC driver may keep ownership of Setup, Data and/or Status buffers
across USB bus resets. USB stack does not attempt to dequeue any
control transfer buffer it enqueued.
This approach implicitly synchronizes UDC driver against USB stack,
which ensures that only one set of Setup/Data/Status buffers is
allocated at a time.
Another advantage of the rework is drawing a clear line on buffer
ownership. The buffer responsibilities are as follows:
* USB stack is the only entity that both allocates and frees the
buffers. Only USB stack is allowed to set "setup", "data" and
"status" fields in struct udc_buf_info.
* UDC takes ownership of buffers handed to it in udc_ep_enqueue().
* UDC releases buffer ownership by calling udc_submit_ep_event().
Because there is just a single place where the buffer ownership changes,
and all buffers must go USB stack (alloc) -> UDC (perform requests on
the bus) -> USB stack (free) route it would be possible in the future to
implement a "tap" similar to Linux usbmon that would ease debugging.
This commit significantly changes how USB stack communicates with UDC
drivers. It was decided that supporting both the old and new model
simultaneously would require way too much effort. Therefore all UDC
drivers were reworked. Following people worked on driver rework:
* Tomasz Moń - ambiq, dwc2, kinetis, mcux ip3511, nrf, numaker,
renesas ra, rpi pico, smartbond, virtual
* Mathieu Choplain - stm32
* Mark Wang - mcux ehci
* Johann Fischer - sam0, stm32
* Ren Chen - it82xx2
* Brandon Hurst - max32
* Gerson Fernando Budke - sam udp, sam usbc, sam usbhs
Co-authored-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Co-authored-by: Johann Fischer <johann.fischer@nordicsemi.no>
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Co-authored-by: Mark Wang <yichang.wang@nxp.com>
Signed-off-by: Mark Wang <yichang.wang@nxp.com>
Co-authored-by: Ren Chen <Ren.Chen@ite.com.tw>
Signed-off-by: Ren Chen <Ren.Chen@ite.com.tw>
Co-authored-by: Brandon Hurst <brandon.hurst@analog.com>
Signed-off-by: Brandon Hurst <brandon.hurst@analog.com>
Co-authored-by: Gerson Fernando Budke <nandojve@gmail.com>
Signed-off-by: Gerson Fernando Budke <nandojve@gmail.com>
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Replaces usage of these deprecated macros with ones that support
fixed and mapped partition compatibles. Also includes an update to
hal_espressif which also (rightly or wrongly) has zephyr specific
code in it
Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
The attach and detach flow was previously scattered across bus event
handlers and class code, causing duplicated enumeration and class
probe/remove logic. Root-device state was also manipulated directly in
the host context, which made lifecycle handling implicit and limited
the ability to support devices behind a hub.
This update introduces common helpers for device attach and detach and
replaces direct root access with simple accessor functions. By unifying
enumeration and teardown into a single path, the control flow becomes
clearer and more consistent, and the host stack is no longer tied to a
single-root assumption. These changes form the basis for supporting
multiple devices attached through a hub in future updates.
Signed-off-by: Aiden Hu <weiwei.hu@nxp.com>
Fix the qsort comparison function that was hitting an integer underflow.
Some video sources such as video-sw-generator have UINT32_MAX for maximum
frame interval (arbitrarily slow), which made the comparison underflow,
which in turn lead to frame interval being listed in the wrong order,
breaking Windows support.
Fixes#101259.
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
Reduce the log level to debug for a number of internal status logs within
the USB device_next stack.
Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
Adds compile-time option for overriding UAC2 Feedback endpoint to allow
usage with non-class-compliant Windows UAC2 driver.
Signed-off-by: James Bennion-Pedley <James.Bennion-Pedley@thinksmartbox.com>
Control read handlers handle_get_status(), handle_get_state() and
handle_upload() return value is used to set errno. Setting errno inside
the functions and then returning 0 therefore does not fail the request
as intended.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
The standard format "frame-based payload" was abused as a way to get
generic descriptors that match all other format and frame types.
This is not accurate as some fields do not match, causing misalignment
of some struct fields in some case.
Correct the misuse by introducing new valid structs and refactoring the
descriptor parsing to use them instead.
Signed-off-by: Josuah Demangeon <me@josuah.net>
Only bind to a controller after probing. Wait that a class is matching and
assigned to a device to assign a host controller to a class. This allows
a class to be used by any of the controller in place.
Remove the `c_data->uhs_ctx` field, not used anywhere, in favor of using
`c_data->udev->ctx`.
Signed-off-by: Josuah Demangeon <me@josuah.net>
Convert USB device shell command help strings to use the
SHELL_HELP() macro instead of inline help text.
This aligns the USB device shell with the updated shell help
formatting used across the tree and ensures consistent
presentation of command descriptions and argument usage.
Signed-off-by: Muhammad Waleed Badar <walid.badar@gmail.com>
zsock_send() does not necessarily have to send the entire data. Use the
recently introduced function zsock_send_all().
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Depending on the server, functions, and client application, we may
get out of transfers very quickly. To throttle here may allow
submitted transfers to be finished.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
UHC transfer handling and assignment of completed transfers to URB
sequences relies on the buf->size. For that, we can just use variable
net_buf pools instead of fixed. Perhaps it gives us also better
utilization of the buffer.
Add Kconfig optons to configure pool size and number of buffers
and use large default pool size for native_sim platform.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Make request completion handling a bit more robust when, for whatever
reason, the connection has been closed. Do not implicitly clear the USB
device pointer on client disconnect, to allow the completion callback to
clean up. Before handling USBIP_RET_SUBMIT, check whether the device is
still exported, and if not, just drop completed transfer.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Move the Kconfig template to configure the number of instances in, for
example, functions or class drivers, to a common directory.
This makes it less confusing when used in host support.
Template was not used in CDC ECM function and can be removed.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Instead of calling the low-level function from usbh_ch9.c, call the
higher level function from usbh_device.c to update the address,
making sure that the udev->address and udev->state are updated
appropriately.
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
To complement usbh_req_set_address(), add a matching function
usbh_device_set_address() that also takes care of updating the data
structures.
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
According to the USB CDC 1.2 specification, section 4.6, the value of
bInterfaceSubClass for the data interface should be 0.
Signed-off-by: Jay Beavers <jay@tolttechnologies.com>
Flag the ECM and NCM interfaces as supporting promisc mode. There's no
filtering really so enabling promisc is a noop but pretending to have
support is needed to allow these to be added to a bridge.
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Compute the maximum of the CONFIG_USBD_VIDEO_MAX_FRMIVAL and
CONFIG_USBH_VIDEO_MAX_FRMIVAL for struct definition, so that
the same struct can be relevant for both host and device
implementation.
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
Signed-off-by: Aiden Hu <weiwei.hu@nxp.com>
Co-authored-by: Aiden Hu <weiwei.hu@nxp.com>
Loop through each of the VideoStreaming and VideoControl descriptor
to parse them. This is meant as a stub for the purpose of testing the
class API.
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
Move UVC helper functions to a file shared between UVC host and device.
The arrays are not visible anymore from either USB host or device, but
instead accessed through a front-end funciton.
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
With the C23 standard, false and true are keywords and constants of type
bool with a value of 0 and 1. Though there does not seem to be issues
with GCC version 14, there is a note in the specification that the
spelling of false and true inside expressions that are subject to the #
and ## preprocessing operators is unspecified.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Correct function prototype which causes a compiler warning
and builds to fail due to it.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
The USB host will have to select the appropriate size for the configurtion
descriptor, and the defaults will not be enough for some classes that
encode a lot of information in the configuration descriptor.
Add logging to debug this.
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
Add tests making sure the USB Host class APIs introduced build
and run as expected. Use USB device samples common code for
initialization.
Co-authored-by: Johann Fischer <johann.fischer@nordicsemi.no>
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
Allocate a larger size to keep room for a nil descriptor at the end of
the configuration descriptor. This is used to walk through the list of
descriptors until this empty descriptor happens.
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
Make sure that there is at least enough room for the header before
dereferencing the fields such as bLength.
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
Move the UVC header with all the definitions from the UVC standard to
share it between USB host and device class implementation.
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
Add functions to probe/remove all classes as part of a new usbh_class.c
and a matching usbh_class.h. These functions are called from the function
usbh_init_device_intl() in usbh_core.c to initialize every class upon
connection of a device. Every class driver provide filters to match the
interfaces of the device.
Co-authored-by: Aiden Hu <weiwei.hu@nxp.com>
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
Add basic functions to initialize and probe class drivers.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
Add helpers to parse and validate USB descriptors.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
In addition to storing the interface pointers, also store the pointers
for the interface association. Also add comments to the other fields
of the structs to adapt to a new CI check.
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
Add API wrappers around the function pointers in struct usbh_class_api,
while also documenting the USB host class internal API.
Signed-off-by: Josuah Demangeon <josuah.demangeon@nordicsemi.no>
Make USBD_HWINFO_DEVID_LENGTH prompt optional so that the code compiles
even if HWINFO is disabled.
Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
When the USB Bus is reset, the USBD stack will disable and re-enable
all Classes. If this occurs while streaming audio with UAC2, the
terminals remain active when re-enabled, yet the endpoints have
yet to be enabled (resulting in -ENODEV logspam). This change
disables all active terminals when the class is disabled.
Signed-off-by: Victor Brzeski <vbrzeski@gmail.com>
In c52c206e26 &
32059d7414 the USB code was changed to
use the Zephyr native net_ prefixed API, but some were forgotten
(nto[hn][ls]()). Let's change it now.
Without this fix/change the code still builds as we are by now setting
CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things
fail to build.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
In 32059d7414 this code was changed to
use the Zephyr native net_ prefixed API, but some were forgotten
(ntohs()). Let's change it now.
Without this fix/change the code still builds as we are by now setting
CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things
fail to build.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
In c52c206e26 this code was changed to use
the Zephyr native net_ prefixed API, but some were forgotten
(ntohs()). Let's change it now.
Without this fix/change the code still builds as we are by now setting
CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things
fail to build.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
Remove duplicated #include directives within the same
preprocessor scope across the Zephyr tree.
Duplicates inside different #ifdef branches are preserved
as they may be intentional.
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
The qsort() function takes a callback argument that is having the
same semantics as strcmp(). Fix uvc_compare_frmival_desc() sorting
to make qsort() list frame intervals in increasing values.
Fix a bug where Windows would not enumerate devices when the video device
have multiple frame interval supported.
Signed-off-by: Josuah Demangeon <me@josuah.net>