Skip to content

Conversation

@jfischer-no
Copy link
Contributor

@jfischer-no jfischer-no commented Apr 2, 2025

Add UDC Kconfig option to enable SOF interrupts.
Disable SOF interrupt in drivers that are maintainable and do not obfuscate how interrupts are enabled. If the new Kconfig option is disabled, no SOF events are passed to the higher layer.

Resolves: #87732

I also wanted to address #74058 in the same PR, but that requires more upfront work.

@henrikbrixandersen
Copy link
Member

Disable SOF interrupt in drivers that are maintainable and do not obfuscate how interrupts are enabled.

Could you elaborate on this?

@MarkWangChinese
Copy link
Contributor

Hi @jfischer-no Could I add one commit in your pr to disable USB_DEVICE_CONFIG_SOF_NOTIFICATIONS based on CONFIG_UDC_ENABLE_SOF for NXP EHCI and IP3511 controller wrapper driver.

Comment on lines 5 to 6
CONFIG_USBD_AUDIO2_CLASS=y
CONFIG_UDC_ENABLE_SOF=y
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the class depend on CONFIG_UDC_ENABLE_SOF? UAC2 cannot work at all without SOF. Changing the default here just makes the actual samples work, but does not prevent in any way configuring an completely not working software.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can add depends on UDC_ENABLE_SOF. I was not sure when I finished the commit. I am thinking about moving the SoF call to be in driver thread context, which could also be meta IRQ or have its own SoF meta IRQ thread, but that needs to be per usbd_context or have its own message queue and is IMO too much. Unfortunately, few drivers use the UDC work queue.

Copy link
Contributor

@tmon-nordic tmon-nordic Apr 7, 2025

Choose a reason for hiding this comment

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

I don't quite think meta IRQ is the way to go. One very important feature of SOF is that if the SW is too late, then all the past work does not really matter (any missed isochronous data is lost forever). The SW has always to worry only what to do within current SOF and the fact how many was missed is not really important.

Using queue for deferring SOF handling allows the queue to become full. I don't think it is about ensuring how fast the queue is handled, but rather about how to avoid the now-obsolete (past deadline) work.

Comment on lines 2157 to 2158
IF_ENABLED(CONFIG_UDC_ENABLE_SOF, (USB_DWC2_GINTSTS_SOF |))
USB_DWC2_GINTSTS_INCOMPISOOUT | USB_DWC2_GINTSTS_INCOMPISOIN,
Copy link
Contributor

Choose a reason for hiding this comment

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

Isochronous transfers won't work without SOF and therefore there is no point in having INCOMPISOOUT and INCOMPISOIN enabled without SOF.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't quite understand. Will these interrupts be triggered even if SOF is disabled and must not be enabled here?

Copy link
Contributor

@tmon-nordic tmon-nordic Apr 7, 2025

Choose a reason for hiding this comment

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

INCOMPISOIN/INCOMPISOOUT will be triggered if SOF is disabled if an isochronous transfer was scheduled and host did not send the IN or OUT token within first 80% of the (micro-)frame.

Isochronous transfers won't really work on DWC2 without SOF interrupt due to how the scheduling works (even/odd bit) and that this manual reschedule is required from driver.

@jfischer-no
Copy link
Contributor Author

Disable SOF interrupt in drivers that are maintainable and do not obfuscate how interrupts are enabled.

Could you elaborate on this?

I will try it very briefly. What started with shim drivers in Zephyr, bad idea, is now some kind of interface to the HAL driver. HAL drivers, code that vendors claim to reuse, but that is not true, because then it would finally be a native driver; use Zephyr primitives, Kconfig options, and enable/disable IRQ in their own or obfuscated way.

@jfischer-no
Copy link
Contributor Author

jfischer-no commented Apr 3, 2025

Hi @jfischer-no Could I add one commit in your pr to disable USB_DEVICE_CONFIG_SOF_NOTIFICATIONS based on CONFIG_UDC_ENABLE_SOF for NXP EHCI and IP3511 controller wrapper driver.

@MarkWangChinese Yes. You can also wait for it to be merged and open a PR to disable interrupts. The driver will not send SoF events anyway, but there will be ISR noise.

AlessandroLuo
AlessandroLuo previously approved these changes Apr 7, 2025

config USBD_AUDIO2_CLASS
bool "USB Audio 2 class support [EXPERIMENTAL]"
depends on UDC_ENABLE_SOF
Copy link
Contributor

@tmon-nordic tmon-nordic Apr 8, 2025

Choose a reason for hiding this comment

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

Actually select UDC_ENABLE_SOF is better than depends on UDC_ENABLE_SOF because:

  • USB Audio 2 class support is then always visible in "New USB device stack" menu
  • The requirement is reflected by showing -*- SOF interrupt processing (can only be disabled if UAC2 is disabled)

With depends on UDC_ENABLE_SOF, disabling SOF interrupt processing disables USB Audio 2 class without any notice to the user.

Copy link
Contributor

Choose a reason for hiding this comment

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

This needs to be addressed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed it to 'select' for now, but using 'depends on' is just fine and follows https://docs.zephyrproject.org/latest/build/kconfig/tips.html. We've already experienced a few terrible 'select -> depends on' changes in the past.

@jfischer-no jfischer-no force-pushed the pr-resolve-87732 branch 2 times, most recently from 173e047 to 0e18cab Compare April 22, 2025 11:28
* @brief Helper function to store UDC SOF stamp.
*
* @param[in] dev Pointer to device struct of the driver instance
* @param[in] fnumber Frame number
Copy link
Contributor

Choose a reason for hiding this comment

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

While for Full-Speed this is enough, the description is insufficient regarding to what value is expected at High-Speed.

Universal Serial Bus Specification Revision 2.0 10.2.3 Frame and Microframe Generation

Host controllers operating with full-speed devices maintain a current frame number (at least 11 bits) that
increments at a 1 ms period. The host transmits the lower 11 bits of the current frame number in each SOF
token transmission.
Host controllers operating with high-speed devices maintain a current microframe number (at least 14 bits)
that increments at a 125 µs period. The host transmits bits 3 through 13 of the current microframe number
in each SOF token transmission. This results in the same SOF packet value being transmitted for eight
consecutive microframes before the SOF packet value increments.

Is the fnumber parameter supposed to be the actual microframe number (i.e. contain the bits 0 through 2, derived by device controller) when operating at High-Speed?

struct net_buf *setup;
/** Driver private data */
void *priv;
#if CONFIG_UDC_ENABLE_SOF
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this new functionality be split away from this PR?

Comment on lines 204 to 212
/*
* Queue the SOF events only if they are from the ISR context.
* Primarily to avoid message queue flooding from high speed
* controllers.
*/
if (event->type == UDC_EVT_SOF && !k_is_in_isr()) {
usbd_class_bcast_event(uds_ctx, event);
return 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the real point here? Isn't this just guarding against broken drivers? Shouldn't this be an assert?


config USBD_AUDIO2_CLASS
bool "USB Audio 2 class support [EXPERIMENTAL]"
depends on UDC_ENABLE_SOF
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs to be addressed.

}

if (evt & BIT(DWC2_DRV_EVT_SOF)) {
udc_update_sof_stamp(dev, priv->sof_num);
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't make sense. The timestamp will have a way too big jitter for any practical use.

Add helper to handle SOF interrupts/events and new Kconfig option to
disable SOF interrupt.

Signed-off-by: Johann Fischer <[email protected]>
If the new Kconfig option is disabled, no SOF events are passed to the
higher layer.

Signed-off-by: Johann Fischer <[email protected]>
@sonarqubecloud
Copy link

@jfischer-no jfischer-no added this to the v4.2.0 milestone Jun 20, 2025
@fabiobaltieri fabiobaltieri merged commit 7b287ec into zephyrproject-rtos:main Jun 23, 2025
26 checks passed
@jfischer-no jfischer-no deleted the pr-resolve-87732 branch June 23, 2025 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Drivers area: Samples Samples area: USB Universal Serial Bus Experimental Experimental features not enabled by default platform: Ambiq Ambiq platform: ITE ITE platform: NXP Drivers NXP Semiconductors, drivers platform: STM32 ST Micro STM32

Projects

None yet

Development

Successfully merging this pull request may close these issues.

USB next stack: make SOF events optional

8 participants