aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbraham Hamidi <[email protected]>2025-09-19 16:13:34 -0500
committerAbraham Hamidi <[email protected]>2025-09-24 15:58:33 -0500
commit987009df7bf77dc963e5cff5c3cbdf565839c17c (patch)
tree54fdf8e0ff44660052cec5c835ee2a84230ca4c5
parent56019ba197443e16b4f0b3a0fe3ff85985f6e45c (diff)
feat(nrf/spim): erase Instance type from Spim
-rw-r--r--embassy-nrf/CHANGELOG.md1
-rw-r--r--embassy-nrf/src/spim.rs64
-rw-r--r--examples/nrf52840/src/bin/ethernet_enc28j60.rs2
-rw-r--r--examples/nrf52840/src/bin/wifi_esp_hosted.rs2
-rw-r--r--tests/nrf/src/bin/ethernet_enc28j60_perf.rs2
-rw-r--r--tests/nrf/src/bin/wifi_esp_hosted_perf.rs2
6 files changed, 41 insertions, 32 deletions
diff --git a/embassy-nrf/CHANGELOG.md b/embassy-nrf/CHANGELOG.md
index 825d9d713..b8d03a1f8 100644
--- a/embassy-nrf/CHANGELOG.md
+++ b/embassy-nrf/CHANGELOG.md
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8<!-- next-header --> 8<!-- next-header -->
9## Unreleased - ReleaseDate 9## Unreleased - ReleaseDate
10 10
11- changed: erase Instance type from Spim
11- changed: nrf54l: Disable glitch detection and enable DC/DC in init. 12- changed: nrf54l: Disable glitch detection and enable DC/DC in init.
12- changed: Add embassy-net-driver-channel implementation for IEEE 802.15.4 13- changed: Add embassy-net-driver-channel implementation for IEEE 802.15.4
13- changed: add persist() method for gpio and ppi 14- changed: add persist() method for gpio and ppi
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs
index 59f5b6d58..c410e49fd 100644
--- a/embassy-nrf/src/spim.rs
+++ b/embassy-nrf/src/spim.rs
@@ -99,13 +99,16 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
99} 99}
100 100
101/// SPIM driver. 101/// SPIM driver.
102pub struct Spim<'d, T: Instance> { 102pub struct Spim<'d> {
103 _p: Peri<'d, T>, 103 r: pac::spim::Spim,
104 irq: interrupt::Interrupt,
105 state: &'static State,
106 _p: PhantomData<&'d ()>,
104} 107}
105 108
106impl<'d, T: Instance> Spim<'d, T> { 109impl<'d> Spim<'d> {
107 /// Create a new SPIM driver. 110 /// Create a new SPIM driver.
108 pub fn new( 111 pub fn new<T: Instance>(
109 spim: Peri<'d, T>, 112 spim: Peri<'d, T>,
110 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 113 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
111 sck: Peri<'d, impl GpioPin>, 114 sck: Peri<'d, impl GpioPin>,
@@ -117,7 +120,7 @@ impl<'d, T: Instance> Spim<'d, T> {
117 } 120 }
118 121
119 /// Create a new SPIM driver, capable of TX only (MOSI only). 122 /// Create a new SPIM driver, capable of TX only (MOSI only).
120 pub fn new_txonly( 123 pub fn new_txonly<T: Instance>(
121 spim: Peri<'d, T>, 124 spim: Peri<'d, T>,
122 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 125 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
123 sck: Peri<'d, impl GpioPin>, 126 sck: Peri<'d, impl GpioPin>,
@@ -128,7 +131,7 @@ impl<'d, T: Instance> Spim<'d, T> {
128 } 131 }
129 132
130 /// Create a new SPIM driver, capable of RX only (MISO only). 133 /// Create a new SPIM driver, capable of RX only (MISO only).
131 pub fn new_rxonly( 134 pub fn new_rxonly<T: Instance>(
132 spim: Peri<'d, T>, 135 spim: Peri<'d, T>,
133 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 136 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
134 sck: Peri<'d, impl GpioPin>, 137 sck: Peri<'d, impl GpioPin>,
@@ -139,7 +142,7 @@ impl<'d, T: Instance> Spim<'d, T> {
139 } 142 }
140 143
141 /// Create a new SPIM driver, capable of TX only (MOSI only), without SCK pin. 144 /// Create a new SPIM driver, capable of TX only (MOSI only), without SCK pin.
142 pub fn new_txonly_nosck( 145 pub fn new_txonly_nosck<T: Instance>(
143 spim: Peri<'d, T>, 146 spim: Peri<'d, T>,
144 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 147 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
145 mosi: Peri<'d, impl GpioPin>, 148 mosi: Peri<'d, impl GpioPin>,
@@ -148,8 +151,8 @@ impl<'d, T: Instance> Spim<'d, T> {
148 Self::new_inner(spim, None, None, Some(mosi.into()), config) 151 Self::new_inner(spim, None, None, Some(mosi.into()), config)
149 } 152 }
150 153
151 fn new_inner( 154 fn new_inner<T: Instance>(
152 spim: Peri<'d, T>, 155 _spim: Peri<'d, T>,
153 sck: Option<Peri<'d, AnyPin>>, 156 sck: Option<Peri<'d, AnyPin>>,
154 miso: Option<Peri<'d, AnyPin>>, 157 miso: Option<Peri<'d, AnyPin>>,
155 mosi: Option<Peri<'d, AnyPin>>, 158 mosi: Option<Peri<'d, AnyPin>>,
@@ -201,7 +204,12 @@ impl<'d, T: Instance> Spim<'d, T> {
201 // Enable SPIM instance. 204 // Enable SPIM instance.
202 r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); 205 r.enable().write(|w| w.set_enable(vals::Enable::ENABLED));
203 206
204 let mut spim = Self { _p: spim }; 207 let mut spim = Self {
208 r: T::regs(),
209 irq: T::Interrupt::IRQ,
210 state: T::state(),
211 _p: PhantomData {},
212 };
205 213
206 // Apply runtime peripheral configuration 214 // Apply runtime peripheral configuration
207 Self::set_config(&mut spim, &config).unwrap(); 215 Self::set_config(&mut spim, &config).unwrap();
@@ -218,7 +226,7 @@ impl<'d, T: Instance> Spim<'d, T> {
218 fn prepare_dma_transfer(&mut self, rx: *mut [u8], tx: *const [u8], offset: usize, length: usize) { 226 fn prepare_dma_transfer(&mut self, rx: *mut [u8], tx: *const [u8], offset: usize, length: usize) {
219 compiler_fence(Ordering::SeqCst); 227 compiler_fence(Ordering::SeqCst);
220 228
221 let r = T::regs(); 229 let r = self.r;
222 230
223 fn xfer_params(ptr: u32, total: usize, offset: usize, length: usize) -> (u32, usize) { 231 fn xfer_params(ptr: u32, total: usize, offset: usize, length: usize) -> (u32, usize) {
224 if total > offset { 232 if total > offset {
@@ -246,7 +254,7 @@ impl<'d, T: Instance> Spim<'d, T> {
246 254
247 #[cfg(feature = "_nrf52832_anomaly_109")] 255 #[cfg(feature = "_nrf52832_anomaly_109")]
248 if offset == 0 { 256 if offset == 0 {
249 let s = T::state(); 257 let s = self.state;
250 258
251 r.events_started().write_value(0); 259 r.events_started().write_value(0);
252 260
@@ -279,7 +287,7 @@ impl<'d, T: Instance> Spim<'d, T> {
279 } 287 }
280 288
281 // Wait for 'end' event. 289 // Wait for 'end' event.
282 while T::regs().events_end().read() == 0 {} 290 while self.r.events_end().read() == 0 {}
283 291
284 compiler_fence(Ordering::SeqCst); 292 compiler_fence(Ordering::SeqCst);
285 } 293 }
@@ -315,7 +323,7 @@ impl<'d, T: Instance> Spim<'d, T> {
315 #[cfg(feature = "_nrf52832_anomaly_109")] 323 #[cfg(feature = "_nrf52832_anomaly_109")]
316 if offset == 0 { 324 if offset == 0 {
317 poll_fn(|cx| { 325 poll_fn(|cx| {
318 let s = T::state(); 326 let s = self.state;
319 327
320 s.waker.register(cx.waker()); 328 s.waker.register(cx.waker());
321 329
@@ -326,8 +334,8 @@ impl<'d, T: Instance> Spim<'d, T> {
326 334
327 // Wait for 'end' event. 335 // Wait for 'end' event.
328 poll_fn(|cx| { 336 poll_fn(|cx| {
329 T::state().waker.register(cx.waker()); 337 self.state.waker.register(cx.waker());
330 if T::regs().events_end().read() != 0 { 338 if self.r.events_end().read() != 0 {
331 return Poll::Ready(()); 339 return Poll::Ready(());
332 } 340 }
333 341
@@ -430,9 +438,9 @@ impl<'d, T: Instance> Spim<'d, T> {
430 438
431 #[cfg(feature = "_nrf52832_anomaly_109")] 439 #[cfg(feature = "_nrf52832_anomaly_109")]
432 fn nrf52832_dma_workaround_status(&mut self) -> Poll<()> { 440 fn nrf52832_dma_workaround_status(&mut self) -> Poll<()> {
433 let r = T::regs(); 441 let r = self.r;
434 if r.events_started().read() != 0 { 442 if r.events_started().read() != 0 {
435 let s = T::state(); 443 let s = self.state;
436 444
437 // Handle the first "fake" transmission 445 // Handle the first "fake" transmission
438 r.events_started().write_value(0); 446 r.events_started().write_value(0);
@@ -451,14 +459,14 @@ impl<'d, T: Instance> Spim<'d, T> {
451 } 459 }
452} 460}
453 461
454impl<'d, T: Instance> Drop for Spim<'d, T> { 462impl<'d> Drop for Spim<'d> {
455 fn drop(&mut self) { 463 fn drop(&mut self) {
456 trace!("spim drop"); 464 trace!("spim drop");
457 465
458 // TODO check for abort, wait for xxxstopped 466 // TODO check for abort, wait for xxxstopped
459 467
460 // disable! 468 // disable!
461 let r = T::regs(); 469 let r = self.r;
462 r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); 470 r.enable().write(|w| w.set_enable(vals::Enable::DISABLED));
463 471
464 gpio::deconfigure_pin(r.psel().sck().read()); 472 gpio::deconfigure_pin(r.psel().sck().read());
@@ -466,7 +474,7 @@ impl<'d, T: Instance> Drop for Spim<'d, T> {
466 gpio::deconfigure_pin(r.psel().mosi().read()); 474 gpio::deconfigure_pin(r.psel().mosi().read());
467 475
468 // Disable all events interrupts 476 // Disable all events interrupts
469 T::Interrupt::disable(); 477 cortex_m::peripheral::NVIC::mask(self.irq);
470 478
471 trace!("spim drop: done"); 479 trace!("spim drop: done");
472 } 480 }
@@ -526,7 +534,7 @@ macro_rules! impl_spim {
526mod eh02 { 534mod eh02 {
527 use super::*; 535 use super::*;
528 536
529 impl<'d, T: Instance> embedded_hal_02::blocking::spi::Transfer<u8> for Spim<'d, T> { 537 impl<'d> embedded_hal_02::blocking::spi::Transfer<u8> for Spim<'d> {
530 type Error = Error; 538 type Error = Error;
531 fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { 539 fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
532 self.blocking_transfer_in_place(words)?; 540 self.blocking_transfer_in_place(words)?;
@@ -534,7 +542,7 @@ mod eh02 {
534 } 542 }
535 } 543 }
536 544
537 impl<'d, T: Instance> embedded_hal_02::blocking::spi::Write<u8> for Spim<'d, T> { 545 impl<'d> embedded_hal_02::blocking::spi::Write<u8> for Spim<'d> {
538 type Error = Error; 546 type Error = Error;
539 547
540 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { 548 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
@@ -551,11 +559,11 @@ impl embedded_hal_1::spi::Error for Error {
551 } 559 }
552} 560}
553 561
554impl<'d, T: Instance> embedded_hal_1::spi::ErrorType for Spim<'d, T> { 562impl<'d> embedded_hal_1::spi::ErrorType for Spim<'d> {
555 type Error = Error; 563 type Error = Error;
556} 564}
557 565
558impl<'d, T: Instance> embedded_hal_1::spi::SpiBus<u8> for Spim<'d, T> { 566impl<'d> embedded_hal_1::spi::SpiBus<u8> for Spim<'d> {
559 fn flush(&mut self) -> Result<(), Self::Error> { 567 fn flush(&mut self) -> Result<(), Self::Error> {
560 Ok(()) 568 Ok(())
561 } 569 }
@@ -577,7 +585,7 @@ impl<'d, T: Instance> embedded_hal_1::spi::SpiBus<u8> for Spim<'d, T> {
577 } 585 }
578} 586}
579 587
580impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spim<'d, T> { 588impl<'d> embedded_hal_async::spi::SpiBus<u8> for Spim<'d> {
581 async fn flush(&mut self) -> Result<(), Error> { 589 async fn flush(&mut self) -> Result<(), Error> {
582 Ok(()) 590 Ok(())
583 } 591 }
@@ -599,11 +607,11 @@ impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spim<'d, T> {
599 } 607 }
600} 608}
601 609
602impl<'d, T: Instance> SetConfig for Spim<'d, T> { 610impl<'d> SetConfig for Spim<'d> {
603 type Config = Config; 611 type Config = Config;
604 type ConfigError = (); 612 type ConfigError = ();
605 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { 613 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
606 let r = T::regs(); 614 let r = self.r;
607 // Configure mode. 615 // Configure mode.
608 let mode = config.mode; 616 let mode = config.mode;
609 r.config().write(|w| { 617 r.config().write(|w| {
diff --git a/examples/nrf52840/src/bin/ethernet_enc28j60.rs b/examples/nrf52840/src/bin/ethernet_enc28j60.rs
index 3bb255a72..e59afd37f 100644
--- a/examples/nrf52840/src/bin/ethernet_enc28j60.rs
+++ b/examples/nrf52840/src/bin/ethernet_enc28j60.rs
@@ -25,7 +25,7 @@ bind_interrupts!(struct Irqs {
25async fn net_task( 25async fn net_task(
26 mut runner: embassy_net::Runner< 26 mut runner: embassy_net::Runner<
27 'static, 27 'static,
28 Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>, 28 Enc28j60<ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, Output<'static>>,
29 >, 29 >,
30) -> ! { 30) -> ! {
31 runner.run().await 31 runner.run().await
diff --git a/examples/nrf52840/src/bin/wifi_esp_hosted.rs b/examples/nrf52840/src/bin/wifi_esp_hosted.rs
index 2dd9abfaa..1bc35746a 100644
--- a/examples/nrf52840/src/bin/wifi_esp_hosted.rs
+++ b/examples/nrf52840/src/bin/wifi_esp_hosted.rs
@@ -27,7 +27,7 @@ bind_interrupts!(struct Irqs {
27async fn wifi_task( 27async fn wifi_task(
28 runner: hosted::Runner< 28 runner: hosted::Runner<
29 'static, 29 'static,
30 ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, 30 ExclusiveDevice<Spim<'static>, Output<'static>, Delay>,
31 Input<'static>, 31 Input<'static>,
32 Output<'static>, 32 Output<'static>,
33 >, 33 >,
diff --git a/tests/nrf/src/bin/ethernet_enc28j60_perf.rs b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
index 5f3fa1fd3..bd6a2effd 100644
--- a/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
+++ b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
@@ -22,7 +22,7 @@ bind_interrupts!(struct Irqs {
22 RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>; 22 RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>;
23}); 23});
24 24
25type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>; 25type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, Output<'static>>;
26 26
27#[embassy_executor::task] 27#[embassy_executor::task]
28async fn net_task(mut runner: embassy_net::Runner<'static, MyDriver>) -> ! { 28async fn net_task(mut runner: embassy_net::Runner<'static, MyDriver>) -> ! {
diff --git a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
index 34c33a4ad..091a70ce9 100644
--- a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
+++ b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
@@ -29,7 +29,7 @@ const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
29async fn wifi_task( 29async fn wifi_task(
30 runner: hosted::Runner< 30 runner: hosted::Runner<
31 'static, 31 'static,
32 ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, 32 ExclusiveDevice<Spim<'static>, Output<'static>, Delay>,
33 Input<'static>, 33 Input<'static>,
34 Output<'static>, 34 Output<'static>,
35 >, 35 >,