From 9e58d9274c63ebe48217e94162e47bea3211ff1c Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 5 Mar 2023 22:12:34 +0100 Subject: [PATCH] nrf/twim: switch to new interrupt binding. --- embassy-nrf/src/twim.rs | 47 +++++++++++++--------- examples/nrf52840/src/bin/twim.rs | 9 +++-- examples/nrf52840/src/bin/twim_lowpower.rs | 9 +++-- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 0dcb2b0d..ef4c929a 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -3,6 +3,7 @@ #![macro_use] use core::future::{poll_fn, Future}; +use core::marker::PhantomData; use core::sync::atomic::compiler_fence; use core::sync::atomic::Ordering::SeqCst; use core::task::Poll; @@ -15,7 +16,7 @@ use embassy_time::{Duration, Instant}; use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; use crate::gpio::Pin as GpioPin; -use crate::interrupt::{Interrupt, InterruptExt}; +use crate::interrupt::{self, Interrupt, InterruptExt}; use crate::util::{slice_in_ram, slice_in_ram_or}; use crate::{gpio, pac, Peripheral}; @@ -92,6 +93,27 @@ pub enum Error { Timeout, } +/// 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_stopped.read().bits() != 0 { + s.end_waker.wake(); + r.intenclr.write(|w| w.stopped().clear()); + } + if r.events_error.read().bits() != 0 { + s.end_waker.wake(); + r.intenclr.write(|w| w.error().clear()); + } + } +} + /// TWI driver. pub struct Twim<'d, T: Instance> { _p: PeripheralRef<'d, T>, @@ -101,12 +123,12 @@ impl<'d, T: Instance> Twim<'d, T> { /// Create a new TWI driver. pub fn new( twim: impl Peripheral

+ 'd, - irq: impl Peripheral

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

+ 'd, scl: impl Peripheral

+ 'd, config: Config, ) -> Self { - into_ref!(twim, irq, sda, scl); + into_ref!(twim, sda, scl); let r = T::regs(); @@ -152,27 +174,12 @@ impl<'d, T: Instance> Twim<'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: twim } } - fn on_interrupt(_: *mut ()) { - let r = T::regs(); - let s = T::state(); - - if r.events_stopped.read().bits() != 0 { - s.end_waker.wake(); - r.intenclr.write(|w| w.stopped().clear()); - } - if r.events_error.read().bits() != 0 { - s.end_waker.wake(); - r.intenclr.write(|w| w.error().clear()); - } - } - /// Set TX buffer, checking that it is in RAM and has suitable length. unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> { slice_in_ram_or(buffer, Error::BufferNotInRAM)?; diff --git a/examples/nrf52840/src/bin/twim.rs b/examples/nrf52840/src/bin/twim.rs index a027cc1e..959e3a4b 100644 --- a/examples/nrf52840/src/bin/twim.rs +++ b/examples/nrf52840/src/bin/twim.rs @@ -8,19 +8,22 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_nrf::interrupt; use embassy_nrf::twim::{self, Twim}; +use embassy_nrf::{bind_interrupts, peripherals}; use {defmt_rtt as _, panic_probe as _}; const ADDRESS: u8 = 0x50; +bind_interrupts!(struct Irqs { + SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_nrf::init(Default::default()); info!("Initializing TWI..."); let config = twim::Config::default(); - let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); - let mut twi = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config); + let mut twi = Twim::new(p.TWISPI0, Irqs, p.P0_03, p.P0_04, config); info!("Reading..."); diff --git a/examples/nrf52840/src/bin/twim_lowpower.rs b/examples/nrf52840/src/bin/twim_lowpower.rs index e30cc968..0970d3c3 100644 --- a/examples/nrf52840/src/bin/twim_lowpower.rs +++ b/examples/nrf52840/src/bin/twim_lowpower.rs @@ -12,25 +12,28 @@ use core::mem; use defmt::*; use embassy_executor::Spawner; -use embassy_nrf::interrupt; use embassy_nrf::twim::{self, Twim}; +use embassy_nrf::{bind_interrupts, peripherals}; use embassy_time::{Duration, Timer}; use {defmt_rtt as _, panic_probe as _}; const ADDRESS: u8 = 0x50; +bind_interrupts!(struct Irqs { + SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_p: Spawner) { let mut p = embassy_nrf::init(Default::default()); info!("Started!"); - let mut irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); loop { info!("Initializing TWI..."); let config = twim::Config::default(); // Create the TWIM instance with borrowed singletons, so they're not consumed. - let mut twi = Twim::new(&mut p.TWISPI0, &mut irq, &mut p.P0_03, &mut p.P0_04, config); + let mut twi = Twim::new(&mut p.TWISPI0, Irqs, &mut p.P0_03, &mut p.P0_04, config); info!("Reading...");