aboutsummaryrefslogtreecommitdiff
path: root/embassy-usb/src/lib.rs
diff options
context:
space:
mode:
authoralexmoon <[email protected]>2022-03-27 17:12:57 -0400
committerDario Nieuwenhuis <[email protected]>2022-04-06 05:38:11 +0200
commit52c622b1cd02ba13accc84cd57e90b04797f0405 (patch)
tree67057b66716715a75a2ca60ecf6115720d577961 /embassy-usb/src/lib.rs
parentbdc6e0481c42d20d5cca19dfc8ec56306e47296e (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.rs48
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;
13pub mod types; 13pub mod types;
14mod util; 14mod util;
15 15
16use class::ControlInRequestStatus;
17
16use self::class::{RequestStatus, UsbClass}; 18use self::class::{RequestStatus, UsbClass};
17use self::control::*; 19use self::control::*;
18use self::descriptor::*; 20use 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.
52pub const DEFAULT_ALTERNATE_SETTING: u8 = 0; 54pub const DEFAULT_ALTERNATE_SETTING: u8 = 0;
53 55
54pub struct UsbDevice<'d, D: Driver<'d>, C: UsbClass<'d, D>> { 56pub 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
71impl<'d, D: Driver<'d>, C: UsbClass<'d, D>> UsbDevice<'d, D, C> { 73impl<'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 {