aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Martens <[email protected]>2022-09-18 12:23:17 -0700
committerAlex Martens <[email protected]>2022-09-18 12:23:17 -0700
commit295cc997ae8b1468617dd9f430be4e502901f4f2 (patch)
treef85f36327a1b10dee77e7dd982d8392d05ad65e3
parentab1a6889a62e86a80af6fc572ffa992cfb9ef960 (diff)
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 b256cc2f0..7ad1a6bfe 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>(
56 ) 56 )
57} 57}
58 58
59pub unsafe fn read_repeated<'a, C: Channel, W: Word>(
60 ch: impl Peripheral<P = C> + 'a,
61 from: *const W,
62 len: usize,
63 dreq: u8,
64) -> Transfer<'a, C> {
65 let mut dummy: u32 = 0;
66 copy_inner(
67 ch,
68 from as *const u32,
69 &mut dummy as *mut u32,
70 len,
71 W::size(),
72 false,
73 false,
74 dreq,
75 )
76}
77
78pub unsafe fn write<'a, C: Channel, W: Word>( 59pub unsafe fn write<'a, C: Channel, W: Word>(
79 ch: impl Peripheral<P = C> + 'a, 60 ch: impl Peripheral<P = C> + 'a,
80 from: *const [W], 61 from: *const [W],
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs
index e7cd99929..3cf823573 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> {
325 } 325 }
326 326
327 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 327 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
328 unsafe {
329 self.inner.regs().dmacr().write(|reg| {
330 reg.set_rxdmae(true);
331 reg.set_txdmae(true);
332 })
333 };
334 let tx_ch = self.tx_dma.as_mut().unwrap(); 328 let tx_ch = self.tx_dma.as_mut().unwrap();
335 let tx_transfer = unsafe { 329 let tx_transfer = unsafe {
330 self.inner.regs().dmacr().modify(|reg| {
331 reg.set_txdmae(true);
332 });
336 // If we don't assign future to a variable, the data register pointer 333 // If we don't assign future to a variable, the data register pointer
337 // is held across an await and makes the future non-Send. 334 // is held across an await and makes the future non-Send.
338 crate::dma::write(tx_ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ) 335 crate::dma::write(tx_ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ)
339 }; 336 };
340 let rx_ch = self.rx_dma.as_mut().unwrap(); 337 tx_transfer.await;
341 let rx_transfer = unsafe { 338
342 // If we don't assign future to a variable, the data register pointer 339 let p = self.inner.regs();
343 // is held across an await and makes the future non-Send. 340 unsafe {
344 crate::dma::read_repeated( 341 while p.sr().read().bsy() {}
345 rx_ch, 342
346 self.inner.regs().dr().ptr() as *const u8, 343 // clear RX FIFO contents to prevent stale reads
347 buffer.len(), 344 while p.sr().read().rne() {
348 T::RX_DREQ, 345 let _: u16 = p.dr().read().data();
349 ) 346 }
350 }; 347 // clear RX overrun interrupt
351 join(tx_transfer, rx_transfer).await; 348 p.icr().write(|w| w.set_roric(true));
349 }
350
352 Ok(()) 351 Ok(())
353 } 352 }
354 353