diff options
| author | Henrik Alsér <[email protected]> | 2022-11-22 00:55:46 +0100 |
|---|---|---|
| committer | Henrik Alsér <[email protected]> | 2022-11-22 00:55:46 +0100 |
| commit | 33ee48b9e815079bbc879818e744b40ce4ed8451 (patch) | |
| tree | bf8127a3596979a47c46090738b3331f950ffd89 /embassy-nrf/src/spis.rs | |
| parent | a6d941fac3d08512f7ef90131d7189ae3aa83bf0 (diff) | |
| parent | 0b066b22d11ee07ed64906b27e950ba83368aa49 (diff) | |
Merge branch 'spis' of github.com:kalkyl/embassy into spis
Diffstat (limited to 'embassy-nrf/src/spis.rs')
| -rw-r--r-- | embassy-nrf/src/spis.rs | 55 |
1 files changed, 19 insertions, 36 deletions
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 | } |
