aboutsummaryrefslogtreecommitdiff
path: root/embassy-usb/src/control.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-05-09 03:25:21 +0200
committerDario Nieuwenhuis <[email protected]>2022-05-09 03:43:24 +0200
commit02ae1138e1b67a18a0fea4f1871751ee1ad858c0 (patch)
tree4bd3c382e664a6eb3ecc9a7029b3ebeafcf8ad4a /embassy-usb/src/control.rs
parent7ed462a6575cba95e8f07d2d9516d5e7b33d7196 (diff)
usb: merge Control logic into main code.
Now that control stuff is called from just one place, there's no need to keep it as a separate struct.
Diffstat (limited to 'embassy-usb/src/control.rs')
-rw-r--r--embassy-usb/src/control.rs123
1 files changed, 0 insertions, 123 deletions
diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs
index 4fc65b6a5..12e5303c3 100644
--- a/embassy-usb/src/control.rs
+++ b/embassy-usb/src/control.rs
@@ -1,7 +1,6 @@
1use core::mem; 1use core::mem;
2 2
3use super::types::*; 3use super::types::*;
4use crate::driver::{self, EndpointError};
5 4
6/// Control request type. 5/// Control request type.
7#[repr(u8)] 6#[repr(u8)]
@@ -194,125 +193,3 @@ pub trait ControlHandler {
194 None 193 None
195 } 194 }
196} 195}
197
198/// Typestate representing a ControlPipe in the DATA IN stage
199#[derive(Debug)]
200#[cfg_attr(feature = "defmt", derive(defmt::Format))]
201pub(crate) struct DataInStage {
202 pub(crate) length: usize,
203}
204
205/// Typestate representing a ControlPipe in the DATA OUT stage
206#[derive(Debug)]
207#[cfg_attr(feature = "defmt", derive(defmt::Format))]
208pub(crate) struct DataOutStage {
209 length: usize,
210}
211
212/// Typestate representing a ControlPipe in the STATUS stage
213#[derive(Debug)]
214#[cfg_attr(feature = "defmt", derive(defmt::Format))]
215pub(crate) struct StatusStage {}
216
217#[derive(Debug)]
218#[cfg_attr(feature = "defmt", derive(defmt::Format))]
219pub(crate) enum Setup {
220 DataIn(Request, DataInStage),
221 DataOut(Request, DataOutStage),
222}
223
224pub(crate) struct ControlPipe<C: driver::ControlPipe> {
225 control: C,
226}
227
228impl<C: driver::ControlPipe> ControlPipe<C> {
229 pub(crate) fn new(control: C) -> Self {
230 ControlPipe { control }
231 }
232
233 pub(crate) async fn setup(&mut self) -> Setup {
234 let req = self.control.setup().await;
235 trace!("control request: {:02x}", req);
236
237 match (req.direction, req.length) {
238 (UsbDirection::Out, n) => Setup::DataOut(
239 req,
240 DataOutStage {
241 length: usize::from(n),
242 },
243 ),
244 (UsbDirection::In, n) => Setup::DataIn(
245 req,
246 DataInStage {
247 length: usize::from(n),
248 },
249 ),
250 }
251 }
252
253 pub(crate) async fn data_out<'a>(
254 &mut self,
255 buf: &'a mut [u8],
256 stage: DataOutStage,
257 ) -> Result<(&'a [u8], StatusStage), EndpointError> {
258 if stage.length == 0 {
259 Ok((&[], StatusStage {}))
260 } else {
261 let req_length = stage.length;
262 let max_packet_size = self.control.max_packet_size();
263 let mut total = 0;
264
265 for chunk in buf.chunks_mut(max_packet_size) {
266 let size = self.control.data_out(chunk).await?;
267 total += size;
268 if size < max_packet_size || total == req_length {
269 break;
270 }
271 }
272
273 let res = &buf[0..total];
274 #[cfg(feature = "defmt")]
275 trace!(" control out data: {:02x}", res);
276 #[cfg(not(feature = "defmt"))]
277 trace!(" control out data: {:02x?}", res);
278
279 Ok((res, StatusStage {}))
280 }
281 }
282
283 pub(crate) async fn accept_in(&mut self, buf: &[u8], stage: DataInStage) {
284 #[cfg(feature = "defmt")]
285 trace!(" control in accept {:02x}", buf);
286 #[cfg(not(feature = "defmt"))]
287 trace!(" control in accept {:02x?}", buf);
288
289 let req_len = stage.length;
290 let len = buf.len().min(req_len);
291 let max_packet_size = self.control.max_packet_size();
292 let need_zlp = len != req_len && (len % usize::from(max_packet_size)) == 0;
293
294 let mut chunks = buf[0..len]
295 .chunks(max_packet_size)
296 .chain(need_zlp.then(|| -> &[u8] { &[] }));
297
298 while let Some(chunk) = chunks.next() {
299 match self.control.data_in(chunk, chunks.size_hint().0 == 0).await {
300 Ok(()) => {}
301 Err(e) => {
302 warn!("control accept_in failed: {:?}", e);
303 return;
304 }
305 }
306 }
307 }
308
309 pub(crate) fn accept(&mut self, _: StatusStage) {
310 trace!(" control accept");
311 self.control.accept();
312 }
313
314 pub(crate) fn reject(&mut self) {
315 trace!(" control reject");
316 self.control.reject();
317 }
318}