summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Martens <alex@thinglab.org>2022-09-18 12:23:17 -0700
committerAlex Martens <alex@thinglab.org>2022-09-18 12:23:17 -0700
commit295cc997ae8b1468617dd9f430be4e502901f4f2 (patch)
treef85f36327a1b10dee77e7dd982d8392d05ad65e3
parentab1a6889a62e86a80af6fc572ffa992cfb9ef960 (diff)
downloadembassy-295cc997ae8b1468617dd9f430be4e502901f4f2.zip
rp: let SPI RX overflow during async write
-rw-r--r--embassy-rp/src/dma.rs19
-rw-r--r--embassy-rp/src/spi.rs35
2 files changed, 17 insertions, 37 deletions
diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs
index b256cc2f..7ad1a6bf 100644
--- a/embassy-rp/src/dma.rs
+++ b/embassy-rp/src/dma.rs
@@ -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>(
ch: impl Peripheral<P = C> + 'a,
from: *const [W],
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs
index e7cd9992..3cf82357 100644
--- a/embassy-rp/src/spi.rs
+++ b/embassy-rp/src/spi.rs
@@ -325,30 +325,29 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
}
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_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
// 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)
};
- let rx_ch = self.rx_dma.as_mut().unwrap();
- let rx_transfer = unsafe {
- // If we don't assign future to a variable, the data register pointer
- // is held across an await and makes the future non-Send.
- crate::dma::read_repeated(
- rx_ch,
- self.inner.regs().dr().ptr() as *const u8,
- buffer.len(),
- T::RX_DREQ,
- )
- };
- join(tx_transfer, rx_transfer).await;
+ tx_transfer.await;
+
+ let p = self.inner.regs();
+ unsafe {
+ while p.sr().read().bsy() {}
+
+ // clear RX FIFO contents to prevent stale reads
+ while p.sr().read().rne() {
+ let _: u16 = p.dr().read().data();
+ }
+ // clear RX overrun interrupt
+ p.icr().write(|w| w.set_roric(true));
+ }
+
Ok(())
}