aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-03-05 22:14:59 +0100
committerDario Nieuwenhuis <[email protected]>2023-03-06 00:17:51 +0100
commit5913553cb1e95431665d3370dce8154a6869e434 (patch)
tree65bab72b8669c02cb211825136d76f7e820f16a6
parent36319fc121f19f86dded45b6fb93aed7c3f4ae33 (diff)
nrf/twis: switch to new interrupt binding.
-rw-r--r--embassy-nrf/src/twis.rs55
-rw-r--r--examples/nrf52840/src/bin/twis.rs12
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
5use core::future::{poll_fn, Future}; 5use core::future::{poll_fn, Future};
6use core::marker::PhantomData;
6use core::sync::atomic::compiler_fence; 7use core::sync::atomic::compiler_fence;
7use core::sync::atomic::Ordering::SeqCst; 8use core::sync::atomic::Ordering::SeqCst;
8use core::task::Poll; 9use core::task::Poll;
@@ -14,7 +15,7 @@ use embassy_time::{Duration, Instant};
14 15
15use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; 16use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
16use crate::gpio::Pin as GpioPin; 17use crate::gpio::Pin as GpioPin;
17use crate::interrupt::{Interrupt, InterruptExt}; 18use crate::interrupt::{self, Interrupt, InterruptExt};
18use crate::util::slice_in_ram_or; 19use crate::util::slice_in_ram_or;
19use crate::{gpio, pac, Peripheral}; 20use 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.
113pub struct InterruptHandler<T: Instance> {
114 _phantom: PhantomData<T>,
115}
116
117impl<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.
112pub struct Twis<'d, T: Instance> { 138pub 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
7use defmt::*; 7use defmt::*;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_nrf::interrupt;
10use embassy_nrf::twis::{self, Command, Twis}; 9use embassy_nrf::twis::{self, Command, Twis};
10use embassy_nrf::{bind_interrupts, peripherals};
11use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
12 12
13bind_interrupts!(struct Irqs {
14 SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twis::InterruptHandler<peripherals::TWISPI0>;
15});
16
13#[embassy_executor::main] 17#[embassy_executor::main]
14async fn main(_spawner: Spawner) { 18async 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 {