rp: let SPI RX overflow during async write

This commit is contained in:
Alex Martens 2022-09-18 12:23:17 -07:00 committed by Mathias
parent c14527486d
commit 4322293f63
2 changed files with 17 additions and 37 deletions

View File

@ -56,25 +56,6 @@ pub unsafe fn read<'a, C: Channel, W: Word>(
) )
} }
pub unsafe fn read_repeated<'a, C: Channel, W: Word>(
ch: impl Peripheral<P = C> + 'a,
from: *const W,
len: usize,
dreq: u8,
) -> Transfer<'a, C> {
let mut dummy: u32 = 0;
copy_inner(
ch,
from as *const u32,
&mut dummy as *mut u32,
len,
W::size(),
false,
false,
dreq,
)
}
pub unsafe fn write<'a, C: Channel, W: Word>( pub unsafe fn write<'a, C: Channel, W: Word>(
ch: impl Peripheral<P = C> + 'a, ch: impl Peripheral<P = C> + 'a,
from: *const [W], from: *const [W],

View File

@ -325,30 +325,29 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
} }
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
unsafe {
self.inner.regs().dmacr().write(|reg| {
reg.set_rxdmae(true);
reg.set_txdmae(true);
})
};
let tx_ch = self.tx_dma.as_mut().unwrap(); let tx_ch = self.tx_dma.as_mut().unwrap();
let tx_transfer = unsafe { let tx_transfer = unsafe {
self.inner.regs().dmacr().modify(|reg| {
reg.set_txdmae(true);
});
// If we don't assign future to a variable, the data register pointer // If we don't assign future to a variable, the data register pointer
// is held across an await and makes the future non-Send. // is held across an await and makes the future non-Send.
crate::dma::write(tx_ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ) crate::dma::write(tx_ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ)
}; };
let rx_ch = self.rx_dma.as_mut().unwrap(); tx_transfer.await;
let rx_transfer = unsafe {
// If we don't assign future to a variable, the data register pointer let p = self.inner.regs();
// is held across an await and makes the future non-Send. unsafe {
crate::dma::read_repeated( while p.sr().read().bsy() {}
rx_ch,
self.inner.regs().dr().ptr() as *const u8, // clear RX FIFO contents to prevent stale reads
buffer.len(), while p.sr().read().rne() {
T::RX_DREQ, let _: u16 = p.dr().read().data();
) }
}; // clear RX overrun interrupt
join(tx_transfer, rx_transfer).await; p.icr().write(|w| w.set_roric(true));
}
Ok(()) Ok(())
} }