From dca11095e2f41d50dbc96d48474a64d9198728c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Als=C3=A9r?= Date: Sun, 13 Nov 2022 01:49:55 +0100 Subject: [PATCH 1/5] Disable UARTE in embassy-nrf::init --- embassy-nrf/src/lib.rs | 6 ++++++ embassy-nrf/src/spis.rs | 39 +++++++++++------------------------- examples/nrf/src/bin/spis.rs | 8 +++++--- 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 587e19be..67b25498 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -268,5 +268,11 @@ pub fn init(config: config::Config) -> Peripherals { #[cfg(feature = "_time-driver")] time_driver::init(config.time_interrupt_priority); + // Disable UARTE (enabled by default for some reason) + unsafe { + (*pac::UARTE0::ptr()).enable.write(|w| w.enable().disabled()); + (*pac::UARTE1::ptr()).enable.write(|w| w.enable().disabled()); + } + peripherals } diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index 3f77c61d..416db2d3 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs @@ -1,5 +1,4 @@ #![macro_use] - use core::future::poll_fn; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; @@ -10,7 +9,7 @@ pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MO use crate::chip::FORCE_COPY_BUFFER_SIZE; use crate::gpio::sealed::Pin as _; -use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; +use crate::gpio::{self, AnyPin, Pin as GpioPin}; use crate::interrupt::{Interrupt, InterruptExt}; use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut}; use crate::{pac, Peripheral}; @@ -122,41 +121,26 @@ impl<'d, T: Instance> Spis<'d, T> { mosi: Option>, config: Config, ) -> Self { - into_ref!(cs, spis, irq); + compiler_fence(Ordering::SeqCst); + + into_ref!(spis, irq, cs, sck); let r = T::regs(); // Configure pins. sck.conf().write(|w| w.input().connect().drive().h0h1()); + r.psel.sck.write(|w| unsafe { w.bits(sck.psel_bits()) }); cs.conf().write(|w| w.input().connect().drive().h0h1()); + r.psel.csn.write(|w| unsafe { w.bits(cs.psel_bits()) }); if let Some(mosi) = &mosi { mosi.conf().write(|w| w.input().connect().drive().h0h1()); + r.psel.mosi.write(|w| unsafe { w.bits(mosi.psel_bits()) }); } if let Some(miso) = &miso { miso.conf().write(|w| w.dir().output().drive().h0h1()); + r.psel.miso.write(|w| unsafe { w.bits(miso.psel_bits()) }); } - match config.mode.polarity { - Polarity::IdleHigh => { - sck.set_high(); - if let Some(mosi) = &mosi { - mosi.set_high(); - } - } - Polarity::IdleLow => { - sck.set_low(); - if let Some(mosi) = &mosi { - mosi.set_low(); - } - } - } - - // Select pins. - r.psel.sck.write(|w| unsafe { w.bits(sck.psel_bits()) }); - r.psel.csn.write(|w| unsafe { w.bits(cs.psel_bits()) }); - r.psel.mosi.write(|w| unsafe { w.bits(mosi.psel_bits()) }); - r.psel.miso.write(|w| unsafe { w.bits(miso.psel_bits()) }); - // Enable SPIS instance. r.enable.write(|w| w.enable().enabled()); @@ -246,9 +230,8 @@ impl<'d, T: Instance> Spis<'d, T> { r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); - // Reset and enable the end event. + // Reset end event. r.events_end.reset(); - r.intenset.write(|w| w.end().set()); // Release the semaphore. r.tasks_release.write(|w| unsafe { w.bits(1) }); @@ -316,6 +299,7 @@ impl<'d, T: Instance> Spis<'d, T> { if r.semstat.read().bits() == 1 { return Poll::Ready(()); } + r.intenset.write(|w| w.acquired().set()); Poll::Pending }) .await; @@ -324,12 +308,13 @@ impl<'d, T: Instance> Spis<'d, T> { self.prepare(rx, tx)?; // Wait for 'end' event. + r.intenset.write(|w| w.end().set()); poll_fn(|cx| { s.end_waker.register(cx.waker()); if r.events_end.read().bits() != 0 { return Poll::Ready(()); } - + r.intenset.write(|w| w.end().set()); Poll::Pending }) .await; diff --git a/examples/nrf/src/bin/spis.rs b/examples/nrf/src/bin/spis.rs index dade5fcb..fe3b0c53 100644 --- a/examples/nrf/src/bin/spis.rs +++ b/examples/nrf/src/bin/spis.rs @@ -17,9 +17,11 @@ async fn main(_spawner: Spawner) { let mut spis = Spis::new(p.SPI2, irq, p.P0_31, p.P0_29, p.P0_28, p.P0_30, Config::default()); loop { - let mut buf = [0_u8; 64]; - if let Ok(n) = spis.read(&mut buf).await { - info!("RX: {:?}", buf[..n]); + let mut rx_buf = [0_u8; 64]; + let tx_buf = [1_u8, 2, 3, 4, 5, 6, 7, 8]; + if let Ok((n_rx, n_tx)) = spis.transfer(&mut rx_buf, &tx_buf).await { + info!("RX: {:?}", rx_buf[..n_rx]); + info!("TX: {:?}", tx_buf[..n_tx]); } } } From 5cfad3f853280069e2927e4838d9b56980e28e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Als=C3=A9r?= Date: Sun, 13 Nov 2022 02:37:23 +0100 Subject: [PATCH 2/5] Feature gate UARTE disable --- embassy-nrf/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 67b25498..5726f118 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -269,6 +269,7 @@ pub fn init(config: config::Config) -> Peripherals { time_driver::init(config.time_interrupt_priority); // Disable UARTE (enabled by default for some reason) + #[cfg(feature = "_nrf9160")] unsafe { (*pac::UARTE0::ptr()).enable.write(|w| w.enable().disabled()); (*pac::UARTE1::ptr()).enable.write(|w| w.enable().disabled()); From 8d2d5a30a519de76c3c74e5e8066ac3bc9aa8f77 Mon Sep 17 00:00:00 2001 From: kalkyl Date: Mon, 14 Nov 2022 11:39:55 +0100 Subject: [PATCH 3/5] Single waker --- embassy-nrf/src/spis.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index 416db2d3..f3105007 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs @@ -201,12 +201,12 @@ impl<'d, T: Instance> Spis<'d, T> { let s = T::state(); if r.events_end.read().bits() != 0 { - s.end_waker.wake(); + s.waker.wake(); r.intenclr.write(|w| w.end().clear()); } if r.events_acquired.read().bits() != 0 { - s.acquire_waker.wake(); + s.waker.wake(); r.intenclr.write(|w| w.acquired().clear()); } } @@ -295,7 +295,7 @@ impl<'d, T: Instance> Spis<'d, T> { // Wait until CPU has acquired the semaphore. poll_fn(|cx| { - s.acquire_waker.register(cx.waker()); + s.waker.register(cx.waker()); if r.semstat.read().bits() == 1 { return Poll::Ready(()); } @@ -310,7 +310,7 @@ impl<'d, T: Instance> Spis<'d, T> { // Wait for 'end' event. r.intenset.write(|w| w.end().set()); poll_fn(|cx| { - s.end_waker.register(cx.waker()); + s.waker.register(cx.waker()); if r.events_end.read().bits() != 0 { return Poll::Ready(()); } @@ -451,15 +451,13 @@ pub(crate) mod sealed { use super::*; pub struct State { - pub end_waker: AtomicWaker, - pub acquire_waker: AtomicWaker, + pub waker: AtomicWaker, } impl State { pub const fn new() -> Self { Self { - end_waker: AtomicWaker::new(), - acquire_waker: AtomicWaker::new(), + waker: AtomicWaker::new(), } } } From 3a1ddd66c64db1c5efd79b89efd76ac97d9eccce Mon Sep 17 00:00:00 2001 From: kalkyl Date: Mon, 14 Nov 2022 16:18:11 +0100 Subject: [PATCH 4/5] Cleanup interrupts --- embassy-nrf/src/spis.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index f3105007..d382ee0c 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs @@ -297,9 +297,9 @@ impl<'d, T: Instance> Spis<'d, T> { poll_fn(|cx| { s.waker.register(cx.waker()); if r.semstat.read().bits() == 1 { + r.events_acquired.reset(); return Poll::Ready(()); } - r.intenset.write(|w| w.acquired().set()); Poll::Pending }) .await; @@ -312,9 +312,9 @@ impl<'d, T: Instance> Spis<'d, T> { poll_fn(|cx| { s.waker.register(cx.waker()); if r.events_end.read().bits() != 0 { + r.events_end.reset(); return Poll::Ready(()); } - r.intenset.write(|w| w.end().set()); Poll::Pending }) .await; From 0b066b22d11ee07ed64906b27e950ba83368aa49 Mon Sep 17 00:00:00 2001 From: kalkyl Date: Mon, 14 Nov 2022 16:24:21 +0100 Subject: [PATCH 5/5] Check events_acquired --- embassy-nrf/src/spis.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index d382ee0c..f6f7db3a 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs @@ -296,7 +296,7 @@ impl<'d, T: Instance> Spis<'d, T> { // Wait until CPU has acquired the semaphore. poll_fn(|cx| { s.waker.register(cx.waker()); - if r.semstat.read().bits() == 1 { + if r.events_acquired.read().bits() == 1 { r.events_acquired.reset(); return Poll::Ready(()); }