diff options
Diffstat (limited to 'embassy-usb/src/lib.rs')
| -rw-r--r-- | embassy-usb/src/lib.rs | 54 |
1 files changed, 22 insertions, 32 deletions
diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 1180b9b66..88d88cad7 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs | |||
| @@ -24,12 +24,12 @@ use embassy_futures::select::{select, Either}; | |||
| 24 | use heapless::Vec; | 24 | use heapless::Vec; |
| 25 | 25 | ||
| 26 | pub use crate::builder::{Builder, Config, FunctionBuilder, InterfaceAltBuilder, InterfaceBuilder}; | 26 | pub use crate::builder::{Builder, Config, FunctionBuilder, InterfaceAltBuilder, InterfaceBuilder}; |
| 27 | use crate::config::*; | 27 | use crate::config::{MAX_HANDLER_COUNT, MAX_INTERFACE_COUNT}; |
| 28 | use crate::control::*; | 28 | use crate::control::{InResponse, OutResponse, Recipient, Request, RequestType}; |
| 29 | use crate::descriptor::*; | 29 | use crate::descriptor::{descriptor_type, lang_id}; |
| 30 | use crate::descriptor_reader::foreach_endpoint; | 30 | use crate::descriptor_reader::foreach_endpoint; |
| 31 | use crate::driver::{Bus, ControlPipe, Direction, Driver, EndpointAddress, Event}; | 31 | use crate::driver::{Bus, ControlPipe, Direction, Driver, EndpointAddress, Event}; |
| 32 | use crate::types::*; | 32 | use crate::types::{InterfaceNumber, StringIndex}; |
| 33 | 33 | ||
| 34 | /// The global state of the USB device. | 34 | /// The global state of the USB device. |
| 35 | /// | 35 | /// |
| @@ -294,7 +294,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 294 | /// After dropping the future, [`UsbDevice::disable()`] should be called | 294 | /// After dropping the future, [`UsbDevice::disable()`] should be called |
| 295 | /// before calling any other `UsbDevice` methods to fully reset the | 295 | /// before calling any other `UsbDevice` methods to fully reset the |
| 296 | /// peripheral. | 296 | /// peripheral. |
| 297 | pub async fn run_until_suspend(&mut self) -> () { | 297 | pub async fn run_until_suspend(&mut self) { |
| 298 | while !self.inner.suspended { | 298 | while !self.inner.suspended { |
| 299 | let control_fut = self.control.setup(); | 299 | let control_fut = self.control.setup(); |
| 300 | let bus_fut = self.inner.bus.poll(); | 300 | let bus_fut = self.inner.bus.poll(); |
| @@ -364,6 +364,8 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | async fn handle_control_in(&mut self, req: Request) { | 366 | async fn handle_control_in(&mut self, req: Request) { |
| 367 | const DEVICE_DESCRIPTOR_LEN: usize = 18; | ||
| 368 | |||
| 367 | let mut resp_length = req.length as usize; | 369 | let mut resp_length = req.length as usize; |
| 368 | let max_packet_size = self.control.max_packet_size(); | 370 | let max_packet_size = self.control.max_packet_size(); |
| 369 | 371 | ||
| @@ -371,19 +373,15 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 371 | // The host doesn't know our EP0 max packet size yet, and might assume | 373 | // The host doesn't know our EP0 max packet size yet, and might assume |
| 372 | // a full-length packet is a short packet, thinking we're done sending data. | 374 | // a full-length packet is a short packet, thinking we're done sending data. |
| 373 | // See https://github.com/hathach/tinyusb/issues/184 | 375 | // See https://github.com/hathach/tinyusb/issues/184 |
| 374 | const DEVICE_DESCRIPTOR_LEN: usize = 18; | 376 | if self.inner.address == 0 && max_packet_size < DEVICE_DESCRIPTOR_LEN && max_packet_size < resp_length { |
| 375 | if self.inner.address == 0 | ||
| 376 | && max_packet_size < DEVICE_DESCRIPTOR_LEN | ||
| 377 | && (max_packet_size as usize) < resp_length | ||
| 378 | { | ||
| 379 | trace!("received control req while not addressed: capping response to 1 packet."); | 377 | trace!("received control req while not addressed: capping response to 1 packet."); |
| 380 | resp_length = max_packet_size; | 378 | resp_length = max_packet_size; |
| 381 | } | 379 | } |
| 382 | 380 | ||
| 383 | match self.inner.handle_control_in(req, &mut self.control_buf) { | 381 | match self.inner.handle_control_in(req, self.control_buf) { |
| 384 | InResponse::Accepted(data) => { | 382 | InResponse::Accepted(data) => { |
| 385 | let len = data.len().min(resp_length); | 383 | let len = data.len().min(resp_length); |
| 386 | let need_zlp = len != resp_length && (len % usize::from(max_packet_size)) == 0; | 384 | let need_zlp = len != resp_length && (len % max_packet_size) == 0; |
| 387 | 385 | ||
| 388 | let chunks = data[0..len] | 386 | let chunks = data[0..len] |
| 389 | .chunks(max_packet_size) | 387 | .chunks(max_packet_size) |
| @@ -435,7 +433,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 435 | self.control.accept_set_address(self.inner.address).await; | 433 | self.control.accept_set_address(self.inner.address).await; |
| 436 | self.inner.set_address_pending = false; | 434 | self.inner.set_address_pending = false; |
| 437 | } else { | 435 | } else { |
| 438 | self.control.accept().await | 436 | self.control.accept().await; |
| 439 | } | 437 | } |
| 440 | } | 438 | } |
| 441 | OutResponse::Rejected => self.control.reject().await, | 439 | OutResponse::Rejected => self.control.reject().await, |
| @@ -548,9 +546,8 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { | |||
| 548 | 546 | ||
| 549 | OutResponse::Accepted | 547 | OutResponse::Accepted |
| 550 | } | 548 | } |
| 551 | (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => match self.device_state { | 549 | (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => { |
| 552 | UsbDeviceState::Default => OutResponse::Accepted, | 550 | if self.device_state != UsbDeviceState::Default { |
| 553 | _ => { | ||
| 554 | debug!("SET_CONFIGURATION: unconfigured"); | 551 | debug!("SET_CONFIGURATION: unconfigured"); |
| 555 | self.device_state = UsbDeviceState::Addressed; | 552 | self.device_state = UsbDeviceState::Addressed; |
| 556 | 553 | ||
| @@ -564,17 +561,15 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { | |||
| 564 | for h in &mut self.handlers { | 561 | for h in &mut self.handlers { |
| 565 | h.configured(false); | 562 | h.configured(false); |
| 566 | } | 563 | } |
| 567 | |||
| 568 | OutResponse::Accepted | ||
| 569 | } | 564 | } |
| 570 | }, | 565 | OutResponse::Accepted |
| 566 | } | ||
| 571 | _ => OutResponse::Rejected, | 567 | _ => OutResponse::Rejected, |
| 572 | }, | 568 | }, |
| 573 | (RequestType::Standard, Recipient::Interface) => { | 569 | (RequestType::Standard, Recipient::Interface) => { |
| 574 | let iface_num = InterfaceNumber::new(req.index as _); | 570 | let iface_num = InterfaceNumber::new(req.index as _); |
| 575 | let iface = match self.interfaces.get_mut(iface_num.0 as usize) { | 571 | let Some(iface) = self.interfaces.get_mut(iface_num.0 as usize) else { |
| 576 | Some(iface) => iface, | 572 | return OutResponse::Rejected; |
| 577 | None => return OutResponse::Rejected, | ||
| 578 | }; | 573 | }; |
| 579 | 574 | ||
| 580 | match req.request { | 575 | match req.request { |
| @@ -650,9 +645,8 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { | |||
| 650 | _ => InResponse::Rejected, | 645 | _ => InResponse::Rejected, |
| 651 | }, | 646 | }, |
| 652 | (RequestType::Standard, Recipient::Interface) => { | 647 | (RequestType::Standard, Recipient::Interface) => { |
| 653 | let iface = match self.interfaces.get_mut(req.index as usize) { | 648 | let Some(iface) = self.interfaces.get_mut(req.index as usize) else { |
| 654 | Some(iface) => iface, | 649 | return InResponse::Rejected; |
| 655 | None => return InResponse::Rejected, | ||
| 656 | }; | 650 | }; |
| 657 | 651 | ||
| 658 | match req.request { | 652 | match req.request { |
| @@ -706,7 +700,7 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { | |||
| 706 | } | 700 | } |
| 707 | 701 | ||
| 708 | fn handle_control_in_delegated<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> InResponse<'a> { | 702 | fn handle_control_in_delegated<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> InResponse<'a> { |
| 709 | unsafe fn extend_lifetime<'x, 'y>(r: InResponse<'x>) -> InResponse<'y> { | 703 | unsafe fn extend_lifetime<'y>(r: InResponse<'_>) -> InResponse<'y> { |
| 710 | core::mem::transmute(r) | 704 | core::mem::transmute(r) |
| 711 | } | 705 | } |
| 712 | 706 | ||
| @@ -756,16 +750,12 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { | |||
| 756 | }; | 750 | }; |
| 757 | 751 | ||
| 758 | if let Some(s) = s { | 752 | if let Some(s) = s { |
| 759 | if buf.len() < 2 { | 753 | assert!(buf.len() >= 2, "control buffer too small"); |
| 760 | panic!("control buffer too small"); | ||
| 761 | } | ||
| 762 | 754 | ||
| 763 | buf[1] = descriptor_type::STRING; | 755 | buf[1] = descriptor_type::STRING; |
| 764 | let mut pos = 2; | 756 | let mut pos = 2; |
| 765 | for c in s.encode_utf16() { | 757 | for c in s.encode_utf16() { |
| 766 | if pos + 2 >= buf.len() { | 758 | assert!(pos + 2 < buf.len(), "control buffer too small"); |
| 767 | panic!("control buffer too small"); | ||
| 768 | } | ||
| 769 | 759 | ||
| 770 | buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes()); | 760 | buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes()); |
| 771 | pos += 2; | 761 | pos += 2; |
