aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-03-05 22:12:34 +0100
committerDario Nieuwenhuis <[email protected]>2023-03-06 00:17:51 +0100
commit9e58d9274c63ebe48217e94162e47bea3211ff1c (patch)
tree6d0bf21662bde1ed0d913fed9a8a21c7ea7bd6e8
parent9f5762d3654464011b5ddda771d4866c547106a0 (diff)
nrf/twim: switch to new interrupt binding.
-rw-r--r--embassy-nrf/src/twim.rs47
-rw-r--r--examples/nrf52840/src/bin/twim.rs9
-rw-r--r--examples/nrf52840/src/bin/twim_lowpower.rs9
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
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;
@@ -15,7 +16,7 @@ use embassy_time::{Duration, Instant};
15 16
16use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; 17use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
17use crate::gpio::Pin as GpioPin; 18use crate::gpio::Pin as GpioPin;
18use crate::interrupt::{Interrupt, InterruptExt}; 19use crate::interrupt::{self, Interrupt, InterruptExt};
19use crate::util::{slice_in_ram, slice_in_ram_or}; 20use crate::util::{slice_in_ram, slice_in_ram_or};
20use crate::{gpio, pac, Peripheral}; 21use crate::{gpio, pac, Peripheral};
21 22
@@ -92,6 +93,27 @@ pub enum Error {
92 Timeout, 93 Timeout,
93} 94}
94 95
96/// Interrupt handler.
97pub struct InterruptHandler<T: Instance> {
98 _phantom: PhantomData<T>,
99}
100
101impl<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.
96pub struct Twim<'d, T: Instance> { 118pub 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
9use defmt::*; 9use defmt::*;
10use embassy_executor::Spawner; 10use embassy_executor::Spawner;
11use embassy_nrf::interrupt;
12use embassy_nrf::twim::{self, Twim}; 11use embassy_nrf::twim::{self, Twim};
12use embassy_nrf::{bind_interrupts, peripherals};
13use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
14 14
15const ADDRESS: u8 = 0x50; 15const ADDRESS: u8 = 0x50;
16 16
17bind_interrupts!(struct Irqs {
18 SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler<peripherals::TWISPI0>;
19});
20
17#[embassy_executor::main] 21#[embassy_executor::main]
18async fn main(_spawner: Spawner) { 22async 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
13use defmt::*; 13use defmt::*;
14use embassy_executor::Spawner; 14use embassy_executor::Spawner;
15use embassy_nrf::interrupt;
16use embassy_nrf::twim::{self, Twim}; 15use embassy_nrf::twim::{self, Twim};
16use embassy_nrf::{bind_interrupts, peripherals};
17use embassy_time::{Duration, Timer}; 17use embassy_time::{Duration, Timer};
18use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
19 19
20const ADDRESS: u8 = 0x50; 20const ADDRESS: u8 = 0x50;
21 21
22bind_interrupts!(struct Irqs {
23 SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler<peripherals::TWISPI0>;
24});
25
22#[embassy_executor::main] 26#[embassy_executor::main]
23async fn main(_p: Spawner) { 27async 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