diff options
| -rw-r--r-- | embassy-nrf/src/lib.rs | 7 | ||||
| -rw-r--r-- | embassy-nrf/src/spis.rs | 55 | ||||
| -rw-r--r-- | examples/nrf/src/bin/spis.rs | 8 |
3 files changed, 31 insertions, 39 deletions
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 587e19be5..5726f1181 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -268,5 +268,12 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 268 | #[cfg(feature = "_time-driver")] | 268 | #[cfg(feature = "_time-driver")] |
| 269 | time_driver::init(config.time_interrupt_priority); | 269 | time_driver::init(config.time_interrupt_priority); |
| 270 | 270 | ||
| 271 | // Disable UARTE (enabled by default for some reason) | ||
| 272 | #[cfg(feature = "_nrf9160")] | ||
| 273 | unsafe { | ||
| 274 | (*pac::UARTE0::ptr()).enable.write(|w| w.enable().disabled()); | ||
| 275 | (*pac::UARTE1::ptr()).enable.write(|w| w.enable().disabled()); | ||
| 276 | } | ||
| 277 | |||
| 271 | peripherals | 278 | peripherals |
| 272 | } | 279 | } |
diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index e005f7b92..61c5fe998 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | |||
| 3 | use core::future::poll_fn; | 2 | use core::future::poll_fn; |
| 4 | use core::sync::atomic::{compiler_fence, Ordering}; | 3 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 5 | use core::task::Poll; | 4 | use core::task::Poll; |
| @@ -10,7 +9,7 @@ pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MO | |||
| 10 | 9 | ||
| 11 | use crate::chip::FORCE_COPY_BUFFER_SIZE; | 10 | use crate::chip::FORCE_COPY_BUFFER_SIZE; |
| 12 | use crate::gpio::sealed::Pin as _; | 11 | use crate::gpio::sealed::Pin as _; |
| 13 | use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; | 12 | use crate::gpio::{self, AnyPin, Pin as GpioPin}; |
| 14 | use crate::interrupt::{Interrupt, InterruptExt}; | 13 | use crate::interrupt::{Interrupt, InterruptExt}; |
| 15 | use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut}; | 14 | use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut}; |
| 16 | use crate::{pac, Peripheral}; | 15 | use crate::{pac, Peripheral}; |
| @@ -122,41 +121,26 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 122 | mosi: Option<PeripheralRef<'d, AnyPin>>, | 121 | mosi: Option<PeripheralRef<'d, AnyPin>>, |
| 123 | config: Config, | 122 | config: Config, |
| 124 | ) -> Self { | 123 | ) -> Self { |
| 125 | into_ref!(cs, spis, irq); | 124 | compiler_fence(Ordering::SeqCst); |
| 125 | |||
| 126 | into_ref!(spis, irq, cs, sck); | ||
| 126 | 127 | ||
| 127 | let r = T::regs(); | 128 | let r = T::regs(); |
| 128 | 129 | ||
| 129 | // Configure pins. | 130 | // Configure pins. |
| 130 | sck.conf().write(|w| w.input().connect().drive().h0h1()); | 131 | sck.conf().write(|w| w.input().connect().drive().h0h1()); |
| 132 | r.psel.sck.write(|w| unsafe { w.bits(sck.psel_bits()) }); | ||
| 131 | cs.conf().write(|w| w.input().connect().drive().h0h1()); | 133 | cs.conf().write(|w| w.input().connect().drive().h0h1()); |
| 134 | r.psel.csn.write(|w| unsafe { w.bits(cs.psel_bits()) }); | ||
| 132 | if let Some(mosi) = &mosi { | 135 | if let Some(mosi) = &mosi { |
| 133 | mosi.conf().write(|w| w.input().connect().drive().h0h1()); | 136 | mosi.conf().write(|w| w.input().connect().drive().h0h1()); |
| 137 | r.psel.mosi.write(|w| unsafe { w.bits(mosi.psel_bits()) }); | ||
| 134 | } | 138 | } |
| 135 | if let Some(miso) = &miso { | 139 | if let Some(miso) = &miso { |
| 136 | miso.conf().write(|w| w.dir().output().drive().h0h1()); | 140 | miso.conf().write(|w| w.dir().output().drive().h0h1()); |
| 141 | r.psel.miso.write(|w| unsafe { w.bits(miso.psel_bits()) }); | ||
| 137 | } | 142 | } |
| 138 | 143 | ||
| 139 | match config.mode.polarity { | ||
| 140 | Polarity::IdleHigh => { | ||
| 141 | sck.set_high(); | ||
| 142 | if let Some(mosi) = &mosi { | ||
| 143 | mosi.set_high(); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | Polarity::IdleLow => { | ||
| 147 | sck.set_low(); | ||
| 148 | if let Some(mosi) = &mosi { | ||
| 149 | mosi.set_low(); | ||
| 150 | } | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | // Select pins. | ||
| 155 | r.psel.sck.write(|w| unsafe { w.bits(sck.psel_bits()) }); | ||
| 156 | r.psel.csn.write(|w| unsafe { w.bits(cs.psel_bits()) }); | ||
| 157 | r.psel.mosi.write(|w| unsafe { w.bits(mosi.psel_bits()) }); | ||
| 158 | r.psel.miso.write(|w| unsafe { w.bits(miso.psel_bits()) }); | ||
| 159 | |||
| 160 | // Enable SPIS instance. | 144 | // Enable SPIS instance. |
| 161 | r.enable.write(|w| w.enable().enabled()); | 145 | r.enable.write(|w| w.enable().enabled()); |
| 162 | 146 | ||
| @@ -217,12 +201,12 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 217 | let s = T::state(); | 201 | let s = T::state(); |
| 218 | 202 | ||
| 219 | if r.events_end.read().bits() != 0 { | 203 | if r.events_end.read().bits() != 0 { |
| 220 | s.end_waker.wake(); | 204 | s.waker.wake(); |
| 221 | r.intenclr.write(|w| w.end().clear()); | 205 | r.intenclr.write(|w| w.end().clear()); |
| 222 | } | 206 | } |
| 223 | 207 | ||
| 224 | if r.events_acquired.read().bits() != 0 { | 208 | if r.events_acquired.read().bits() != 0 { |
| 225 | s.acquire_waker.wake(); | 209 | s.waker.wake(); |
| 226 | r.intenclr.write(|w| w.acquired().clear()); | 210 | r.intenclr.write(|w| w.acquired().clear()); |
| 227 | } | 211 | } |
| 228 | } | 212 | } |
| @@ -246,9 +230,8 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 246 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); | 230 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); |
| 247 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | 231 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); |
| 248 | 232 | ||
| 249 | // Reset and enable the end event. | 233 | // Reset end event. |
| 250 | r.events_end.reset(); | 234 | r.events_end.reset(); |
| 251 | r.intenset.write(|w| w.end().set()); | ||
| 252 | 235 | ||
| 253 | // Release the semaphore. | 236 | // Release the semaphore. |
| 254 | r.tasks_release.write(|w| unsafe { w.bits(1) }); | 237 | r.tasks_release.write(|w| unsafe { w.bits(1) }); |
| @@ -312,8 +295,9 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 312 | 295 | ||
| 313 | // Wait until CPU has acquired the semaphore. | 296 | // Wait until CPU has acquired the semaphore. |
| 314 | poll_fn(|cx| { | 297 | poll_fn(|cx| { |
| 315 | s.acquire_waker.register(cx.waker()); | 298 | s.waker.register(cx.waker()); |
| 316 | if r.semstat.read().bits() == 1 { | 299 | if r.events_acquired.read().bits() == 1 { |
| 300 | r.events_acquired.reset(); | ||
| 317 | return Poll::Ready(()); | 301 | return Poll::Ready(()); |
| 318 | } | 302 | } |
| 319 | Poll::Pending | 303 | Poll::Pending |
| @@ -324,12 +308,13 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 324 | self.prepare(rx, tx)?; | 308 | self.prepare(rx, tx)?; |
| 325 | 309 | ||
| 326 | // Wait for 'end' event. | 310 | // Wait for 'end' event. |
| 311 | r.intenset.write(|w| w.end().set()); | ||
| 327 | poll_fn(|cx| { | 312 | poll_fn(|cx| { |
| 328 | s.end_waker.register(cx.waker()); | 313 | s.waker.register(cx.waker()); |
| 329 | if r.events_end.read().bits() != 0 { | 314 | if r.events_end.read().bits() != 0 { |
| 315 | r.events_end.reset(); | ||
| 330 | return Poll::Ready(()); | 316 | return Poll::Ready(()); |
| 331 | } | 317 | } |
| 332 | |||
| 333 | Poll::Pending | 318 | Poll::Pending |
| 334 | }) | 319 | }) |
| 335 | .await; | 320 | .await; |
| @@ -466,15 +451,13 @@ pub(crate) mod sealed { | |||
| 466 | use super::*; | 451 | use super::*; |
| 467 | 452 | ||
| 468 | pub struct State { | 453 | pub struct State { |
| 469 | pub end_waker: AtomicWaker, | 454 | pub waker: AtomicWaker, |
| 470 | pub acquire_waker: AtomicWaker, | ||
| 471 | } | 455 | } |
| 472 | 456 | ||
| 473 | impl State { | 457 | impl State { |
| 474 | pub const fn new() -> Self { | 458 | pub const fn new() -> Self { |
| 475 | Self { | 459 | Self { |
| 476 | end_waker: AtomicWaker::new(), | 460 | waker: AtomicWaker::new(), |
| 477 | acquire_waker: AtomicWaker::new(), | ||
| 478 | } | 461 | } |
| 479 | } | 462 | } |
| 480 | } | 463 | } |
diff --git a/examples/nrf/src/bin/spis.rs b/examples/nrf/src/bin/spis.rs index dade5fcbd..fe3b0c53d 100644 --- a/examples/nrf/src/bin/spis.rs +++ b/examples/nrf/src/bin/spis.rs | |||
| @@ -17,9 +17,11 @@ async fn main(_spawner: Spawner) { | |||
| 17 | let mut spis = Spis::new(p.SPI2, irq, p.P0_31, p.P0_29, p.P0_28, p.P0_30, Config::default()); | 17 | let mut spis = Spis::new(p.SPI2, irq, p.P0_31, p.P0_29, p.P0_28, p.P0_30, Config::default()); |
| 18 | 18 | ||
| 19 | loop { | 19 | loop { |
| 20 | let mut buf = [0_u8; 64]; | 20 | let mut rx_buf = [0_u8; 64]; |
| 21 | if let Ok(n) = spis.read(&mut buf).await { | 21 | let tx_buf = [1_u8, 2, 3, 4, 5, 6, 7, 8]; |
| 22 | info!("RX: {:?}", buf[..n]); | 22 | if let Ok((n_rx, n_tx)) = spis.transfer(&mut rx_buf, &tx_buf).await { |
| 23 | info!("RX: {:?}", rx_buf[..n_rx]); | ||
| 24 | info!("TX: {:?}", tx_buf[..n_tx]); | ||
| 23 | } | 25 | } |
| 24 | } | 26 | } |
| 25 | } | 27 | } |
