aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf
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 /embassy-nrf
parent2dc56082033f650083355464c3106ccb57302338 (diff)
nrf/spim: switch to new interrupt binding.
Diffstat (limited to 'embassy-nrf')
-rw-r--r--embassy-nrf/src/spim.rs59
1 files changed, 32 insertions, 27 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