aboutsummaryrefslogtreecommitdiff
path: root/embassy-rp
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-06-02 04:04:38 +0200
committerDario Nieuwenhuis <[email protected]>2023-06-02 04:05:25 +0200
commitdd5ce985bda5f36fdd934fe27de55c46a9972a1a (patch)
tree8811a1ff31694939c3f470e240f3fd88ae0583ec /embassy-rp
parentf901cf57e56d3080c4722d8753c3f31819f520cc (diff)
rp/spi: enable rxdmae/txdmae only once at init.
see https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/hardware_spi/spi.c#L27-L28
Diffstat (limited to 'embassy-rp')
-rw-r--r--embassy-rp/src/spi.rs27
1 files changed, 8 insertions, 19 deletions
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs
index 2cd2aa753..7da214743 100644
--- a/embassy-rp/src/spi.rs
+++ b/embassy-rp/src/spi.rs
@@ -90,10 +90,16 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
90 w.set_sph(config.phase == Phase::CaptureOnSecondTransition); 90 w.set_sph(config.phase == Phase::CaptureOnSecondTransition);
91 w.set_scr(postdiv); 91 w.set_scr(postdiv);
92 }); 92 });
93 p.cr1().write(|w| { 93
94 w.set_sse(true); // enable 94 // Always enable DREQ signals -- harmless if DMA is not listening
95 p.dmacr().write(|reg| {
96 reg.set_rxdmae(true);
97 reg.set_txdmae(true);
95 }); 98 });
96 99
100 // finally, enable.
101 p.cr1().write(|w| w.set_sse(true));
102
97 if let Some(pin) = &clk { 103 if let Some(pin) = &clk {
98 pin.io().ctrl().write(|w| w.set_funcsel(1)); 104 pin.io().ctrl().write(|w| w.set_funcsel(1));
99 } 105 }
@@ -329,9 +335,6 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
329 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 335 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
330 let tx_ch = self.tx_dma.as_mut().unwrap(); 336 let tx_ch = self.tx_dma.as_mut().unwrap();
331 let tx_transfer = unsafe { 337 let tx_transfer = unsafe {
332 self.inner.regs().dmacr().modify(|reg| {
333 reg.set_txdmae(true);
334 });
335 // If we don't assign future to a variable, the data register pointer 338 // If we don't assign future to a variable, the data register pointer
336 // is held across an await and makes the future non-Send. 339 // is held across an await and makes the future non-Send.
337 crate::dma::write(tx_ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ) 340 crate::dma::write(tx_ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ)
@@ -354,13 +357,6 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
354 } 357 }
355 358
356 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 359 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
357 unsafe {
358 self.inner.regs().dmacr().write(|reg| {
359 reg.set_rxdmae(true);
360 reg.set_txdmae(true);
361 })
362 };
363
364 // Start RX first. Transfer starts when TX starts, if RX 360 // Start RX first. Transfer starts when TX starts, if RX
365 // is not started yet we might lose bytes. 361 // is not started yet we might lose bytes.
366 let rx_ch = self.rx_dma.as_mut().unwrap(); 362 let rx_ch = self.rx_dma.as_mut().unwrap();
@@ -392,13 +388,6 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
392 let (_, tx_len) = crate::dma::slice_ptr_parts(tx_ptr); 388 let (_, tx_len) = crate::dma::slice_ptr_parts(tx_ptr);
393 let (_, rx_len) = crate::dma::slice_ptr_parts_mut(rx_ptr); 389 let (_, rx_len) = crate::dma::slice_ptr_parts_mut(rx_ptr);
394 390
395 unsafe {
396 self.inner.regs().dmacr().write(|reg| {
397 reg.set_rxdmae(true);
398 reg.set_txdmae(true);
399 })
400 };
401
402 // Start RX first. Transfer starts when TX starts, if RX 391 // Start RX first. Transfer starts when TX starts, if RX
403 // is not started yet we might lose bytes. 392 // is not started yet we might lose bytes.
404 let rx_ch = self.rx_dma.as_mut().unwrap(); 393 let rx_ch = self.rx_dma.as_mut().unwrap();