diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-03-05 22:12:34 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-03-06 00:17:51 +0100 |
| commit | 9e58d9274c63ebe48217e94162e47bea3211ff1c (patch) | |
| tree | 6d0bf21662bde1ed0d913fed9a8a21c7ea7bd6e8 | |
| parent | 9f5762d3654464011b5ddda771d4866c547106a0 (diff) | |
nrf/twim: switch to new interrupt binding.
| -rw-r--r-- | embassy-nrf/src/twim.rs | 47 | ||||
| -rw-r--r-- | examples/nrf52840/src/bin/twim.rs | 9 | ||||
| -rw-r--r-- | 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 0dcb2b0da..ef4c929a3 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | #![macro_use] | 3 | #![macro_use] |
| 4 | 4 | ||
| 5 | use core::future::{poll_fn, Future}; | 5 | use core::future::{poll_fn, Future}; |
| 6 | use core::marker::PhantomData; | ||
| 6 | use core::sync::atomic::compiler_fence; | 7 | use core::sync::atomic::compiler_fence; |
| 7 | use core::sync::atomic::Ordering::SeqCst; | 8 | use core::sync::atomic::Ordering::SeqCst; |
| 8 | use core::task::Poll; | 9 | use core::task::Poll; |
| @@ -15,7 +16,7 @@ use embassy_time::{Duration, Instant}; | |||
| 15 | 16 | ||
| 16 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 17 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 17 | use crate::gpio::Pin as GpioPin; | 18 | use crate::gpio::Pin as GpioPin; |
| 18 | use crate::interrupt::{Interrupt, InterruptExt}; | 19 | use crate::interrupt::{self, Interrupt, InterruptExt}; |
| 19 | use crate::util::{slice_in_ram, slice_in_ram_or}; | 20 | use crate::util::{slice_in_ram, slice_in_ram_or}; |
| 20 | use crate::{gpio, pac, Peripheral}; | 21 | use crate::{gpio, pac, Peripheral}; |
| 21 | 22 | ||
| @@ -92,6 +93,27 @@ pub enum Error { | |||
| 92 | Timeout, | 93 | Timeout, |
| 93 | } | 94 | } |
| 94 | 95 | ||
| 96 | /// Interrupt handler. | ||
| 97 | pub struct InterruptHandler<T: Instance> { | ||
| 98 | _phantom: PhantomData<T>, | ||
| 99 | } | ||
| 100 | |||
| 101 | impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { | ||
| 102 | unsafe fn on_interrupt() { | ||
| 103 | let r = T::regs(); | ||
| 104 | let s = T::state(); | ||
| 105 | |||
| 106 | if r.events_stopped.read().bits() != 0 { | ||
| 107 | s.end_waker.wake(); | ||
| 108 | r.intenclr.write(|w| w.stopped().clear()); | ||
| 109 | } | ||
| 110 | if r.events_error.read().bits() != 0 { | ||
| 111 | s.end_waker.wake(); | ||
| 112 | r.intenclr.write(|w| w.error().clear()); | ||
| 113 | } | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 95 | /// TWI driver. | 117 | /// TWI driver. |
| 96 | pub struct Twim<'d, T: Instance> { | 118 | pub struct Twim<'d, T: Instance> { |
| 97 | _p: PeripheralRef<'d, T>, | 119 | _p: PeripheralRef<'d, T>, |
| @@ -101,12 +123,12 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 101 | /// Create a new TWI driver. | 123 | /// Create a new TWI driver. |
| 102 | pub fn new( | 124 | pub fn new( |
| 103 | twim: impl Peripheral<P = T> + 'd, | 125 | twim: impl Peripheral<P = T> + 'd, |
| 104 | irq: impl Peripheral<P = T::Interrupt> + 'd, | 126 | _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 105 | sda: impl Peripheral<P = impl GpioPin> + 'd, | 127 | sda: impl Peripheral<P = impl GpioPin> + 'd, |
| 106 | scl: impl Peripheral<P = impl GpioPin> + 'd, | 128 | scl: impl Peripheral<P = impl GpioPin> + 'd, |
| 107 | config: Config, | 129 | config: Config, |
| 108 | ) -> Self { | 130 | ) -> Self { |
| 109 | into_ref!(twim, irq, sda, scl); | 131 | into_ref!(twim, sda, scl); |
| 110 | 132 | ||
| 111 | let r = T::regs(); | 133 | let r = T::regs(); |
| 112 | 134 | ||
| @@ -152,27 +174,12 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 152 | // Disable all events interrupts | 174 | // Disable all events interrupts |
| 153 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); | 175 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); |
| 154 | 176 | ||
| 155 | irq.set_handler(Self::on_interrupt); | 177 | unsafe { T::Interrupt::steal() }.unpend(); |
| 156 | irq.unpend(); | 178 | unsafe { T::Interrupt::steal() }.enable(); |
| 157 | irq.enable(); | ||
| 158 | 179 | ||
| 159 | Self { _p: twim } | 180 | Self { _p: twim } |
| 160 | } | 181 | } |
| 161 | 182 | ||
| 162 | fn on_interrupt(_: *mut ()) { | ||
| 163 | let r = T::regs(); | ||
| 164 | let s = T::state(); | ||
| 165 | |||
| 166 | if r.events_stopped.read().bits() != 0 { | ||
| 167 | s.end_waker.wake(); | ||
| 168 | r.intenclr.write(|w| w.stopped().clear()); | ||
| 169 | } | ||
| 170 | if r.events_error.read().bits() != 0 { | ||
| 171 | s.end_waker.wake(); | ||
| 172 | r.intenclr.write(|w| w.error().clear()); | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | /// Set TX buffer, checking that it is in RAM and has suitable length. | 183 | /// Set TX buffer, checking that it is in RAM and has suitable length. |
| 177 | unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> { | 184 | unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 178 | slice_in_ram_or(buffer, Error::BufferNotInRAM)?; | 185 | slice_in_ram_or(buffer, Error::BufferNotInRAM)?; |
diff --git a/examples/nrf52840/src/bin/twim.rs b/examples/nrf52840/src/bin/twim.rs index a027cc1e7..959e3a4be 100644 --- a/examples/nrf52840/src/bin/twim.rs +++ b/examples/nrf52840/src/bin/twim.rs | |||
| @@ -8,19 +8,22 @@ | |||
| 8 | 8 | ||
| 9 | use defmt::*; | 9 | use defmt::*; |
| 10 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
| 11 | use embassy_nrf::interrupt; | ||
| 12 | use embassy_nrf::twim::{self, Twim}; | 11 | use embassy_nrf::twim::{self, Twim}; |
| 12 | use embassy_nrf::{bind_interrupts, peripherals}; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| 15 | const ADDRESS: u8 = 0x50; | 15 | const ADDRESS: u8 = 0x50; |
| 16 | 16 | ||
| 17 | bind_interrupts!(struct Irqs { | ||
| 18 | SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler<peripherals::TWISPI0>; | ||
| 19 | }); | ||
| 20 | |||
| 17 | #[embassy_executor::main] | 21 | #[embassy_executor::main] |
| 18 | async fn main(_spawner: Spawner) { | 22 | async fn main(_spawner: Spawner) { |
| 19 | let p = embassy_nrf::init(Default::default()); | 23 | let p = embassy_nrf::init(Default::default()); |
| 20 | info!("Initializing TWI..."); | 24 | info!("Initializing TWI..."); |
| 21 | let config = twim::Config::default(); | 25 | let config = twim::Config::default(); |
| 22 | let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | 26 | let mut twi = Twim::new(p.TWISPI0, Irqs, p.P0_03, p.P0_04, config); |
| 23 | let mut twi = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config); | ||
| 24 | 27 | ||
| 25 | info!("Reading..."); | 28 | info!("Reading..."); |
| 26 | 29 | ||
diff --git a/examples/nrf52840/src/bin/twim_lowpower.rs b/examples/nrf52840/src/bin/twim_lowpower.rs index e30cc9688..0970d3c3c 100644 --- a/examples/nrf52840/src/bin/twim_lowpower.rs +++ b/examples/nrf52840/src/bin/twim_lowpower.rs | |||
| @@ -12,25 +12,28 @@ use core::mem; | |||
| 12 | 12 | ||
| 13 | use defmt::*; | 13 | use defmt::*; |
| 14 | use embassy_executor::Spawner; | 14 | use embassy_executor::Spawner; |
| 15 | use embassy_nrf::interrupt; | ||
| 16 | use embassy_nrf::twim::{self, Twim}; | 15 | use embassy_nrf::twim::{self, Twim}; |
| 16 | use embassy_nrf::{bind_interrupts, peripherals}; | ||
| 17 | use embassy_time::{Duration, Timer}; | 17 | use embassy_time::{Duration, Timer}; |
| 18 | use {defmt_rtt as _, panic_probe as _}; | 18 | use {defmt_rtt as _, panic_probe as _}; |
| 19 | 19 | ||
| 20 | const ADDRESS: u8 = 0x50; | 20 | const ADDRESS: u8 = 0x50; |
| 21 | 21 | ||
| 22 | bind_interrupts!(struct Irqs { | ||
| 23 | SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler<peripherals::TWISPI0>; | ||
| 24 | }); | ||
| 25 | |||
| 22 | #[embassy_executor::main] | 26 | #[embassy_executor::main] |
| 23 | async fn main(_p: Spawner) { | 27 | async fn main(_p: Spawner) { |
| 24 | let mut p = embassy_nrf::init(Default::default()); | 28 | let mut p = embassy_nrf::init(Default::default()); |
| 25 | info!("Started!"); | 29 | info!("Started!"); |
| 26 | let mut irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 27 | 30 | ||
| 28 | loop { | 31 | loop { |
| 29 | info!("Initializing TWI..."); | 32 | info!("Initializing TWI..."); |
| 30 | let config = twim::Config::default(); | 33 | let config = twim::Config::default(); |
| 31 | 34 | ||
| 32 | // Create the TWIM instance with borrowed singletons, so they're not consumed. | 35 | // Create the TWIM instance with borrowed singletons, so they're not consumed. |
| 33 | let mut twi = Twim::new(&mut p.TWISPI0, &mut irq, &mut p.P0_03, &mut p.P0_04, config); | 36 | let mut twi = Twim::new(&mut p.TWISPI0, Irqs, &mut p.P0_03, &mut p.P0_04, config); |
| 34 | 37 | ||
| 35 | info!("Reading..."); | 38 | info!("Reading..."); |
| 36 | 39 | ||
