convert spim txrx timeout from a hard-error into an error message

occassionally when the bus is loaded, some SPIM transactions won't
complete. this needs to be looked into a little more, i think...
This commit is contained in:
bunnie 2025-11-27 12:34:40 +08:00
parent a24aaaa944
commit bc4e459e28
3 changed files with 13 additions and 4 deletions

View file

@ -423,7 +423,11 @@ impl<'a> Oled128x128<'a> {
.txrx_data_async_from_parts::<u8>(total_buf_len, len, true, false)
.expect("Couldn't initiate oled command");
}
self.spim.txrx_await(false).unwrap();
self.spim.txrx_await(false).unwrap_or_else(|_e| {
#[cfg(feature = "std")]
log::error!("txrx err {:?}", _e);
&[]
});
}
pub fn init(&mut self) {
@ -479,7 +483,11 @@ impl<'a> FrameBuffer for Oled128x128<'a> {
.txrx_data_async_from_parts::<u8>(page * chunk_size, chunk_size, true, false)
.expect("Couldn't initiate oled data transfer");
}
self.spim.txrx_await(false).unwrap();
self.spim.txrx_await(false).unwrap_or_else(|_e| {
#[cfg(feature = "std")]
log::error!("txrx err {:?}", _e);
&[]
});
}
}

View file

@ -270,7 +270,7 @@ pub trait Udma {
); */
bank_addr.add(DmaReg::Saddr.into()).write_volatile(buf_addr);
bank_addr.add(DmaReg::Size.into()).write_volatile((buf.len() * size_of::<T>()) as u32);
bank_addr.add(DmaReg::Cfg.into()).write_volatile(config | CFG_EN)
bank_addr.add(DmaReg::Cfg.into()).write_volatile(config | CFG_EN | CFG_BACKPRESSURE)
}
fn udma_reset(&self, bank: Bank) {
unsafe {

View file

@ -657,7 +657,7 @@ impl Spim {
if let Some(pending) = self.pending_txrx.take() {
let tt = xous_api_ticktimer::Ticktimer::new().unwrap();
let start = tt.elapsed_ms();
let mut now = tt.elapsed_ms();
let mut now = start;
const TIMEOUT_MS: u64 = 500;
while (self.udma_busy(Bank::Tx) || self.udma_busy(Bank::Rx) || self.udma_busy(Bank::Custom))
&& ((now - start) < TIMEOUT_MS)
@ -690,6 +690,7 @@ impl Spim {
self.csr().base().add(Bank::Rx as usize).add(DmaReg::Saddr.into()).write_volatile(0);
self.csr().base().add(Bank::Rx as usize).add(DmaReg::Cfg.into()).write_volatile(0); // clear bit is not self-clearing
};
return Err(xous::Error::Timeout);
}
Ok(&self.rx_buf()[..pending])
} else {