Skip to content

Commit 61432e7

Browse files
committed
usb: Implement SOF handling hooks in the USB stack
1 parent 23623d6 commit 61432e7

File tree

8 files changed

+33
-8
lines changed

8 files changed

+33
-8
lines changed

embassy-nrf/src/usb/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ impl<'d, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, V> {
160160
))
161161
}
162162

163-
fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
163+
fn start(self, control_max_packet_size: u16, _enable_sof_interrupts: bool) -> (Self::Bus, Self::ControlPipe) {
164164
(
165165
Bus {
166166
regs: self.regs,

embassy-rp/src/usb.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
330330
self.alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms)
331331
}
332332

333-
fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
333+
fn start(self, control_max_packet_size: u16, _enable_sof_interrupts: bool) -> (Self::Bus, Self::ControlPipe) {
334334
let regs = T::regs();
335335
regs.inte().write(|w| {
336336
w.set_bus_reset(true);

embassy-stm32/src/usb/otg.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,8 @@ impl<'d, T: Instance> embassy_usb_driver::Driver<'d> for Driver<'d, T> {
250250
.alloc_endpoint_out(ep_type, ep_addr, max_packet_size, interval_ms)
251251
}
252252

253-
fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
254-
let (bus, cp) = self.inner.start(control_max_packet_size);
253+
fn start(self, control_max_packet_size: u16, enable_sof_interrupts: bool) -> (Self::Bus, Self::ControlPipe) {
254+
let (bus, cp) = self.inner.start(control_max_packet_size, enable_sof_interrupts);
255255

256256
(
257257
Bus {

embassy-stm32/src/usb/usb.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
514514
self.alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms)
515515
}
516516

517-
fn start(mut self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
517+
fn start(mut self, control_max_packet_size: u16, _enable_sof_interrupts: bool) -> (Self::Bus, Self::ControlPipe) {
518518
let ep_out = self
519519
.alloc_endpoint(EndpointType::Control, None, control_max_packet_size, 0)
520520
.unwrap();

embassy-usb-driver/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ pub trait Driver<'a> {
168168
///
169169
/// This consumes the `Driver` instance, so it's no longer possible to allocate more
170170
/// endpoints.
171-
fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe);
171+
fn start(self, control_max_packet_size: u16, enable_sof_interrupts: bool) -> (Self::Bus, Self::ControlPipe);
172172
}
173173

174174
/// USB bus trait.
@@ -402,6 +402,9 @@ pub enum Event {
402402

403403
/// The USB power has been removed. Not supported by all devices.
404404
PowerRemoved,
405+
406+
/// A Start of Frame token has been received
407+
SOF,
405408
}
406409

407410
/// Allocating an endpoint failed.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ impl<'d, const MAX_EP_COUNT: usize> embassy_usb_driver::Driver<'d> for Driver<'d
479479
self.alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms)
480480
}
481481

482-
fn start(mut self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
482+
fn start(mut self, control_max_packet_size: u16, _enable_sof_interrupts: bool) -> (Self::Bus, Self::ControlPipe) {
483483
let ep_out = self
484484
.alloc_endpoint(EndpointType::Control, None, control_max_packet_size, 0)
485485
.unwrap();

embassy-usb/src/builder.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,18 @@ pub struct Config<'a> {
117117
/// Default: 100mA
118118
/// Max: 500mA
119119
pub max_power: u16,
120+
121+
/// Whether to enable SOF interrupts
122+
///
123+
/// Start of Frame can be a useful event on the bus, happening either every
124+
/// 1ms for USB LS and FS, or every 125µs for USB HS. This can be used as a
125+
/// free extra timer in a lot of cases, and as a way to process events at
126+
/// the end of the frame if things needed deferring. However, this can be
127+
/// a significant amount of interrupt traffic, so only enable this if you
128+
/// really need this style of handling.
129+
///
130+
/// Default: `false`
131+
pub enable_sof_interrupts: bool,
120132
}
121133

122134
impl<'a> Config<'a> {
@@ -138,6 +150,7 @@ impl<'a> Config<'a> {
138150
supports_remote_wakeup: false,
139151
composite_with_iads: true,
140152
max_power: 100,
153+
enable_sof_interrupts: false,
141154
}
142155
}
143156
}

embassy-usb/src/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ pub trait Handler {
111111
let _ = alternate_setting;
112112
}
113113

114+
/// Called when a SOF token is processed.
115+
fn sof(&mut self) {}
116+
114117
/// Called when a control request is received with direction HostToDevice.
115118
///
116119
/// # Arguments
@@ -225,7 +228,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
225228
) -> UsbDevice<'d, D> {
226229
// Start the USB bus.
227230
// This prevent further allocation by consuming the driver.
228-
let (bus, control) = driver.start(config.max_packet_size_0 as u16);
231+
let (bus, control) = driver.start(config.max_packet_size_0 as u16, config.enable_sof_interrupts);
229232
let device_descriptor = descriptor::device_descriptor(&config);
230233
let device_qualifier_descriptor = descriptor::device_qualifier_descriptor(&config);
231234

@@ -495,6 +498,12 @@ impl<'d, D: Driver<'d>> Inner<'d, D> {
495498
h.enabled(false);
496499
}
497500
}
501+
Event::SOF => {
502+
trace!("usb: start of frame");
503+
for h in &mut self.handlers {
504+
h.sof();
505+
}
506+
}
498507
}
499508
}
500509

0 commit comments

Comments
 (0)