fix: UCPD drop logic

Read rxpaysz immediately
This commit is contained in:
elagil 2025-02-07 23:31:02 +01:00
parent 3b734a7d08
commit 38799c63fd

View File

@ -266,7 +266,7 @@ impl<'d, T: Instance> Drop for CcPhy<'d, T> {
// Check if the PdPhy part was dropped already. // Check if the PdPhy part was dropped already.
let drop_not_ready = &T::state().drop_not_ready; let drop_not_ready = &T::state().drop_not_ready;
if drop_not_ready.load(Ordering::Relaxed) { if drop_not_ready.load(Ordering::Relaxed) {
drop_not_ready.store(true, Ordering::Relaxed); drop_not_ready.store(false, Ordering::Relaxed);
} else { } else {
r.cfgr1().write(|w| w.set_ucpden(false)); r.cfgr1().write(|w| w.set_ucpden(false));
rcc::disable::<T>(); rcc::disable::<T>();
@ -411,13 +411,14 @@ pub struct PdPhy<'d, T: Instance> {
impl<'d, T: Instance> Drop for PdPhy<'d, T> { impl<'d, T: Instance> Drop for PdPhy<'d, T> {
fn drop(&mut self) { fn drop(&mut self) {
T::REGS.cr().modify(|w| w.set_phyrxen(false)); let r = T::REGS;
// Check if the Type-C part was dropped already. r.cr().modify(|w| w.set_phyrxen(false));
// Check if the CcPhy part was dropped already.
let drop_not_ready = &T::state().drop_not_ready; let drop_not_ready = &T::state().drop_not_ready;
if drop_not_ready.load(Ordering::Relaxed) { if drop_not_ready.load(Ordering::Relaxed) {
drop_not_ready.store(true, Ordering::Relaxed); drop_not_ready.store(false, Ordering::Relaxed);
} else { } else {
T::REGS.cfgr1().write(|w| w.set_ucpden(false)); r.cfgr1().write(|w| w.set_ucpden(false));
rcc::disable::<T>(); rcc::disable::<T>();
T::Interrupt::disable(); T::Interrupt::disable();
} }
@ -453,6 +454,8 @@ impl<'d, T: Instance> PdPhy<'d, T> {
}); });
}); });
let mut rxpaysz = 0;
// Stop DMA reception immediately after receiving a packet, to prevent storing multiple packets in the same buffer. // Stop DMA reception immediately after receiving a packet, to prevent storing multiple packets in the same buffer.
poll_fn(|cx| { poll_fn(|cx| {
let sr = r.sr().read(); let sr = r.sr().read();
@ -466,6 +469,8 @@ impl<'d, T: Instance> PdPhy<'d, T> {
Poll::Ready(Err(RxError::HardReset)) Poll::Ready(Err(RxError::HardReset))
} else if sr.rxmsgend() { } else if sr.rxmsgend() {
dma.request_stop(); dma.request_stop();
// Should be read immediately on interrupt.
rxpaysz = r.rx_payszr().read().rxpaysz().into();
let ret = if sr.rxovr() { let ret = if sr.rxovr() {
Err(RxError::Overrun) Err(RxError::Overrun)
@ -501,7 +506,7 @@ impl<'d, T: Instance> PdPhy<'d, T> {
_ => unreachable!(), _ => unreachable!(),
}; };
Ok((sop, r.rx_payszr().read().rxpaysz().into())) Ok((sop, rxpaysz))
} }
fn enable_rx_interrupt(enable: bool) { fn enable_rx_interrupt(enable: bool) {