diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-03-05 22:14:59 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-03-06 00:17:51 +0100 |
| commit | 5913553cb1e95431665d3370dce8154a6869e434 (patch) | |
| tree | 65bab72b8669c02cb211825136d76f7e820f16a6 | |
| parent | 36319fc121f19f86dded45b6fb93aed7c3f4ae33 (diff) | |
nrf/twis: switch to new interrupt binding.
| -rw-r--r-- | embassy-nrf/src/twis.rs | 55 | ||||
| -rw-r--r-- | examples/nrf52840/src/bin/twis.rs | 12 |
2 files changed, 38 insertions, 29 deletions
diff --git a/embassy-nrf/src/twis.rs b/embassy-nrf/src/twis.rs index c514d9f2f..bfa30b044 100644 --- a/embassy-nrf/src/twis.rs +++ b/embassy-nrf/src/twis.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; |
| @@ -14,7 +15,7 @@ use embassy_time::{Duration, Instant}; | |||
| 14 | 15 | ||
| 15 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 16 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 16 | use crate::gpio::Pin as GpioPin; | 17 | use crate::gpio::Pin as GpioPin; |
| 17 | use crate::interrupt::{Interrupt, InterruptExt}; | 18 | use crate::interrupt::{self, Interrupt, InterruptExt}; |
| 18 | use crate::util::slice_in_ram_or; | 19 | use crate::util::slice_in_ram_or; |
| 19 | use crate::{gpio, pac, Peripheral}; | 20 | use crate::{gpio, pac, Peripheral}; |
| 20 | 21 | ||
| @@ -108,6 +109,31 @@ pub enum Command { | |||
| 108 | Write(usize), | 109 | Write(usize), |
| 109 | } | 110 | } |
| 110 | 111 | ||
| 112 | /// Interrupt handler. | ||
| 113 | pub struct InterruptHandler<T: Instance> { | ||
| 114 | _phantom: PhantomData<T>, | ||
| 115 | } | ||
| 116 | |||
| 117 | impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { | ||
| 118 | unsafe fn on_interrupt() { | ||
| 119 | let r = T::regs(); | ||
| 120 | let s = T::state(); | ||
| 121 | |||
| 122 | if r.events_read.read().bits() != 0 || r.events_write.read().bits() != 0 { | ||
| 123 | s.waker.wake(); | ||
| 124 | r.intenclr.modify(|_r, w| w.read().clear().write().clear()); | ||
| 125 | } | ||
| 126 | if r.events_stopped.read().bits() != 0 { | ||
| 127 | s.waker.wake(); | ||
| 128 | r.intenclr.modify(|_r, w| w.stopped().clear()); | ||
| 129 | } | ||
| 130 | if r.events_error.read().bits() != 0 { | ||
| 131 | s.waker.wake(); | ||
| 132 | r.intenclr.modify(|_r, w| w.error().clear()); | ||
| 133 | } | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 111 | /// TWIS driver. | 137 | /// TWIS driver. |
| 112 | pub struct Twis<'d, T: Instance> { | 138 | pub struct Twis<'d, T: Instance> { |
| 113 | _p: PeripheralRef<'d, T>, | 139 | _p: PeripheralRef<'d, T>, |
| @@ -117,12 +143,12 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 117 | /// Create a new TWIS driver. | 143 | /// Create a new TWIS driver. |
| 118 | pub fn new( | 144 | pub fn new( |
| 119 | twis: impl Peripheral<P = T> + 'd, | 145 | twis: impl Peripheral<P = T> + 'd, |
| 120 | irq: impl Peripheral<P = T::Interrupt> + 'd, | 146 | _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 121 | sda: impl Peripheral<P = impl GpioPin> + 'd, | 147 | sda: impl Peripheral<P = impl GpioPin> + 'd, |
| 122 | scl: impl Peripheral<P = impl GpioPin> + 'd, | 148 | scl: impl Peripheral<P = impl GpioPin> + 'd, |
| 123 | config: Config, | 149 | config: Config, |
| 124 | ) -> Self { | 150 | ) -> Self { |
| 125 | into_ref!(twis, irq, sda, scl); | 151 | into_ref!(twis, sda, scl); |
| 126 | 152 | ||
| 127 | let r = T::regs(); | 153 | let r = T::regs(); |
| 128 | 154 | ||
| @@ -178,31 +204,12 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 178 | // Generate suspend on read event | 204 | // Generate suspend on read event |
| 179 | r.shorts.write(|w| w.read_suspend().enabled()); | 205 | r.shorts.write(|w| w.read_suspend().enabled()); |
| 180 | 206 | ||
| 181 | irq.set_handler(Self::on_interrupt); | 207 | unsafe { T::Interrupt::steal() }.unpend(); |
| 182 | irq.unpend(); | 208 | unsafe { T::Interrupt::steal() }.enable(); |
| 183 | irq.enable(); | ||
| 184 | 209 | ||
| 185 | Self { _p: twis } | 210 | Self { _p: twis } |
| 186 | } | 211 | } |
| 187 | 212 | ||
| 188 | fn on_interrupt(_: *mut ()) { | ||
| 189 | let r = T::regs(); | ||
| 190 | let s = T::state(); | ||
| 191 | |||
| 192 | if r.events_read.read().bits() != 0 || r.events_write.read().bits() != 0 { | ||
| 193 | s.waker.wake(); | ||
| 194 | r.intenclr.modify(|_r, w| w.read().clear().write().clear()); | ||
| 195 | } | ||
| 196 | if r.events_stopped.read().bits() != 0 { | ||
| 197 | s.waker.wake(); | ||
| 198 | r.intenclr.modify(|_r, w| w.stopped().clear()); | ||
| 199 | } | ||
| 200 | if r.events_error.read().bits() != 0 { | ||
| 201 | s.waker.wake(); | ||
| 202 | r.intenclr.modify(|_r, w| w.error().clear()); | ||
| 203 | } | ||
| 204 | } | ||
| 205 | |||
| 206 | /// Set TX buffer, checking that it is in RAM and has suitable length. | 213 | /// Set TX buffer, checking that it is in RAM and has suitable length. |
| 207 | unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> { | 214 | unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 208 | slice_in_ram_or(buffer, Error::BufferNotInRAM)?; | 215 | slice_in_ram_or(buffer, Error::BufferNotInRAM)?; |
diff --git a/examples/nrf52840/src/bin/twis.rs b/examples/nrf52840/src/bin/twis.rs index 54cba9494..aa42b679e 100644 --- a/examples/nrf52840/src/bin/twis.rs +++ b/examples/nrf52840/src/bin/twis.rs | |||
| @@ -6,19 +6,21 @@ | |||
| 6 | 6 | ||
| 7 | use defmt::*; | 7 | use defmt::*; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_nrf::interrupt; | ||
| 10 | use embassy_nrf::twis::{self, Command, Twis}; | 9 | use embassy_nrf::twis::{self, Command, Twis}; |
| 10 | use embassy_nrf::{bind_interrupts, peripherals}; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | 11 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 12 | ||
| 13 | bind_interrupts!(struct Irqs { | ||
| 14 | SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twis::InterruptHandler<peripherals::TWISPI0>; | ||
| 15 | }); | ||
| 16 | |||
| 13 | #[embassy_executor::main] | 17 | #[embassy_executor::main] |
| 14 | async fn main(_spawner: Spawner) { | 18 | async fn main(_spawner: Spawner) { |
| 15 | let p = embassy_nrf::init(Default::default()); | 19 | let p = embassy_nrf::init(Default::default()); |
| 16 | 20 | ||
| 17 | let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); | ||
| 18 | let mut config = twis::Config::default(); | 21 | let mut config = twis::Config::default(); |
| 19 | // Set i2c address | 22 | config.address0 = 0x55; // Set i2c address |
| 20 | config.address0 = 0x55; | 23 | let mut i2c = Twis::new(p.TWISPI0, Irqs, p.P0_03, p.P0_04, config); |
| 21 | let mut i2c = Twis::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config); | ||
| 22 | 24 | ||
| 23 | info!("Listening..."); | 25 | info!("Listening..."); |
| 24 | loop { | 26 | loop { |
