aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-03-05 22:00:52 +0100
committerDario Nieuwenhuis <[email protected]>2023-03-06 00:17:51 +0100
commita32e82029a8b6944ef3e9861b09095bae01b37a3 (patch)
tree09cd2afd71cbf8163c302a5c1f36df22e07b032f
parent2dc56082033f650083355464c3106ccb57302338 (diff)
nrf/spim: switch to new interrupt binding.
-rw-r--r--embassy-nrf/src/spim.rs59
-rw-r--r--examples/nrf52840/src/bin/lora_p2p_report.rs9
-rw-r--r--examples/nrf52840/src/bin/lora_p2p_sense.rs9
-rw-r--r--examples/nrf52840/src/bin/spim.rs9
4 files changed, 50 insertions, 36 deletions
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs
index 17e435787..89cbdfee9 100644
--- a/embassy-nrf/src/spim.rs
+++ b/embassy-nrf/src/spim.rs
@@ -3,6 +3,7 @@
3#![macro_use] 3#![macro_use]
4 4
5use core::future::poll_fn; 5use core::future::poll_fn;
6use core::marker::PhantomData;
6use core::sync::atomic::{compiler_fence, Ordering}; 7use core::sync::atomic::{compiler_fence, Ordering};
7use core::task::Poll; 8use core::task::Poll;
8 9
@@ -14,7 +15,7 @@ pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
14use crate::chip::FORCE_COPY_BUFFER_SIZE; 15use crate::chip::FORCE_COPY_BUFFER_SIZE;
15use crate::gpio::sealed::Pin as _; 16use crate::gpio::sealed::Pin as _;
16use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; 17use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
17use crate::interrupt::{Interrupt, InterruptExt}; 18use crate::interrupt::{self, Interrupt, InterruptExt};
18use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut}; 19use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut};
19use crate::{pac, Peripheral}; 20use crate::{pac, Peripheral};
20 21
@@ -31,11 +32,6 @@ pub enum Error {
31 BufferNotInRAM, 32 BufferNotInRAM,
32} 33}
33 34
34/// SPIM driver.
35pub struct Spim<'d, T: Instance> {
36 _p: PeripheralRef<'d, T>,
37}
38
39/// SPIM configuration. 35/// SPIM configuration.
40#[non_exhaustive] 36#[non_exhaustive]
41pub struct Config { 37pub struct Config {
@@ -62,11 +58,33 @@ impl Default for Config {
62 } 58 }
63} 59}
64 60
61/// Interrupt handler.
62pub struct InterruptHandler<T: Instance> {
63 _phantom: PhantomData<T>,
64}
65
66impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> {
67 unsafe fn on_interrupt() {
68 let r = T::regs();
69 let s = T::state();
70
71 if r.events_end.read().bits() != 0 {
72 s.end_waker.wake();
73 r.intenclr.write(|w| w.end().clear());
74 }
75 }
76}
77
78/// SPIM driver.
79pub struct Spim<'d, T: Instance> {
80 _p: PeripheralRef<'d, T>,
81}
82
65impl<'d, T: Instance> Spim<'d, T> { 83impl<'d, T: Instance> Spim<'d, T> {
66 /// Create a new SPIM driver. 84 /// Create a new SPIM driver.
67 pub fn new( 85 pub fn new(
68 spim: impl Peripheral<P = T> + 'd, 86 spim: impl Peripheral<P = T> + 'd,
69 irq: impl Peripheral<P = T::Interrupt> + 'd, 87 _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
70 sck: impl Peripheral<P = impl GpioPin> + 'd, 88 sck: impl Peripheral<P = impl GpioPin> + 'd,
71 miso: impl Peripheral<P = impl GpioPin> + 'd, 89 miso: impl Peripheral<P = impl GpioPin> + 'd,
72 mosi: impl Peripheral<P = impl GpioPin> + 'd, 90 mosi: impl Peripheral<P = impl GpioPin> + 'd,
@@ -75,7 +93,6 @@ impl<'d, T: Instance> Spim<'d, T> {
75 into_ref!(sck, miso, mosi); 93 into_ref!(sck, miso, mosi);
76 Self::new_inner( 94 Self::new_inner(
77 spim, 95 spim,
78 irq,
79 sck.map_into(), 96 sck.map_into(),
80 Some(miso.map_into()), 97 Some(miso.map_into()),
81 Some(mosi.map_into()), 98 Some(mosi.map_into()),
@@ -86,36 +103,35 @@ impl<'d, T: Instance> Spim<'d, T> {
86 /// Create a new SPIM driver, capable of TX only (MOSI only). 103 /// Create a new SPIM driver, capable of TX only (MOSI only).
87 pub fn new_txonly( 104 pub fn new_txonly(
88 spim: impl Peripheral<P = T> + 'd, 105 spim: impl Peripheral<P = T> + 'd,
89 irq: impl Peripheral<P = T::Interrupt> + 'd, 106 _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
90 sck: impl Peripheral<P = impl GpioPin> + 'd, 107 sck: impl Peripheral<P = impl GpioPin> + 'd,
91 mosi: impl Peripheral<P = impl GpioPin> + 'd, 108 mosi: impl Peripheral<P = impl GpioPin> + 'd,
92 config: Config, 109 config: Config,
93 ) -> Self { 110 ) -> Self {
94 into_ref!(sck, mosi); 111 into_ref!(sck, mosi);
95 Self::new_inner(spim, irq, sck.map_into(), None, Some(mosi.map_into()), config) 112 Self::new_inner(spim, sck.map_into(), None, Some(mosi.map_into()), config)
96 } 113 }
97 114
98 /// Create a new SPIM driver, capable of RX only (MISO only). 115 /// Create a new SPIM driver, capable of RX only (MISO only).
99 pub fn new_rxonly( 116 pub fn new_rxonly(
100 spim: impl Peripheral<P = T> + 'd, 117 spim: impl Peripheral<P = T> + 'd,
101 irq: impl Peripheral<P = T::Interrupt> + 'd, 118 _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
102 sck: impl Peripheral<P = impl GpioPin> + 'd, 119 sck: impl Peripheral<P = impl GpioPin> + 'd,
103 miso: impl Peripheral<P = impl GpioPin> + 'd, 120 miso: impl Peripheral<P = impl GpioPin> + 'd,
104 config: Config, 121 config: Config,
105 ) -> Self { 122 ) -> Self {
106 into_ref!(sck, miso); 123 into_ref!(sck, miso);
107 Self::new_inner(spim, irq, sck.map_into(), Some(miso.map_into()), None, config) 124 Self::new_inner(spim, sck.map_into(), Some(miso.map_into()), None, config)
108 } 125 }
109 126
110 fn new_inner( 127 fn new_inner(
111 spim: impl Peripheral<P = T> + 'd, 128 spim: impl Peripheral<P = T> + 'd,
112 irq: impl Peripheral<P = T::Interrupt> + 'd,
113 sck: PeripheralRef<'d, AnyPin>, 129 sck: PeripheralRef<'d, AnyPin>,
114 miso: Option<PeripheralRef<'d, AnyPin>>, 130 miso: Option<PeripheralRef<'d, AnyPin>>,
115 mosi: Option<PeripheralRef<'d, AnyPin>>, 131 mosi: Option<PeripheralRef<'d, AnyPin>>,
116 config: Config, 132 config: Config,
117 ) -> Self { 133 ) -> Self {
118 into_ref!(spim, irq); 134 into_ref!(spim);
119 135
120 let r = T::regs(); 136 let r = T::regs();
121 137
@@ -191,23 +207,12 @@ impl<'d, T: Instance> Spim<'d, T> {
191 // Disable all events interrupts 207 // Disable all events interrupts
192 r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); 208 r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) });
193 209
194 irq.set_handler(Self::on_interrupt); 210 unsafe { T::Interrupt::steal() }.unpend();
195 irq.unpend(); 211 unsafe { T::Interrupt::steal() }.enable();
196 irq.enable();
197 212
198 Self { _p: spim } 213 Self { _p: spim }
199 } 214 }
200 215
201 fn on_interrupt(_: *mut ()) {
202 let r = T::regs();
203 let s = T::state();
204
205 if r.events_end.read().bits() != 0 {
206 s.end_waker.wake();
207 r.intenclr.write(|w| w.end().clear());
208 }
209 }
210
211 fn prepare(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> { 216 fn prepare(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> {
212 slice_in_ram_or(tx, Error::BufferNotInRAM)?; 217 slice_in_ram_or(tx, Error::BufferNotInRAM)?;
213 // NOTE: RAM slice check for rx is not necessary, as a mutable 218 // NOTE: RAM slice check for rx is not necessary, as a mutable
diff --git a/examples/nrf52840/src/bin/lora_p2p_report.rs b/examples/nrf52840/src/bin/lora_p2p_report.rs
index d512b83f6..e24f0db03 100644
--- a/examples/nrf52840/src/bin/lora_p2p_report.rs
+++ b/examples/nrf52840/src/bin/lora_p2p_report.rs
@@ -11,11 +11,15 @@ use defmt::*;
11use embassy_executor::Spawner; 11use embassy_executor::Spawner;
12use embassy_lora::sx126x::*; 12use embassy_lora::sx126x::*;
13use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; 13use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull};
14use embassy_nrf::{interrupt, spim}; 14use embassy_nrf::{bind_interrupts, peripherals, spim};
15use embassy_time::{Duration, Timer}; 15use embassy_time::{Duration, Timer};
16use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor}; 16use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor};
17use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
18 18
19bind_interrupts!(struct Irqs {
20 SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1 => spim::InterruptHandler<peripherals::TWISPI1>;
21});
22
19#[embassy_executor::main] 23#[embassy_executor::main]
20async fn main(_spawner: Spawner) { 24async fn main(_spawner: Spawner) {
21 let p = embassy_nrf::init(Default::default()); 25 let p = embassy_nrf::init(Default::default());
@@ -23,8 +27,7 @@ async fn main(_spawner: Spawner) {
23 spi_config.frequency = spim::Frequency::M16; 27 spi_config.frequency = spim::Frequency::M16;
24 28
25 let mut radio = { 29 let mut radio = {
26 let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); 30 let spim = spim::Spim::new(p.TWISPI1, Irqs, p.P1_11, p.P1_13, p.P1_12, spi_config);
27 let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config);
28 31
29 let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard); 32 let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard);
30 let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard); 33 let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard);
diff --git a/examples/nrf52840/src/bin/lora_p2p_sense.rs b/examples/nrf52840/src/bin/lora_p2p_sense.rs
index b9768874b..b6f41ffcc 100644
--- a/examples/nrf52840/src/bin/lora_p2p_sense.rs
+++ b/examples/nrf52840/src/bin/lora_p2p_sense.rs
@@ -12,13 +12,17 @@ use defmt::*;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_lora::sx126x::*; 13use embassy_lora::sx126x::*;
14use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; 14use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull};
15use embassy_nrf::{interrupt, spim}; 15use embassy_nrf::{bind_interrupts, peripherals, spim};
16use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 16use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
17use embassy_sync::pubsub::{PubSubChannel, Publisher}; 17use embassy_sync::pubsub::{PubSubChannel, Publisher};
18use embassy_time::{Duration, Timer}; 18use embassy_time::{Duration, Timer};
19use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor, TxConfig}; 19use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor, TxConfig};
20use {defmt_rtt as _, panic_probe as _, panic_probe as _}; 20use {defmt_rtt as _, panic_probe as _, panic_probe as _};
21 21
22bind_interrupts!(struct Irqs {
23 SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1 => spim::InterruptHandler<peripherals::TWISPI1>;
24});
25
22// Message bus: queue of 2, 1 subscriber (Lora P2P), 2 publishers (temperature, motion detection) 26// Message bus: queue of 2, 1 subscriber (Lora P2P), 2 publishers (temperature, motion detection)
23static MESSAGE_BUS: PubSubChannel<CriticalSectionRawMutex, Message, 2, 1, 2> = PubSubChannel::new(); 27static MESSAGE_BUS: PubSubChannel<CriticalSectionRawMutex, Message, 2, 1, 2> = PubSubChannel::new();
24 28
@@ -58,8 +62,7 @@ async fn main(spawner: Spawner) {
58 spi_config.frequency = spim::Frequency::M16; 62 spi_config.frequency = spim::Frequency::M16;
59 63
60 let mut radio = { 64 let mut radio = {
61 let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); 65 let spim = spim::Spim::new(p.TWISPI1, Irqs, p.P1_11, p.P1_13, p.P1_12, spi_config);
62 let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config);
63 66
64 let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard); 67 let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard);
65 let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard); 68 let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard);
diff --git a/examples/nrf52840/src/bin/spim.rs b/examples/nrf52840/src/bin/spim.rs
index 132e01660..9d1843a8f 100644
--- a/examples/nrf52840/src/bin/spim.rs
+++ b/examples/nrf52840/src/bin/spim.rs
@@ -5,9 +5,13 @@
5use defmt::{info, unwrap}; 5use defmt::{info, unwrap};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_nrf::gpio::{Level, Output, OutputDrive}; 7use embassy_nrf::gpio::{Level, Output, OutputDrive};
8use embassy_nrf::{interrupt, spim}; 8use embassy_nrf::{bind_interrupts, peripherals, spim};
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
10 10
11bind_interrupts!(struct Irqs {
12 SPIM3 => spim::InterruptHandler<peripherals::SPI3>;
13});
14
11#[embassy_executor::main] 15#[embassy_executor::main]
12async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
13 let p = embassy_nrf::init(Default::default()); 17 let p = embassy_nrf::init(Default::default());
@@ -16,8 +20,7 @@ async fn main(_spawner: Spawner) {
16 let mut config = spim::Config::default(); 20 let mut config = spim::Config::default();
17 config.frequency = spim::Frequency::M16; 21 config.frequency = spim::Frequency::M16;
18 22
19 let irq = interrupt::take!(SPIM3); 23 let mut spim = spim::Spim::new(p.SPI3, Irqs, p.P0_29, p.P0_28, p.P0_30, config);
20 let mut spim = spim::Spim::new(p.SPI3, irq, p.P0_29, p.P0_28, p.P0_30, config);
21 24
22 let mut ncs = Output::new(p.P0_31, Level::High, OutputDrive::Standard); 25 let mut ncs = Output::new(p.P0_31, Level::High, OutputDrive::Standard);
23 26