diff options
| author | alexmoon <[email protected]> | 2022-04-10 15:41:51 -0400 |
|---|---|---|
| committer | alexmoon <[email protected]> | 2022-04-13 14:55:02 -0400 |
| commit | f5656e354485888cc7c2697052ae2c79b94a59ad (patch) | |
| tree | 8580410dbaca2c3f0db6e431f77f248dd6bd5dc9 /embassy-usb/src/builder.rs | |
| parent | 2217de24c02e9f7e0aafeb8315ab6be8b644c52f (diff) | |
Add DeviceStateHandler, DeviceCommand channel, and remote wakeup support
Diffstat (limited to 'embassy-usb/src/builder.rs')
| -rw-r--r-- | embassy-usb/src/builder.rs | 77 |
1 files changed, 73 insertions, 4 deletions
diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index 4bbcd3e56..30d31ac74 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs | |||
| @@ -1,9 +1,14 @@ | |||
| 1 | use embassy::blocking_mutex::raw::{NoopRawMutex, RawMutex}; | ||
| 2 | use embassy::channel::Channel; | ||
| 1 | use heapless::Vec; | 3 | use heapless::Vec; |
| 2 | 4 | ||
| 5 | use crate::DeviceCommand; | ||
| 6 | |||
| 3 | use super::control::ControlHandler; | 7 | use super::control::ControlHandler; |
| 4 | use super::descriptor::{BosWriter, DescriptorWriter}; | 8 | use super::descriptor::{BosWriter, DescriptorWriter}; |
| 5 | use super::driver::{Driver, EndpointAllocError}; | 9 | use super::driver::{Driver, EndpointAllocError}; |
| 6 | use super::types::*; | 10 | use super::types::*; |
| 11 | use super::DeviceStateHandler; | ||
| 7 | use super::UsbDevice; | 12 | use super::UsbDevice; |
| 8 | use super::MAX_INTERFACE_COUNT; | 13 | use super::MAX_INTERFACE_COUNT; |
| 9 | 14 | ||
| @@ -93,6 +98,11 @@ pub struct Config<'a> { | |||
| 93 | /// Default: 100mA | 98 | /// Default: 100mA |
| 94 | /// Max: 500mA | 99 | /// Max: 500mA |
| 95 | pub max_power: u16, | 100 | pub max_power: u16, |
| 101 | |||
| 102 | /// Whether the USB bus should be enabled when built. | ||
| 103 | /// | ||
| 104 | /// Default: true | ||
| 105 | pub start_enabled: bool, | ||
| 96 | } | 106 | } |
| 97 | 107 | ||
| 98 | impl<'a> Config<'a> { | 108 | impl<'a> Config<'a> { |
| @@ -112,15 +122,18 @@ impl<'a> Config<'a> { | |||
| 112 | supports_remote_wakeup: false, | 122 | supports_remote_wakeup: false, |
| 113 | composite_with_iads: false, | 123 | composite_with_iads: false, |
| 114 | max_power: 100, | 124 | max_power: 100, |
| 125 | start_enabled: true, | ||
| 115 | } | 126 | } |
| 116 | } | 127 | } |
| 117 | } | 128 | } |
| 118 | 129 | ||
| 119 | /// Used to build new [`UsbDevice`]s. | 130 | /// Used to build new [`UsbDevice`]s. |
| 120 | pub struct UsbDeviceBuilder<'d, D: Driver<'d>> { | 131 | pub struct UsbDeviceBuilder<'d, D: Driver<'d>, M: RawMutex> { |
| 121 | config: Config<'d>, | 132 | config: Config<'d>, |
| 133 | handler: Option<&'d dyn DeviceStateHandler>, | ||
| 122 | interfaces: Vec<(u8, &'d mut dyn ControlHandler), MAX_INTERFACE_COUNT>, | 134 | interfaces: Vec<(u8, &'d mut dyn ControlHandler), MAX_INTERFACE_COUNT>, |
| 123 | control_buf: &'d mut [u8], | 135 | control_buf: &'d mut [u8], |
| 136 | commands: Option<&'d Channel<M, DeviceCommand, 1>>, | ||
| 124 | 137 | ||
| 125 | driver: D, | 138 | driver: D, |
| 126 | next_interface_number: u8, | 139 | next_interface_number: u8, |
| @@ -132,7 +145,7 @@ pub struct UsbDeviceBuilder<'d, D: Driver<'d>> { | |||
| 132 | pub bos_descriptor: BosWriter<'d>, | 145 | pub bos_descriptor: BosWriter<'d>, |
| 133 | } | 146 | } |
| 134 | 147 | ||
| 135 | impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D> { | 148 | impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D, NoopRawMutex> { |
| 136 | /// Creates a builder for constructing a new [`UsbDevice`]. | 149 | /// Creates a builder for constructing a new [`UsbDevice`]. |
| 137 | /// | 150 | /// |
| 138 | /// `control_buf` is a buffer used for USB control request data. It should be sized | 151 | /// `control_buf` is a buffer used for USB control request data. It should be sized |
| @@ -145,6 +158,58 @@ impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D> { | |||
| 145 | config_descriptor_buf: &'d mut [u8], | 158 | config_descriptor_buf: &'d mut [u8], |
| 146 | bos_descriptor_buf: &'d mut [u8], | 159 | bos_descriptor_buf: &'d mut [u8], |
| 147 | control_buf: &'d mut [u8], | 160 | control_buf: &'d mut [u8], |
| 161 | handler: Option<&'d dyn DeviceStateHandler>, | ||
| 162 | ) -> Self { | ||
| 163 | Self::new_inner( | ||
| 164 | driver, | ||
| 165 | config, | ||
| 166 | device_descriptor_buf, | ||
| 167 | config_descriptor_buf, | ||
| 168 | bos_descriptor_buf, | ||
| 169 | control_buf, | ||
| 170 | handler, | ||
| 171 | None, | ||
| 172 | ) | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | impl<'d, D: Driver<'d>, M: RawMutex> UsbDeviceBuilder<'d, D, M> { | ||
| 177 | /// Creates a builder for constructing a new [`UsbDevice`]. | ||
| 178 | /// | ||
| 179 | /// `control_buf` is a buffer used for USB control request data. It should be sized | ||
| 180 | /// large enough for the length of the largest control request (in or out) | ||
| 181 | /// anticipated by any class added to the device. | ||
| 182 | pub fn new_with_channel( | ||
| 183 | driver: D, | ||
| 184 | config: Config<'d>, | ||
| 185 | device_descriptor_buf: &'d mut [u8], | ||
| 186 | config_descriptor_buf: &'d mut [u8], | ||
| 187 | bos_descriptor_buf: &'d mut [u8], | ||
| 188 | control_buf: &'d mut [u8], | ||
| 189 | handler: Option<&'d dyn DeviceStateHandler>, | ||
| 190 | channel: &'d Channel<M, DeviceCommand, 1>, | ||
| 191 | ) -> Self { | ||
| 192 | Self::new_inner( | ||
| 193 | driver, | ||
| 194 | config, | ||
| 195 | device_descriptor_buf, | ||
| 196 | config_descriptor_buf, | ||
| 197 | bos_descriptor_buf, | ||
| 198 | control_buf, | ||
| 199 | handler, | ||
| 200 | Some(channel), | ||
| 201 | ) | ||
| 202 | } | ||
| 203 | |||
| 204 | fn new_inner( | ||
| 205 | driver: D, | ||
| 206 | config: Config<'d>, | ||
| 207 | device_descriptor_buf: &'d mut [u8], | ||
| 208 | config_descriptor_buf: &'d mut [u8], | ||
| 209 | bos_descriptor_buf: &'d mut [u8], | ||
| 210 | control_buf: &'d mut [u8], | ||
| 211 | handler: Option<&'d dyn DeviceStateHandler>, | ||
| 212 | channel: Option<&'d Channel<M, DeviceCommand, 1>>, | ||
| 148 | ) -> Self { | 213 | ) -> Self { |
| 149 | // Magic values specified in USB-IF ECN on IADs. | 214 | // Magic values specified in USB-IF ECN on IADs. |
| 150 | if config.composite_with_iads | 215 | if config.composite_with_iads |
| @@ -174,9 +239,12 @@ impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D> { | |||
| 174 | 239 | ||
| 175 | UsbDeviceBuilder { | 240 | UsbDeviceBuilder { |
| 176 | driver, | 241 | driver, |
| 242 | handler, | ||
| 177 | config, | 243 | config, |
| 178 | interfaces: Vec::new(), | 244 | interfaces: Vec::new(), |
| 179 | control_buf, | 245 | control_buf, |
| 246 | commands: channel, | ||
| 247 | |||
| 180 | next_interface_number: 0, | 248 | next_interface_number: 0, |
| 181 | next_string_index: 4, | 249 | next_string_index: 4, |
| 182 | 250 | ||
| @@ -187,20 +255,21 @@ impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D> { | |||
| 187 | } | 255 | } |
| 188 | 256 | ||
| 189 | /// Creates the [`UsbDevice`] instance with the configuration in this builder. | 257 | /// Creates the [`UsbDevice`] instance with the configuration in this builder. |
| 190 | pub async fn build(mut self) -> UsbDevice<'d, D> { | 258 | pub fn build(mut self) -> UsbDevice<'d, D, M> { |
| 191 | self.config_descriptor.end_configuration(); | 259 | self.config_descriptor.end_configuration(); |
| 192 | self.bos_descriptor.end_bos(); | 260 | self.bos_descriptor.end_bos(); |
| 193 | 261 | ||
| 194 | UsbDevice::build( | 262 | UsbDevice::build( |
| 195 | self.driver, | 263 | self.driver, |
| 196 | self.config, | 264 | self.config, |
| 265 | self.handler, | ||
| 266 | self.commands, | ||
| 197 | self.device_descriptor.into_buf(), | 267 | self.device_descriptor.into_buf(), |
| 198 | self.config_descriptor.into_buf(), | 268 | self.config_descriptor.into_buf(), |
| 199 | self.bos_descriptor.writer.into_buf(), | 269 | self.bos_descriptor.writer.into_buf(), |
| 200 | self.interfaces, | 270 | self.interfaces, |
| 201 | self.control_buf, | 271 | self.control_buf, |
| 202 | ) | 272 | ) |
| 203 | .await | ||
| 204 | } | 273 | } |
| 205 | 274 | ||
| 206 | /// Allocates a new interface number. | 275 | /// Allocates a new interface number. |
