aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/usb_otg/usb.rs21
1 files changed, 16 insertions, 5 deletions
diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs
index d90f83433..ba77bfb16 100644
--- a/embassy-stm32/src/usb_otg/usb.rs
+++ b/embassy-stm32/src/usb_otg/usb.rs
@@ -107,10 +107,10 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
107 vals::Pktstsd::SETUP_DATA_DONE => { 107 vals::Pktstsd::SETUP_DATA_DONE => {
108 trace!("SETUP_DATA_DONE ep={}", ep_num); 108 trace!("SETUP_DATA_DONE ep={}", ep_num);
109 109
110 // Clear NAK to indicate we are ready to receive more data 110 if quirk_setup_late_cnak(r) {
111 T::regs().doepctl(ep_num).modify(|w| { 111 // Clear NAK to indicate we are ready to receive more data
112 w.set_cnak(true); 112 r.doepctl(ep_num).modify(|w| w.set_cnak(true));
113 }); 113 }
114 } 114 }
115 x => trace!("unknown PKTSTS: {}", x.to_bits()), 115 x => trace!("unknown PKTSTS: {}", x.to_bits()),
116 } 116 }
@@ -1317,16 +1317,23 @@ impl<'d, T: Instance> embassy_usb_driver::ControlPipe for ControlPipe<'d, T> {
1317 1317
1318 state.ep_out_wakers[0].register(cx.waker()); 1318 state.ep_out_wakers[0].register(cx.waker());
1319 1319
1320 let r = T::regs();
1321
1320 if state.ep0_setup_ready.load(Ordering::Relaxed) { 1322 if state.ep0_setup_ready.load(Ordering::Relaxed) {
1321 let data = unsafe { *state.ep0_setup_data.get() }; 1323 let data = unsafe { *state.ep0_setup_data.get() };
1322 state.ep0_setup_ready.store(false, Ordering::Release); 1324 state.ep0_setup_ready.store(false, Ordering::Release);
1323 1325
1324 // EP0 should not be controlled by `Bus` so this RMW does not need a critical section 1326 // EP0 should not be controlled by `Bus` so this RMW does not need a critical section
1325 // Receive 1 SETUP packet 1327 // Receive 1 SETUP packet
1326 T::regs().doeptsiz(self.ep_out.info.addr.index()).modify(|w| { 1328 r.doeptsiz(self.ep_out.info.addr.index()).modify(|w| {
1327 w.set_rxdpid_stupcnt(1); 1329 w.set_rxdpid_stupcnt(1);
1328 }); 1330 });
1329 1331
1332 // Clear NAK to indicate we are ready to receive more data
1333 if !quirk_setup_late_cnak(r) {
1334 r.doepctl(self.ep_out.info.addr.index()).modify(|w| w.set_cnak(true));
1335 }
1336
1330 trace!("SETUP received: {:?}", data); 1337 trace!("SETUP received: {:?}", data);
1331 Poll::Ready(data) 1338 Poll::Ready(data)
1332 } else { 1339 } else {
@@ -1461,3 +1468,7 @@ fn calculate_trdt(speed: vals::Dspd, ahb_freq: Hertz) -> u8 {
1461 _ => unimplemented!(), 1468 _ => unimplemented!(),
1462 } 1469 }
1463} 1470}
1471
1472fn quirk_setup_late_cnak(r: crate::pac::otg::Otg) -> bool {
1473 r.cid().read().0 & 0xf000 == 0x1000
1474}