From a32e82029a8b6944ef3e9861b09095bae01b37a3 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 5 Mar 2023 22:00:52 +0100 Subject: [PATCH] nrf/spim: switch to new interrupt binding. --- embassy-nrf/src/spim.rs | 59 +++++++++++--------- examples/nrf52840/src/bin/lora_p2p_report.rs | 9 ++- examples/nrf52840/src/bin/lora_p2p_sense.rs | 9 ++- examples/nrf52840/src/bin/spim.rs | 9 ++- 4 files changed, 50 insertions(+), 36 deletions(-) diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index 17e43578..89cbdfee 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs @@ -3,6 +3,7 @@ #![macro_use] use core::future::poll_fn; +use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; @@ -14,7 +15,7 @@ pub use pac::spim0::frequency::FREQUENCY_A as Frequency; use crate::chip::FORCE_COPY_BUFFER_SIZE; use crate::gpio::sealed::Pin as _; use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; -use crate::interrupt::{Interrupt, InterruptExt}; +use crate::interrupt::{self, Interrupt, InterruptExt}; use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut}; use crate::{pac, Peripheral}; @@ -31,11 +32,6 @@ pub enum Error { BufferNotInRAM, } -/// SPIM driver. -pub struct Spim<'d, T: Instance> { - _p: PeripheralRef<'d, T>, -} - /// SPIM configuration. #[non_exhaustive] pub struct Config { @@ -62,11 +58,33 @@ impl Default for Config { } } +/// Interrupt handler. +pub struct InterruptHandler { + _phantom: PhantomData, +} + +impl interrupt::Handler for InterruptHandler { + unsafe fn on_interrupt() { + let r = T::regs(); + let s = T::state(); + + if r.events_end.read().bits() != 0 { + s.end_waker.wake(); + r.intenclr.write(|w| w.end().clear()); + } + } +} + +/// SPIM driver. +pub struct Spim<'d, T: Instance> { + _p: PeripheralRef<'d, T>, +} + impl<'d, T: Instance> Spim<'d, T> { /// Create a new SPIM driver. pub fn new( spim: impl Peripheral

+ 'd, - irq: impl Peripheral

+ 'd, + _irq: impl interrupt::Binding> + 'd, sck: impl Peripheral

+ 'd, miso: impl Peripheral

+ 'd, mosi: impl Peripheral

+ 'd, @@ -75,7 +93,6 @@ impl<'d, T: Instance> Spim<'d, T> { into_ref!(sck, miso, mosi); Self::new_inner( spim, - irq, sck.map_into(), Some(miso.map_into()), Some(mosi.map_into()), @@ -86,36 +103,35 @@ impl<'d, T: Instance> Spim<'d, T> { /// Create a new SPIM driver, capable of TX only (MOSI only). pub fn new_txonly( spim: impl Peripheral

+ 'd, - irq: impl Peripheral

+ 'd, + _irq: impl interrupt::Binding> + 'd, sck: impl Peripheral

+ 'd, mosi: impl Peripheral

+ 'd, config: Config, ) -> Self { into_ref!(sck, mosi); - Self::new_inner(spim, irq, sck.map_into(), None, Some(mosi.map_into()), config) + Self::new_inner(spim, sck.map_into(), None, Some(mosi.map_into()), config) } /// Create a new SPIM driver, capable of RX only (MISO only). pub fn new_rxonly( spim: impl Peripheral

+ 'd, - irq: impl Peripheral

+ 'd, + _irq: impl interrupt::Binding> + 'd, sck: impl Peripheral

+ 'd, miso: impl Peripheral

+ 'd, config: Config, ) -> Self { into_ref!(sck, miso); - Self::new_inner(spim, irq, sck.map_into(), Some(miso.map_into()), None, config) + Self::new_inner(spim, sck.map_into(), Some(miso.map_into()), None, config) } fn new_inner( spim: impl Peripheral

+ 'd, - irq: impl Peripheral

+ 'd, sck: PeripheralRef<'d, AnyPin>, miso: Option>, mosi: Option>, config: Config, ) -> Self { - into_ref!(spim, irq); + into_ref!(spim); let r = T::regs(); @@ -191,23 +207,12 @@ impl<'d, T: Instance> Spim<'d, T> { // Disable all events interrupts r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - irq.set_handler(Self::on_interrupt); - irq.unpend(); - irq.enable(); + unsafe { T::Interrupt::steal() }.unpend(); + unsafe { T::Interrupt::steal() }.enable(); Self { _p: spim } } - fn on_interrupt(_: *mut ()) { - let r = T::regs(); - let s = T::state(); - - if r.events_end.read().bits() != 0 { - s.end_waker.wake(); - r.intenclr.write(|w| w.end().clear()); - } - } - fn prepare(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> { slice_in_ram_or(tx, Error::BufferNotInRAM)?; // NOTE: RAM slice check for rx is not necessary, as a mutable diff --git a/examples/nrf52840/src/bin/lora_p2p_report.rs b/examples/nrf52840/src/bin/lora_p2p_report.rs index d512b83f..e24f0db0 100644 --- a/examples/nrf52840/src/bin/lora_p2p_report.rs +++ b/examples/nrf52840/src/bin/lora_p2p_report.rs @@ -11,11 +11,15 @@ use defmt::*; use embassy_executor::Spawner; use embassy_lora::sx126x::*; use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; -use embassy_nrf::{interrupt, spim}; +use embassy_nrf::{bind_interrupts, peripherals, spim}; use embassy_time::{Duration, Timer}; use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor}; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!(struct Irqs { + SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1 => spim::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_nrf::init(Default::default()); @@ -23,8 +27,7 @@ async fn main(_spawner: Spawner) { spi_config.frequency = spim::Frequency::M16; let mut radio = { - let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); - let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config); + let spim = spim::Spim::new(p.TWISPI1, Irqs, p.P1_11, p.P1_13, p.P1_12, spi_config); let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard); let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard); diff --git a/examples/nrf52840/src/bin/lora_p2p_sense.rs b/examples/nrf52840/src/bin/lora_p2p_sense.rs index b9768874..b6f41ffc 100644 --- a/examples/nrf52840/src/bin/lora_p2p_sense.rs +++ b/examples/nrf52840/src/bin/lora_p2p_sense.rs @@ -12,13 +12,17 @@ use defmt::*; use embassy_executor::Spawner; use embassy_lora::sx126x::*; use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; -use embassy_nrf::{interrupt, spim}; +use embassy_nrf::{bind_interrupts, peripherals, spim}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::pubsub::{PubSubChannel, Publisher}; use embassy_time::{Duration, Timer}; use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor, TxConfig}; use {defmt_rtt as _, panic_probe as _, panic_probe as _}; +bind_interrupts!(struct Irqs { + SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1 => spim::InterruptHandler; +}); + // Message bus: queue of 2, 1 subscriber (Lora P2P), 2 publishers (temperature, motion detection) static MESSAGE_BUS: PubSubChannel = PubSubChannel::new(); @@ -58,8 +62,7 @@ async fn main(spawner: Spawner) { spi_config.frequency = spim::Frequency::M16; let mut radio = { - let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); - let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config); + let spim = spim::Spim::new(p.TWISPI1, Irqs, p.P1_11, p.P1_13, p.P1_12, spi_config); let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard); let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard); diff --git a/examples/nrf52840/src/bin/spim.rs b/examples/nrf52840/src/bin/spim.rs index 132e0166..9d1843a8 100644 --- a/examples/nrf52840/src/bin/spim.rs +++ b/examples/nrf52840/src/bin/spim.rs @@ -5,9 +5,13 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_nrf::gpio::{Level, Output, OutputDrive}; -use embassy_nrf::{interrupt, spim}; +use embassy_nrf::{bind_interrupts, peripherals, spim}; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!(struct Irqs { + SPIM3 => spim::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_nrf::init(Default::default()); @@ -16,8 +20,7 @@ async fn main(_spawner: Spawner) { let mut config = spim::Config::default(); config.frequency = spim::Frequency::M16; - let irq = interrupt::take!(SPIM3); - let mut spim = spim::Spim::new(p.SPI3, irq, p.P0_29, p.P0_28, p.P0_30, config); + let mut spim = spim::Spim::new(p.SPI3, Irqs, p.P0_29, p.P0_28, p.P0_30, config); let mut ncs = Output::new(p.P0_31, Level::High, OutputDrive::Standard);