usb: unify ControlHandler+DeviceStateHandler, route all control requests to all handlers.
- Allows classes to handle vendor requests. - Allows classes to use a single handler for multiple interfaces. - Allows classes to access the other events (previously only `reset` was available).
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
use heapless::Vec;
|
||||
|
||||
use crate::control::ControlHandler;
|
||||
use crate::config::*;
|
||||
use crate::descriptor::{BosWriter, DescriptorWriter};
|
||||
use crate::driver::{Driver, Endpoint, EndpointType};
|
||||
#[cfg(feature = "msos-descriptor")]
|
||||
use crate::msos::{DeviceLevelDescriptor, FunctionLevelDescriptor, MsOsDescriptorWriter};
|
||||
use crate::types::*;
|
||||
use crate::{DeviceStateHandler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START};
|
||||
use crate::{Handler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START};
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
@@ -122,8 +122,8 @@ impl<'a> Config<'a> {
|
||||
/// [`UsbDevice`] builder.
|
||||
pub struct Builder<'d, D: Driver<'d>> {
|
||||
config: Config<'d>,
|
||||
handler: Option<&'d dyn DeviceStateHandler>,
|
||||
interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>,
|
||||
handlers: Vec<&'d mut dyn Handler, MAX_HANDLER_COUNT>,
|
||||
interfaces: Vec<Interface, MAX_INTERFACE_COUNT>,
|
||||
control_buf: &'d mut [u8],
|
||||
|
||||
driver: D,
|
||||
@@ -151,7 +151,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> {
|
||||
bos_descriptor_buf: &'d mut [u8],
|
||||
#[cfg(feature = "msos-descriptor")] msos_descriptor_buf: &'d mut [u8],
|
||||
control_buf: &'d mut [u8],
|
||||
handler: Option<&'d dyn DeviceStateHandler>,
|
||||
) -> Self {
|
||||
// Magic values specified in USB-IF ECN on IADs.
|
||||
if config.composite_with_iads
|
||||
@@ -179,9 +178,9 @@ impl<'d, D: Driver<'d>> Builder<'d, D> {
|
||||
|
||||
Builder {
|
||||
driver,
|
||||
handler,
|
||||
config,
|
||||
interfaces: Vec::new(),
|
||||
handlers: Vec::new(),
|
||||
control_buf,
|
||||
next_string_index: STRING_INDEX_CUSTOM_START,
|
||||
|
||||
@@ -205,7 +204,7 @@ impl<'d, D: Driver<'d>> Builder<'d, D> {
|
||||
UsbDevice::build(
|
||||
self.driver,
|
||||
self.config,
|
||||
self.handler,
|
||||
self.handlers,
|
||||
self.device_descriptor.into_buf(),
|
||||
self.config_descriptor.into_buf(),
|
||||
self.bos_descriptor.writer.into_buf(),
|
||||
@@ -248,6 +247,26 @@ impl<'d, D: Driver<'d>> Builder<'d, D> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a Handler.
|
||||
///
|
||||
/// The Handler is called on some USB bus events, and to handle all control requests not already
|
||||
/// handled by the USB stack.
|
||||
pub fn handler(&mut self, handler: &'d mut dyn Handler) {
|
||||
if self.handlers.push(handler).is_err() {
|
||||
panic!(
|
||||
"embassy-usb: handler list full. Increase the `max_handler_count` compile-time setting. Current value: {}",
|
||||
MAX_HANDLER_COUNT
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Allocates a new string index.
|
||||
pub fn string(&mut self) -> StringIndex {
|
||||
let index = self.next_string_index;
|
||||
self.next_string_index += 1;
|
||||
StringIndex::new(index)
|
||||
}
|
||||
|
||||
#[cfg(feature = "msos-descriptor")]
|
||||
/// Add an MS OS 2.0 Descriptor Set.
|
||||
///
|
||||
@@ -301,10 +320,8 @@ impl<'a, 'd, D: Driver<'d>> FunctionBuilder<'a, 'd, D> {
|
||||
|
||||
let number = self.builder.interfaces.len() as _;
|
||||
let iface = Interface {
|
||||
handler: None,
|
||||
current_alt_setting: 0,
|
||||
num_alt_settings: 0,
|
||||
num_strings: 0,
|
||||
};
|
||||
|
||||
if self.builder.interfaces.push(iface).is_err() {
|
||||
@@ -350,17 +367,9 @@ impl<'a, 'd, D: Driver<'d>> InterfaceBuilder<'a, 'd, D> {
|
||||
self.interface_number
|
||||
}
|
||||
|
||||
pub fn handler(&mut self, handler: &'d mut dyn ControlHandler) {
|
||||
self.builder.interfaces[self.interface_number.0 as usize].handler = Some(handler);
|
||||
}
|
||||
|
||||
/// Allocates a new string index.
|
||||
pub fn string(&mut self) -> StringIndex {
|
||||
let index = self.builder.next_string_index;
|
||||
self.builder.next_string_index += 1;
|
||||
self.builder.interfaces[self.interface_number.0 as usize].num_strings += 1;
|
||||
|
||||
StringIndex::new(index)
|
||||
self.builder.string()
|
||||
}
|
||||
|
||||
/// Add an alternate setting to the interface and write its descriptor.
|
||||
|
Reference in New Issue
Block a user