diff options
| author | alexmoon <[email protected]> | 2022-03-27 17:12:57 -0400 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-04-06 05:38:11 +0200 |
| commit | 52c622b1cd02ba13accc84cd57e90b04797f0405 (patch) | |
| tree | 67057b66716715a75a2ca60ecf6115720d577961 /embassy-usb/src/lib.rs | |
| parent | bdc6e0481c42d20d5cca19dfc8ec56306e47296e (diff) | |
Use trait objects instead of generics for UsbDevice::classes
Diffstat (limited to 'embassy-usb/src/lib.rs')
| -rw-r--r-- | embassy-usb/src/lib.rs | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 4082868fb..ff3930afa 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs | |||
| @@ -13,6 +13,8 @@ pub mod driver; | |||
| 13 | pub mod types; | 13 | pub mod types; |
| 14 | mod util; | 14 | mod util; |
| 15 | 15 | ||
| 16 | use class::ControlInRequestStatus; | ||
| 17 | |||
| 16 | use self::class::{RequestStatus, UsbClass}; | 18 | use self::class::{RequestStatus, UsbClass}; |
| 17 | use self::control::*; | 19 | use self::control::*; |
| 18 | use self::descriptor::*; | 20 | use self::descriptor::*; |
| @@ -51,7 +53,7 @@ pub const CONFIGURATION_VALUE: u8 = 1; | |||
| 51 | /// The default value for bAlternateSetting for all interfaces. | 53 | /// The default value for bAlternateSetting for all interfaces. |
| 52 | pub const DEFAULT_ALTERNATE_SETTING: u8 = 0; | 54 | pub const DEFAULT_ALTERNATE_SETTING: u8 = 0; |
| 53 | 55 | ||
| 54 | pub struct UsbDevice<'d, D: Driver<'d>, C: UsbClass<'d, D>> { | 56 | pub struct UsbDevice<'d, D: Driver<'d>> { |
| 55 | bus: D::Bus, | 57 | bus: D::Bus, |
| 56 | control: D::ControlPipe, | 58 | control: D::ControlPipe, |
| 57 | 59 | ||
| @@ -65,17 +67,17 @@ pub struct UsbDevice<'d, D: Driver<'d>, C: UsbClass<'d, D>> { | |||
| 65 | self_powered: bool, | 67 | self_powered: bool, |
| 66 | pending_address: u8, | 68 | pending_address: u8, |
| 67 | 69 | ||
| 68 | classes: C, | 70 | classes: &'d mut [&'d mut dyn UsbClass], |
| 69 | } | 71 | } |
| 70 | 72 | ||
| 71 | impl<'d, D: Driver<'d>, C: UsbClass<'d, D>> UsbDevice<'d, D, C> { | 73 | impl<'d, D: Driver<'d>> UsbDevice<'d, D> { |
| 72 | pub(crate) fn build( | 74 | pub(crate) fn build( |
| 73 | mut driver: D, | 75 | mut driver: D, |
| 74 | config: Config<'d>, | 76 | config: Config<'d>, |
| 75 | device_descriptor: &'d [u8], | 77 | device_descriptor: &'d [u8], |
| 76 | config_descriptor: &'d [u8], | 78 | config_descriptor: &'d [u8], |
| 77 | bos_descriptor: &'d [u8], | 79 | bos_descriptor: &'d [u8], |
| 78 | classes: C, | 80 | classes: &'d mut [&'d mut dyn UsbClass], |
| 79 | ) -> Self { | 81 | ) -> Self { |
| 80 | let control = driver | 82 | let control = driver |
| 81 | .alloc_control_pipe(config.max_packet_size_0 as u16) | 83 | .alloc_control_pipe(config.max_packet_size_0 as u16) |
| @@ -113,7 +115,9 @@ impl<'d, D: Driver<'d>, C: UsbClass<'d, D>> UsbDevice<'d, D, C> { | |||
| 113 | self.remote_wakeup_enabled = false; | 115 | self.remote_wakeup_enabled = false; |
| 114 | self.pending_address = 0; | 116 | self.pending_address = 0; |
| 115 | 117 | ||
| 116 | self.classes.reset(); | 118 | for c in self.classes.iter_mut() { |
| 119 | c.reset(); | ||
| 120 | } | ||
| 117 | } | 121 | } |
| 118 | Event::Resume => {} | 122 | Event::Resume => {} |
| 119 | Event::Suspend => { | 123 | Event::Suspend => { |
| @@ -155,10 +159,12 @@ impl<'d, D: Driver<'d>, C: UsbClass<'d, D>> UsbDevice<'d, D, C> { | |||
| 155 | &[] | 159 | &[] |
| 156 | }; | 160 | }; |
| 157 | 161 | ||
| 158 | match self.classes.control_out(req, data).await { | 162 | for c in self.classes.iter_mut() { |
| 159 | RequestStatus::Accepted => return self.control.accept(), | 163 | match c.control_out(req, data) { |
| 160 | RequestStatus::Rejected => return self.control.reject(), | 164 | RequestStatus::Accepted => return self.control.accept(), |
| 161 | RequestStatus::Unhandled => (), | 165 | RequestStatus::Rejected => return self.control.reject(), |
| 166 | RequestStatus::Unhandled => (), | ||
| 167 | } | ||
| 162 | } | 168 | } |
| 163 | } | 169 | } |
| 164 | 170 | ||
| @@ -233,14 +239,22 @@ impl<'d, D: Driver<'d>, C: UsbClass<'d, D>> UsbDevice<'d, D, C> { | |||
| 233 | } | 239 | } |
| 234 | 240 | ||
| 235 | async fn handle_control_in(&mut self, req: Request) { | 241 | async fn handle_control_in(&mut self, req: Request) { |
| 236 | match self | 242 | let mut buf = [0; 128]; |
| 237 | .classes | 243 | for c in self.classes.iter_mut() { |
| 238 | .control_in(req, class::ControlIn::new(&mut self.control)) | 244 | match c.control_in(req, class::ControlIn::new(&mut buf)) { |
| 239 | .await | 245 | ControlInRequestStatus { |
| 240 | .status() | 246 | status: RequestStatus::Accepted, |
| 241 | { | 247 | data, |
| 242 | RequestStatus::Accepted | RequestStatus::Rejected => return, | 248 | } => return self.control.accept_in(data).await, |
| 243 | RequestStatus::Unhandled => (), | 249 | ControlInRequestStatus { |
| 250 | status: RequestStatus::Rejected, | ||
| 251 | .. | ||
| 252 | } => return self.control.reject(), | ||
| 253 | ControlInRequestStatus { | ||
| 254 | status: RequestStatus::Unhandled, | ||
| 255 | .. | ||
| 256 | } => (), | ||
| 257 | } | ||
| 244 | } | 258 | } |
| 245 | 259 | ||
| 246 | match req.request_type { | 260 | match req.request_type { |
