From d9b00c01e09deea8d1255a89ce40174960aad793 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 6 Nov 2023 03:26:00 +0100 Subject: [PATCH 1/4] usb: reject instead of panic on CONTROL OUT longer than the buf. --- embassy-usb/src/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 88d88cad..9fc1e332 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -406,6 +406,16 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { let max_packet_size = self.control.max_packet_size(); let mut total = 0; + if req_length > self.control_buf.len() { + warn!( + "got CONTROL OUT with length {} higher than the control_buf len {}, rejecting.", + req_length, + self.control_buf.len() + ); + self.control.reject().await; + return; + } + let chunks = self.control_buf[..req_length].chunks_mut(max_packet_size); for (first, last, chunk) in first_last(chunks) { let size = match self.control.data_out(chunk, first, last).await { From b8679c0cc85e5eb65bd996ee18deac4a952b1b10 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 6 Nov 2023 03:37:39 +0100 Subject: [PATCH 2/4] stm32/rcc: set highest VOS on some F4s with no overdrive. --- embassy-stm32/src/rcc/f4f7.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f4f7.rs index 2e4f9572..d507a6fd 100644 --- a/embassy-stm32/src/rcc/f4f7.rs +++ b/embassy-stm32/src/rcc/f4f7.rs @@ -113,6 +113,14 @@ pub(crate) unsafe fn init(config: Config) { while !PWR.csr1().read().odswrdy() {} } + #[cfg(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423))] + { + use crate::pac::pwr::vals::Vos; + use crate::pac::PWR; + + PWR.cr1().modify(|w| w.set_vos(Vos::SCALE1)); + } + // Configure HSI let hsi = match config.hsi { false => { From 70a700e430b5258b77c678ba66dfb33977f3e7a8 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 6 Nov 2023 03:38:13 +0100 Subject: [PATCH 3/4] stm32/otg: log TRDT --- embassy-stm32/src/usb_otg/usb.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs index e45e4ac4..26a14ff0 100644 --- a/embassy-stm32/src/usb_otg/usb.rs +++ b/embassy-stm32/src/usb_otg/usb.rs @@ -911,11 +911,9 @@ impl<'d, T: Instance> embassy_usb_driver::Bus for Bus<'d, T> { trace!("enumdne"); let speed = r.dsts().read().enumspd(); - trace!(" speed={}", speed.to_bits()); - - r.gusbcfg().modify(|w| { - w.set_trdt(calculate_trdt(speed, T::frequency())); - }); + let trdt = calculate_trdt(speed, T::frequency()); + trace!(" speed={} trdt={}", speed.to_bits(), trdt); + r.gusbcfg().modify(|w| w.set_trdt(trdt)); r.gintsts().write(|w| w.set_enumdne(true)); // clear Self::restore_irqs(); From b4eef6b1ee5d1b92263ada437692fb7c9c3fe569 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 6 Nov 2023 03:38:42 +0100 Subject: [PATCH 4/4] stm32/otg: fix CONTROL OUT transfers on F4. --- embassy-stm32/src/usb_otg/usb.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs index 26a14ff0..d90f8343 100644 --- a/embassy-stm32/src/usb_otg/usb.rs +++ b/embassy-stm32/src/usb_otg/usb.rs @@ -40,6 +40,7 @@ impl interrupt::typelevel::Handler for InterruptHandl // Handle RX while r.gintsts().read().rxflvl() { let status = r.grxstsp().read(); + trace!("=== status {:08x}", status.0); let ep_num = status.epnum() as usize; let len = status.bcnt() as usize; @@ -51,6 +52,15 @@ impl interrupt::typelevel::Handler for InterruptHandl assert!(len == 8, "invalid SETUP packet length={}", len); assert!(ep_num == 0, "invalid SETUP packet endpoint={}", ep_num); + // flushing TX if something stuck in control endpoint + if r.dieptsiz(ep_num).read().pktcnt() != 0 { + r.grstctl().modify(|w| { + w.set_txfnum(ep_num as _); + w.set_txfflsh(true); + }); + while r.grstctl().read().txfflsh() {} + } + if state.ep0_setup_ready.load(Ordering::Relaxed) == false { // SAFETY: exclusive access ensured by atomic bool let data = unsafe { &mut *state.ep0_setup_data.get() }; @@ -96,6 +106,11 @@ impl interrupt::typelevel::Handler for InterruptHandl } vals::Pktstsd::SETUP_DATA_DONE => { trace!("SETUP_DATA_DONE ep={}", ep_num); + + // Clear NAK to indicate we are ready to receive more data + T::regs().doepctl(ep_num).modify(|w| { + w.set_cnak(true); + }); } x => trace!("unknown PKTSTS: {}", x.to_bits()), } @@ -1312,11 +1327,6 @@ impl<'d, T: Instance> embassy_usb_driver::ControlPipe for ControlPipe<'d, T> { w.set_rxdpid_stupcnt(1); }); - // Clear NAK to indicate we are ready to receive more data - T::regs().doepctl(self.ep_out.info.addr.index()).modify(|w| { - w.set_cnak(true); - }); - trace!("SETUP received: {:?}", data); Poll::Ready(data) } else {