aboutsummaryrefslogtreecommitdiff
path: root/embassy-usb/src/builder.rs
diff options
context:
space:
mode:
authoralexmoon <[email protected]>2022-04-10 15:41:51 -0400
committeralexmoon <[email protected]>2022-04-13 14:55:02 -0400
commitf5656e354485888cc7c2697052ae2c79b94a59ad (patch)
tree8580410dbaca2c3f0db6e431f77f248dd6bd5dc9 /embassy-usb/src/builder.rs
parent2217de24c02e9f7e0aafeb8315ab6be8b644c52f (diff)
Add DeviceStateHandler, DeviceCommand channel, and remote wakeup support
Diffstat (limited to 'embassy-usb/src/builder.rs')
-rw-r--r--embassy-usb/src/builder.rs77
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 @@
1use embassy::blocking_mutex::raw::{NoopRawMutex, RawMutex};
2use embassy::channel::Channel;
1use heapless::Vec; 3use heapless::Vec;
2 4
5use crate::DeviceCommand;
6
3use super::control::ControlHandler; 7use super::control::ControlHandler;
4use super::descriptor::{BosWriter, DescriptorWriter}; 8use super::descriptor::{BosWriter, DescriptorWriter};
5use super::driver::{Driver, EndpointAllocError}; 9use super::driver::{Driver, EndpointAllocError};
6use super::types::*; 10use super::types::*;
11use super::DeviceStateHandler;
7use super::UsbDevice; 12use super::UsbDevice;
8use super::MAX_INTERFACE_COUNT; 13use 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
98impl<'a> Config<'a> { 108impl<'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.
120pub struct UsbDeviceBuilder<'d, D: Driver<'d>> { 131pub 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
135impl<'d, D: Driver<'d>> UsbDeviceBuilder<'d, D> { 148impl<'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
176impl<'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.