From 987009df7bf77dc963e5cff5c3cbdf565839c17c Mon Sep 17 00:00:00 2001 From: Abraham Hamidi Date: Fri, 19 Sep 2025 16:13:34 -0500 Subject: [PATCH] feat(nrf/spim): erase Instance type from Spim --- embassy-nrf/CHANGELOG.md | 1 + embassy-nrf/src/spim.rs | 64 +++++++++++-------- .../nrf52840/src/bin/ethernet_enc28j60.rs | 2 +- examples/nrf52840/src/bin/wifi_esp_hosted.rs | 2 +- tests/nrf/src/bin/ethernet_enc28j60_perf.rs | 2 +- tests/nrf/src/bin/wifi_esp_hosted_perf.rs | 2 +- 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 ## Unreleased - ReleaseDate +- changed: erase Instance type from Spim - changed: nrf54l: Disable glitch detection and enable DC/DC in init. - changed: Add embassy-net-driver-channel implementation for IEEE 802.15.4 - 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 interrupt::typelevel::Handler for InterruptHandl } /// SPIM driver. -pub struct Spim<'d, T: Instance> { - _p: Peri<'d, T>, +pub struct Spim<'d> { + r: pac::spim::Spim, + irq: interrupt::Interrupt, + state: &'static State, + _p: PhantomData<&'d ()>, } -impl<'d, T: Instance> Spim<'d, T> { +impl<'d> Spim<'d> { /// Create a new SPIM driver. - pub fn new( + pub fn new( spim: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, sck: Peri<'d, impl GpioPin>, @@ -117,7 +120,7 @@ impl<'d, T: Instance> Spim<'d, T> { } /// Create a new SPIM driver, capable of TX only (MOSI only). - pub fn new_txonly( + pub fn new_txonly( spim: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, sck: Peri<'d, impl GpioPin>, @@ -128,7 +131,7 @@ impl<'d, T: Instance> Spim<'d, T> { } /// Create a new SPIM driver, capable of RX only (MISO only). - pub fn new_rxonly( + pub fn new_rxonly( spim: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, sck: Peri<'d, impl GpioPin>, @@ -139,7 +142,7 @@ impl<'d, T: Instance> Spim<'d, T> { } /// Create a new SPIM driver, capable of TX only (MOSI only), without SCK pin. - pub fn new_txonly_nosck( + pub fn new_txonly_nosck( spim: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, mosi: Peri<'d, impl GpioPin>, @@ -148,8 +151,8 @@ impl<'d, T: Instance> Spim<'d, T> { Self::new_inner(spim, None, None, Some(mosi.into()), config) } - fn new_inner( - spim: Peri<'d, T>, + fn new_inner( + _spim: Peri<'d, T>, sck: Option>, miso: Option>, mosi: Option>, @@ -201,7 +204,12 @@ impl<'d, T: Instance> Spim<'d, T> { // Enable SPIM instance. r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); - let mut spim = Self { _p: spim }; + let mut spim = Self { + r: T::regs(), + irq: T::Interrupt::IRQ, + state: T::state(), + _p: PhantomData {}, + }; // Apply runtime peripheral configuration Self::set_config(&mut spim, &config).unwrap(); @@ -218,7 +226,7 @@ impl<'d, T: Instance> Spim<'d, T> { fn prepare_dma_transfer(&mut self, rx: *mut [u8], tx: *const [u8], offset: usize, length: usize) { compiler_fence(Ordering::SeqCst); - let r = T::regs(); + let r = self.r; fn xfer_params(ptr: u32, total: usize, offset: usize, length: usize) -> (u32, usize) { if total > offset { @@ -246,7 +254,7 @@ impl<'d, T: Instance> Spim<'d, T> { #[cfg(feature = "_nrf52832_anomaly_109")] if offset == 0 { - let s = T::state(); + let s = self.state; r.events_started().write_value(0); @@ -279,7 +287,7 @@ impl<'d, T: Instance> Spim<'d, T> { } // Wait for 'end' event. - while T::regs().events_end().read() == 0 {} + while self.r.events_end().read() == 0 {} compiler_fence(Ordering::SeqCst); } @@ -315,7 +323,7 @@ impl<'d, T: Instance> Spim<'d, T> { #[cfg(feature = "_nrf52832_anomaly_109")] if offset == 0 { poll_fn(|cx| { - let s = T::state(); + let s = self.state; s.waker.register(cx.waker()); @@ -326,8 +334,8 @@ impl<'d, T: Instance> Spim<'d, T> { // Wait for 'end' event. poll_fn(|cx| { - T::state().waker.register(cx.waker()); - if T::regs().events_end().read() != 0 { + self.state.waker.register(cx.waker()); + if self.r.events_end().read() != 0 { return Poll::Ready(()); } @@ -430,9 +438,9 @@ impl<'d, T: Instance> Spim<'d, T> { #[cfg(feature = "_nrf52832_anomaly_109")] fn nrf52832_dma_workaround_status(&mut self) -> Poll<()> { - let r = T::regs(); + let r = self.r; if r.events_started().read() != 0 { - let s = T::state(); + let s = self.state; // Handle the first "fake" transmission r.events_started().write_value(0); @@ -451,14 +459,14 @@ impl<'d, T: Instance> Spim<'d, T> { } } -impl<'d, T: Instance> Drop for Spim<'d, T> { +impl<'d> Drop for Spim<'d> { fn drop(&mut self) { trace!("spim drop"); // TODO check for abort, wait for xxxstopped // disable! - let r = T::regs(); + let r = self.r; r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); gpio::deconfigure_pin(r.psel().sck().read()); @@ -466,7 +474,7 @@ impl<'d, T: Instance> Drop for Spim<'d, T> { gpio::deconfigure_pin(r.psel().mosi().read()); // Disable all events interrupts - T::Interrupt::disable(); + cortex_m::peripheral::NVIC::mask(self.irq); trace!("spim drop: done"); } @@ -526,7 +534,7 @@ macro_rules! impl_spim { mod eh02 { use super::*; - impl<'d, T: Instance> embedded_hal_02::blocking::spi::Transfer for Spim<'d, T> { + impl<'d> embedded_hal_02::blocking::spi::Transfer for Spim<'d> { type Error = Error; fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { self.blocking_transfer_in_place(words)?; @@ -534,7 +542,7 @@ mod eh02 { } } - impl<'d, T: Instance> embedded_hal_02::blocking::spi::Write for Spim<'d, T> { + impl<'d> embedded_hal_02::blocking::spi::Write for Spim<'d> { type Error = Error; fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { @@ -551,11 +559,11 @@ impl embedded_hal_1::spi::Error for Error { } } -impl<'d, T: Instance> embedded_hal_1::spi::ErrorType for Spim<'d, T> { +impl<'d> embedded_hal_1::spi::ErrorType for Spim<'d> { type Error = Error; } -impl<'d, T: Instance> embedded_hal_1::spi::SpiBus for Spim<'d, T> { +impl<'d> embedded_hal_1::spi::SpiBus for Spim<'d> { fn flush(&mut self) -> Result<(), Self::Error> { Ok(()) } @@ -577,7 +585,7 @@ impl<'d, T: Instance> embedded_hal_1::spi::SpiBus for Spim<'d, T> { } } -impl<'d, T: Instance> embedded_hal_async::spi::SpiBus for Spim<'d, T> { +impl<'d> embedded_hal_async::spi::SpiBus for Spim<'d> { async fn flush(&mut self) -> Result<(), Error> { Ok(()) } @@ -599,11 +607,11 @@ impl<'d, T: Instance> embedded_hal_async::spi::SpiBus for Spim<'d, T> { } } -impl<'d, T: Instance> SetConfig for Spim<'d, T> { +impl<'d> SetConfig for Spim<'d> { type Config = Config; type ConfigError = (); fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { - let r = T::regs(); + let r = self.r; // Configure mode. let mode = config.mode; 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 { async fn net_task( mut runner: embassy_net::Runner< 'static, - Enc28j60, Output<'static>, Delay>, Output<'static>>, + Enc28j60, Output<'static>, Delay>, Output<'static>>, >, ) -> ! { 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 { async fn wifi_task( runner: hosted::Runner< 'static, - ExclusiveDevice, Output<'static>, Delay>, + ExclusiveDevice, Output<'static>, Delay>, Input<'static>, Output<'static>, >, 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 { RNG => embassy_nrf::rng::InterruptHandler; }); -type MyDriver = Enc28j60, Output<'static>, Delay>, Output<'static>>; +type MyDriver = Enc28j60, Output<'static>, Delay>, Output<'static>>; #[embassy_executor::task] async 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"; async fn wifi_task( runner: hosted::Runner< 'static, - ExclusiveDevice, Output<'static>, Delay>, + ExclusiveDevice, Output<'static>, Delay>, Input<'static>, Output<'static>, >,