diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-02-07 22:49:14 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-02-08 00:17:08 +0100 |
| commit | 3af991ab63d14cfad6f50d28bfb944d1895d1c70 (patch) | |
| tree | 575fecf6f47fbfd7116070aff2ffd5f4e84c7cf1 /embassy-usb/src/builder.rs | |
| parent | 1d841cc8ac74feacc4d231958ce2c46419ae3bda (diff) | |
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).
Diffstat (limited to 'embassy-usb/src/builder.rs')
| -rw-r--r-- | embassy-usb/src/builder.rs | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index d89fc4017..07b2a177c 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs | |||
| @@ -1,12 +1,12 @@ | |||
| 1 | use heapless::Vec; | 1 | use heapless::Vec; |
| 2 | 2 | ||
| 3 | use crate::control::ControlHandler; | 3 | use crate::config::*; |
| 4 | use crate::descriptor::{BosWriter, DescriptorWriter}; | 4 | use crate::descriptor::{BosWriter, DescriptorWriter}; |
| 5 | use crate::driver::{Driver, Endpoint, EndpointType}; | 5 | use crate::driver::{Driver, Endpoint, EndpointType}; |
| 6 | #[cfg(feature = "msos-descriptor")] | 6 | #[cfg(feature = "msos-descriptor")] |
| 7 | use crate::msos::{DeviceLevelDescriptor, FunctionLevelDescriptor, MsOsDescriptorWriter}; | 7 | use crate::msos::{DeviceLevelDescriptor, FunctionLevelDescriptor, MsOsDescriptorWriter}; |
| 8 | use crate::types::*; | 8 | use crate::types::*; |
| 9 | use crate::{DeviceStateHandler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START}; | 9 | use crate::{Handler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START}; |
| 10 | 10 | ||
| 11 | #[derive(Debug, Copy, Clone)] | 11 | #[derive(Debug, Copy, Clone)] |
| 12 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 12 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| @@ -122,8 +122,8 @@ impl<'a> Config<'a> { | |||
| 122 | /// [`UsbDevice`] builder. | 122 | /// [`UsbDevice`] builder. |
| 123 | pub struct Builder<'d, D: Driver<'d>> { | 123 | pub struct Builder<'d, D: Driver<'d>> { |
| 124 | config: Config<'d>, | 124 | config: Config<'d>, |
| 125 | handler: Option<&'d dyn DeviceStateHandler>, | 125 | handlers: Vec<&'d mut dyn Handler, MAX_HANDLER_COUNT>, |
| 126 | interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>, | 126 | interfaces: Vec<Interface, MAX_INTERFACE_COUNT>, |
| 127 | control_buf: &'d mut [u8], | 127 | control_buf: &'d mut [u8], |
| 128 | 128 | ||
| 129 | driver: D, | 129 | driver: D, |
| @@ -151,7 +151,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { | |||
| 151 | bos_descriptor_buf: &'d mut [u8], | 151 | bos_descriptor_buf: &'d mut [u8], |
| 152 | #[cfg(feature = "msos-descriptor")] msos_descriptor_buf: &'d mut [u8], | 152 | #[cfg(feature = "msos-descriptor")] msos_descriptor_buf: &'d mut [u8], |
| 153 | control_buf: &'d mut [u8], | 153 | control_buf: &'d mut [u8], |
| 154 | handler: Option<&'d dyn DeviceStateHandler>, | ||
| 155 | ) -> Self { | 154 | ) -> Self { |
| 156 | // Magic values specified in USB-IF ECN on IADs. | 155 | // Magic values specified in USB-IF ECN on IADs. |
| 157 | if config.composite_with_iads | 156 | if config.composite_with_iads |
| @@ -179,9 +178,9 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { | |||
| 179 | 178 | ||
| 180 | Builder { | 179 | Builder { |
| 181 | driver, | 180 | driver, |
| 182 | handler, | ||
| 183 | config, | 181 | config, |
| 184 | interfaces: Vec::new(), | 182 | interfaces: Vec::new(), |
| 183 | handlers: Vec::new(), | ||
| 185 | control_buf, | 184 | control_buf, |
| 186 | next_string_index: STRING_INDEX_CUSTOM_START, | 185 | next_string_index: STRING_INDEX_CUSTOM_START, |
| 187 | 186 | ||
| @@ -205,7 +204,7 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { | |||
| 205 | UsbDevice::build( | 204 | UsbDevice::build( |
| 206 | self.driver, | 205 | self.driver, |
| 207 | self.config, | 206 | self.config, |
| 208 | self.handler, | 207 | self.handlers, |
| 209 | self.device_descriptor.into_buf(), | 208 | self.device_descriptor.into_buf(), |
| 210 | self.config_descriptor.into_buf(), | 209 | self.config_descriptor.into_buf(), |
| 211 | self.bos_descriptor.writer.into_buf(), | 210 | self.bos_descriptor.writer.into_buf(), |
| @@ -248,6 +247,26 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { | |||
| 248 | } | 247 | } |
| 249 | } | 248 | } |
| 250 | 249 | ||
| 250 | /// Add a Handler. | ||
| 251 | /// | ||
| 252 | /// The Handler is called on some USB bus events, and to handle all control requests not already | ||
| 253 | /// handled by the USB stack. | ||
| 254 | pub fn handler(&mut self, handler: &'d mut dyn Handler) { | ||
| 255 | if self.handlers.push(handler).is_err() { | ||
| 256 | panic!( | ||
| 257 | "embassy-usb: handler list full. Increase the `max_handler_count` compile-time setting. Current value: {}", | ||
| 258 | MAX_HANDLER_COUNT | ||
| 259 | ) | ||
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 263 | /// Allocates a new string index. | ||
| 264 | pub fn string(&mut self) -> StringIndex { | ||
| 265 | let index = self.next_string_index; | ||
| 266 | self.next_string_index += 1; | ||
| 267 | StringIndex::new(index) | ||
| 268 | } | ||
| 269 | |||
| 251 | #[cfg(feature = "msos-descriptor")] | 270 | #[cfg(feature = "msos-descriptor")] |
| 252 | /// Add an MS OS 2.0 Descriptor Set. | 271 | /// Add an MS OS 2.0 Descriptor Set. |
| 253 | /// | 272 | /// |
| @@ -301,10 +320,8 @@ impl<'a, 'd, D: Driver<'d>> FunctionBuilder<'a, 'd, D> { | |||
| 301 | 320 | ||
| 302 | let number = self.builder.interfaces.len() as _; | 321 | let number = self.builder.interfaces.len() as _; |
| 303 | let iface = Interface { | 322 | let iface = Interface { |
| 304 | handler: None, | ||
| 305 | current_alt_setting: 0, | 323 | current_alt_setting: 0, |
| 306 | num_alt_settings: 0, | 324 | num_alt_settings: 0, |
| 307 | num_strings: 0, | ||
| 308 | }; | 325 | }; |
| 309 | 326 | ||
| 310 | if self.builder.interfaces.push(iface).is_err() { | 327 | if self.builder.interfaces.push(iface).is_err() { |
| @@ -350,17 +367,9 @@ impl<'a, 'd, D: Driver<'d>> InterfaceBuilder<'a, 'd, D> { | |||
| 350 | self.interface_number | 367 | self.interface_number |
| 351 | } | 368 | } |
| 352 | 369 | ||
| 353 | pub fn handler(&mut self, handler: &'d mut dyn ControlHandler) { | ||
| 354 | self.builder.interfaces[self.interface_number.0 as usize].handler = Some(handler); | ||
| 355 | } | ||
| 356 | |||
| 357 | /// Allocates a new string index. | 370 | /// Allocates a new string index. |
| 358 | pub fn string(&mut self) -> StringIndex { | 371 | pub fn string(&mut self) -> StringIndex { |
| 359 | let index = self.builder.next_string_index; | 372 | self.builder.string() |
| 360 | self.builder.next_string_index += 1; | ||
| 361 | self.builder.interfaces[self.interface_number.0 as usize].num_strings += 1; | ||
| 362 | |||
| 363 | StringIndex::new(index) | ||
| 364 | } | 373 | } |
| 365 | 374 | ||
| 366 | /// Add an alternate setting to the interface and write its descriptor. | 375 | /// Add an alternate setting to the interface and write its descriptor. |
