Zephyr OS Composite USB: Diagnose Endpoint Capability Before Counting Interfaces

Two USB functions that work separately may fail when combined because the controller cannot satisfy the combined endpoint requirements. Counting interfaces or class instances alone does not establish that a composite configuration fits. Review the required endpoint direction, transfer type and packet size against the actual controller and selected configuration.

This discussion uses Zephyr 4.4.0's newer USB device stack and common UDC implementation. It does not claim that a particular board supports a specific composite device. Controller-specific endpoint allocation, shared memory and FIFO restrictions still need separate verification.

Composite USB review maps active class endpoint requirements to direction, type, packet size and controller enable results.
Original conceptual engineering diagram. Proposed review method, not a measured result.

Inventory requirements by active configuration

Build a small endpoint inventory from the actual class descriptors. For each relevant endpoint, identify its direction, transfer type and maximum packet size, together with the class instance that requires it. Keep full-speed and high-speed configurations distinct where the device supports both.

The tagged USB configuration implementation keeps speed-specific configuration lists. Adding a high-speed configuration checks both compiled stack support and controller speed capability. Selecting a configuration invokes default-interface setup before recording the new configuration and enabling classes.

Those stages provide useful diagnostic boundaries. A registration or initialization failure is different from a host selecting a configuration whose endpoints then fail to activate. Record the first failing stage and return value before experimenting with descriptor edits.

Do not add every descriptor in the entire firmware as if all alternative configurations were simultaneously active. Conversely, do not assume that resources used by different functions in the same active configuration can be shared merely because the applications rarely transfer data at the same moment.

An endpoint number is not a capability guarantee

The tagged UDC common code validates direction, transfer type, maximum packet size and relevant high-bandwidth capability. Its trial configuration path distinguishes a missing endpoint configuration from an unsupported request. Endpoint enabling separately rejects an already enabled endpoint and invokes the controller's enable operation.

This explains why “there are enough endpoint numbers” is an incomplete conclusion. A hypothetical additional interrupt-IN function may need a capability that the remaining controller resources cannot provide, even if a simplistic total count appears acceptable. The actual driver and hardware determine the constraints.

Use the common checks as evidence about the request presented to the controller, not as proof that every controller-specific resource has been modeled there. A driver may have further restrictions in its endpoint-enable implementation. Follow the failure into that implementation when the common validation succeeds but activation still fails.

Compare the failing composition with working subsets

A useful controlled comparison begins with each function alone, then the intended combination with unchanged versions and build settings. Capture the endpoint inventory and initialization result for each. If adding one function changes allocation or descriptors for another, preserve that difference instead of reducing the finding to “class B is broken.”

Change one relevant requirement at a time during diagnosis. Removing an optional function can establish a resource relationship, but it is not a production fix until the resulting product still meets its requirements. Reducing a packet size or changing a transfer type without checking the class contract can create a different incompatibility.

Also examine endpoint address collisions within the active configuration. Do not resolve a collision by choosing an arbitrary address that the controller cannot implement. The revised address must remain consistent through descriptor generation, class handling and controller allocation.

Verify the configuration the host actually selected

A firmware image can contain a configuration that is never the one exercised during testing. Match the host-observed configuration and speed to the device-side diagnostic record. Repeat at supported speed modes rather than assuming success at one mode proves the other.

The integration is ready when the full active composition fits the controller, every endpoint request is explainable, and configuration activation succeeds with the intended host-visible descriptors. This is a concrete resource-allocation check, separate from later protocol traffic, endpoint halt recovery or disconnect lifetime handling.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *