aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/src/spis.rs50
1 files changed, 28 insertions, 22 deletions
diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs
index 2a3928d25..713163a55 100644
--- a/embassy-nrf/src/spis.rs
+++ b/embassy-nrf/src/spis.rs
@@ -96,14 +96,16 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
96 } 96 }
97} 97}
98 98
99/// SPIS driver. 99/// Serial Peripheral Interface in slave mode.
100pub struct Spis<'d, T: Instance> { 100pub struct Spis<'d> {
101 _p: Peri<'d, T>, 101 r: pac::spis::Spis,
102 state: &'static State,
103 _p: PhantomData<&'d ()>,
102} 104}
103 105
104impl<'d, T: Instance> Spis<'d, T> { 106impl<'d> Spis<'d> {
105 /// Create a new SPIS driver. 107 /// Create a new SPIS driver.
106 pub fn new( 108 pub fn new<T: Instance>(
107 spis: Peri<'d, T>, 109 spis: Peri<'d, T>,
108 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 110 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
109 cs: Peri<'d, impl GpioPin>, 111 cs: Peri<'d, impl GpioPin>,
@@ -123,7 +125,7 @@ impl<'d, T: Instance> Spis<'d, T> {
123 } 125 }
124 126
125 /// Create a new SPIS driver, capable of TX only (MISO only). 127 /// Create a new SPIS driver, capable of TX only (MISO only).
126 pub fn new_txonly( 128 pub fn new_txonly<T: Instance>(
127 spis: Peri<'d, T>, 129 spis: Peri<'d, T>,
128 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 130 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
129 cs: Peri<'d, impl GpioPin>, 131 cs: Peri<'d, impl GpioPin>,
@@ -135,7 +137,7 @@ impl<'d, T: Instance> Spis<'d, T> {
135 } 137 }
136 138
137 /// Create a new SPIS driver, capable of RX only (MOSI only). 139 /// Create a new SPIS driver, capable of RX only (MOSI only).
138 pub fn new_rxonly( 140 pub fn new_rxonly<T: Instance>(
139 spis: Peri<'d, T>, 141 spis: Peri<'d, T>,
140 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 142 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
141 cs: Peri<'d, impl GpioPin>, 143 cs: Peri<'d, impl GpioPin>,
@@ -147,7 +149,7 @@ impl<'d, T: Instance> Spis<'d, T> {
147 } 149 }
148 150
149 /// Create a new SPIS driver, capable of TX only (MISO only) without SCK pin. 151 /// Create a new SPIS driver, capable of TX only (MISO only) without SCK pin.
150 pub fn new_txonly_nosck( 152 pub fn new_txonly_nosck<T: Instance>(
151 spis: Peri<'d, T>, 153 spis: Peri<'d, T>,
152 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 154 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
153 cs: Peri<'d, impl GpioPin>, 155 cs: Peri<'d, impl GpioPin>,
@@ -157,8 +159,8 @@ impl<'d, T: Instance> Spis<'d, T> {
157 Self::new_inner(spis, cs.into(), None, Some(miso.into()), None, config) 159 Self::new_inner(spis, cs.into(), None, Some(miso.into()), None, config)
158 } 160 }
159 161
160 fn new_inner( 162 fn new_inner<T: Instance>(
161 spis: Peri<'d, T>, 163 _spis: Peri<'d, T>,
162 cs: Peri<'d, AnyPin>, 164 cs: Peri<'d, AnyPin>,
163 sck: Option<Peri<'d, AnyPin>>, 165 sck: Option<Peri<'d, AnyPin>>,
164 miso: Option<Peri<'d, AnyPin>>, 166 miso: Option<Peri<'d, AnyPin>>,
@@ -191,10 +193,14 @@ impl<'d, T: Instance> Spis<'d, T> {
191 // Enable SPIS instance. 193 // Enable SPIS instance.
192 r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); 194 r.enable().write(|w| w.set_enable(vals::Enable::ENABLED));
193 195
194 let mut spis = Self { _p: spis }; 196 let mut spis = Self {
197 r: T::regs(),
198 state: T::state(),
199 _p: PhantomData,
200 };
195 201
196 // Apply runtime peripheral configuration 202 // Apply runtime peripheral configuration
197 Self::set_config(&mut spis, &config).unwrap(); 203 spis.set_config(&config).unwrap();
198 204
199 // Disable all events interrupts. 205 // Disable all events interrupts.
200 r.intenclr().write(|w| w.0 = 0xFFFF_FFFF); 206 r.intenclr().write(|w| w.0 = 0xFFFF_FFFF);
@@ -212,7 +218,7 @@ impl<'d, T: Instance> Spis<'d, T> {
212 218
213 compiler_fence(Ordering::SeqCst); 219 compiler_fence(Ordering::SeqCst);
214 220
215 let r = T::regs(); 221 let r = self.r;
216 222
217 // Set up the DMA write. 223 // Set up the DMA write.
218 if tx.len() > EASY_DMA_SIZE { 224 if tx.len() > EASY_DMA_SIZE {
@@ -239,7 +245,7 @@ impl<'d, T: Instance> Spis<'d, T> {
239 245
240 fn blocking_inner_from_ram(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(usize, usize), Error> { 246 fn blocking_inner_from_ram(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(usize, usize), Error> {
241 compiler_fence(Ordering::SeqCst); 247 compiler_fence(Ordering::SeqCst);
242 let r = T::regs(); 248 let r = self.r;
243 249
244 // Acquire semaphore. 250 // Acquire semaphore.
245 if r.semstat().read().0 != 1 { 251 if r.semstat().read().0 != 1 {
@@ -276,8 +282,8 @@ impl<'d, T: Instance> Spis<'d, T> {
276 } 282 }
277 283
278 async fn async_inner_from_ram(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(usize, usize), Error> { 284 async fn async_inner_from_ram(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(usize, usize), Error> {
279 let r = T::regs(); 285 let r = self.r;
280 let s = T::state(); 286 let s = self.state;
281 287
282 // Clear status register. 288 // Clear status register.
283 r.status().write(|w| { 289 r.status().write(|w| {
@@ -420,21 +426,21 @@ impl<'d, T: Instance> Spis<'d, T> {
420 426
421 /// Checks if last transaction overread. 427 /// Checks if last transaction overread.
422 pub fn is_overread(&mut self) -> bool { 428 pub fn is_overread(&mut self) -> bool {
423 T::regs().status().read().overread() 429 self.r.status().read().overread()
424 } 430 }
425 431
426 /// Checks if last transaction overflowed. 432 /// Checks if last transaction overflowed.
427 pub fn is_overflow(&mut self) -> bool { 433 pub fn is_overflow(&mut self) -> bool {
428 T::regs().status().read().overflow() 434 self.r.status().read().overflow()
429 } 435 }
430} 436}
431 437
432impl<'d, T: Instance> Drop for Spis<'d, T> { 438impl<'d> Drop for Spis<'d> {
433 fn drop(&mut self) { 439 fn drop(&mut self) {
434 trace!("spis drop"); 440 trace!("spis drop");
435 441
436 // Disable 442 // Disable
437 let r = T::regs(); 443 let r = self.r;
438 r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); 444 r.enable().write(|w| w.set_enable(vals::Enable::DISABLED));
439 445
440 gpio::deconfigure_pin(r.psel().sck().read()); 446 gpio::deconfigure_pin(r.psel().sck().read());
@@ -489,11 +495,11 @@ macro_rules! impl_spis {
489 495
490// ==================== 496// ====================
491 497
492impl<'d, T: Instance> SetConfig for Spis<'d, T> { 498impl<'d> SetConfig for Spis<'d> {
493 type Config = Config; 499 type Config = Config;
494 type ConfigError = (); 500 type ConfigError = ();
495 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { 501 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
496 let r = T::regs(); 502 let r = self.r;
497 // Configure mode. 503 // Configure mode.
498 let mode = config.mode; 504 let mode = config.mode;
499 r.config().write(|w| { 505 r.config().write(|w| {