Spi works when working within rtic init. It does not work within a rtic task.
seanybaggins opened this issue · comments
Hi David,
I am having an issue where spi will work when a write is called within rtic's init function but when a write is called within a software task, the write call hangs.
Initialization code
let cs = Pin::new(Port::G, 12, PinMode::Output);
let _sck = Pin::new(Port::C, 10, PinMode::Alt(6));
let _miso = Pin::new(Port::C, 11, PinMode::Alt(6));
let _mosi = Pin::new(Port::C, 12, PinMode::Alt(6));
let mode = SpiMode {
polarity: SpiPolarity::IdleLow,
phase: SpiPhase::CaptureOnFirstTransition,
};
let spi_config = SpiConfig {
mode,
..Default::default()
};
// spi_clock_frequency = 80MHz / BaudRate::<divisor>
let spi = Spi::new(reg, spi_config, BaudRate::Div32);
Here is where things hang
// In spi.rs line 557
while !self.regs.sr.read().rxne().bit_is_set() {}
Any thoughts or workarounds to getting a spi.write call to work within a software task?
No idea; have never used software tasks. Maybe the RTIC guys can help.
Here's the code from spi.rs from line 529 to 561:
/// Read a single byte if available, or block until it's available.
/// See L44 RM, section 40.4.9: Data transmission and reception procedures.
#[cfg(not(feature = "h7"))]
pub fn read(&mut self) -> Result<u8, SpiError> {
let sr = self.regs.sr.read();
cfg_if! {
if #[cfg(feature = "h7")] {
let crce = sr.crce().bit_is_set();
} else {
let crce = sr.crcerr().bit_is_set();
}
}
if sr.ovr().bit_is_set() {
return Err(SpiError::Overrun);
} else if sr.modf().bit_is_set() {
return Err(SpiError::ModeFault);
} else if crce {
return Err(SpiError::Crc);
}
cfg_if! {
if #[cfg(feature = "h7")] {
while !self.regs.sr.read().rxp().bit_is_set() {}
// todo: note: H7 can support words beyond u8. (Can others too?)
Ok(unsafe{ ptr::read_volatile(&self.regs.rxdr as *const _ as *const u8) })
} else {
while !self.regs.sr.read().rxne().bit_is_set() {}
Ok(unsafe { ptr::read_volatile(&self.regs.dr as *const _ as *const u8) })
}
}
}
The RXNE
flag indicates that the buffer is not empty ("Receive Not Empty" literally) as far as I understand it. Could you show your software task code? Are you perfectly sure you're not calling read instead of write?
Closing; re-open if this is still coming up.