Skip to content

Synopsys-OTG: type-erase endpoint counts#6097

Merged
Dirbaio merged 17 commits into
embassy-rs:mainfrom
bugadani:synopsys
May 25, 2026
Merged

Synopsys-OTG: type-erase endpoint counts#6097
Dirbaio merged 17 commits into
embassy-rs:mainfrom
bugadani:synopsys

Conversation

@bugadani
Copy link
Copy Markdown
Contributor

@bugadani bugadani commented May 13, 2026

This PR allows type-erasing the USB instance in HAL drivers without forcing them to use the same capacity endpoint/channel state buffer (i.e. without wasting memory for the "smaller" peripheral). This is done by introducing a type-erased state struct that holds slices and references, and also by moving the endpoint allocation buffers to the global state. This is the foundation for esp-rs/esp-hal#5560

@bugadani bugadani force-pushed the synopsys branch 2 times, most recently from fadd085 to e70ef64 Compare May 13, 2026 14:17
@bugadani bugadani marked this pull request as ready for review May 14, 2026 08:08
Copilot AI review requested due to automatic review settings May 14, 2026 08:08
@bugadani bugadani marked this pull request as draft May 14, 2026 08:10
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes const-generic endpoint/channel counts from the Synopsys OTG device/host drivers by introducing type-erased OtgState/OtgHostState views, moving endpoint allocation bookkeeping into State, and updating downstream HAL crates to pass the new state views. It also aims to expand host channel support up to 16 channels.

Changes:

  • Introduce OtgState/OtgHostState type-erased borrows and make OtgInstance/OtgHostInstance non-generic.
  • Move endpoint allocation tracking into State and update FIFO sizing/IRQ mask computation to use shared state.
  • Update STM32 + nRF wrappers to use the new type-erased state and non-generic driver/bus types.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
embassy-usb-synopsys-otg/src/otg_v1.rs Adjust host-channel register accessor bounds (but currently inconsistent).
embassy-usb-synopsys-otg/src/lib.rs Introduce OtgState, move endpoint allocation to State, remove const generics from driver/bus/instance.
embassy-usb-synopsys-otg/src/host.rs Introduce OtgHostState, remove const generics from host types, add runtime clamping in allocator.
embassy-usb-synopsys-otg/CHANGELOG.md Document breaking API change + 16 host channel support.
embassy-stm32/src/usb/otg.rs Adapt STM32 OTG wrapper to new type-erased state + non-generic Synopsys driver/bus.
embassy-nrf/src/usb/usbhs.rs Adapt nRF USBHS wrapper to new type-erased state + non-generic Synopsys driver/bus.
Comments suppressed due to low confidence (3)

embassy-usb-synopsys-otg/src/lib.rs:316

  • OtgState::ep_alloc_get indexes ep_{in,out}_alloc[index] directly. With the new type-erased API, callers can pass an endpoint_count larger than these slices, causing a panic. Consider using .get(index) and returning None when out of range (and/or asserting the invariant once when constructing/using OtgInstance).
    pub(crate) fn ep_alloc_get(&self, dir: Direction, index: usize) -> Option<&EndpointData> {
        unsafe {
            match dir {
                Direction::In => (*self.ep_in_alloc[index].get()).as_ref(),
                Direction::Out => (*self.ep_out_alloc[index].get()).as_ref(),

embassy-usb-synopsys-otg/src/lib.rs:325

  • ep_fifo_size_in iterates 0..endpoint_count and calls ep_alloc_get, which will panic if endpoint_count exceeds the backing slice lengths. Since endpoint_count is now runtime-provided, clamp it to min(endpoint_count, ep_in_alloc.len()) (and similarly in the other helpers) or assert the invariant once and reuse the checked value.
    pub(crate) fn ep_fifo_size_in(&self, endpoint_count: usize) -> u16 {
        (0..endpoint_count)
            .filter_map(|i| self.ep_alloc_get(Direction::In, i))
            .map(|ep| ep.fifo_size_words)
            .sum()

embassy-usb-synopsys-otg/src/host.rs:136

  • on_host_interrupt guards ch_num >= ch_count, but after type-erasing HostState, ch_count is no longer type-coupled to state.channels.len(). If a caller passes a larger ch_count than the slice length, state.channels[ch_num] can panic in the ISR. Clamp ch_count to state.channels.len() (or assert the invariant) at the start of the handler.
pub unsafe fn on_host_interrupt(r: Otg, state: &OtgHostState<'_>, ch_count: usize) {
    let gintsts = r.gintsts().read();

    // Clear SOF interrupt immediately to avoid flooding.
    if gintsts.sof() {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread embassy-usb-synopsys-otg/src/otg_v1.rs Outdated
Comment thread embassy-usb-synopsys-otg/src/lib.rs
@bugadani bugadani force-pushed the synopsys branch 3 times, most recently from 3ac81cb to a28fd88 Compare May 14, 2026 08:40
@bugadani bugadani marked this pull request as ready for review May 14, 2026 08:49
@bugadani bugadani force-pushed the synopsys branch 4 times, most recently from 6676033 to 24cd844 Compare May 17, 2026 20:29
Comment thread embassy-usb-synopsys-otg/src/host.rs Outdated
Comment thread embassy-usb-synopsys-otg/src/host.rs Outdated
Comment thread embassy-usb-synopsys-otg/src/host.rs Outdated
@bugadani bugadani marked this pull request as draft May 18, 2026 19:33
@bugadani bugadani force-pushed the synopsys branch 6 times, most recently from 996fe3d to 04556dd Compare May 20, 2026 20:45
@bugadani

This comment was marked as resolved.

@bugadani bugadani marked this pull request as ready for review May 22, 2026 09:14
@Dirbaio Dirbaio added this pull request to the merge queue May 25, 2026
Merged via the queue into embassy-rs:main with commit 38fa2ac May 25, 2026
7 checks passed
@bugadani bugadani deleted the synopsys branch May 25, 2026 22:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants