diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-03-05 22:00:52 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-03-06 00:17:51 +0100 |
| commit | a32e82029a8b6944ef3e9861b09095bae01b37a3 (patch) | |
| tree | 09cd2afd71cbf8163c302a5c1f36df22e07b032f /embassy-nrf | |
| parent | 2dc56082033f650083355464c3106ccb57302338 (diff) | |
nrf/spim: switch to new interrupt binding.
Diffstat (limited to 'embassy-nrf')
| -rw-r--r-- | embassy-nrf/src/spim.rs | 59 |
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 | ||
| 5 | use core::future::poll_fn; | 5 | use core::future::poll_fn; |
| 6 | use core::marker::PhantomData; | ||
| 6 | use core::sync::atomic::{compiler_fence, Ordering}; | 7 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 7 | use core::task::Poll; | 8 | use core::task::Poll; |
| 8 | 9 | ||
| @@ -14,7 +15,7 @@ pub use pac::spim0::frequency::FREQUENCY_A as Frequency; | |||
| 14 | use crate::chip::FORCE_COPY_BUFFER_SIZE; | 15 | use crate::chip::FORCE_COPY_BUFFER_SIZE; |
| 15 | use crate::gpio::sealed::Pin as _; | 16 | use crate::gpio::sealed::Pin as _; |
| 16 | use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; | 17 | use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; |
| 17 | use crate::interrupt::{Interrupt, InterruptExt}; | 18 | use crate::interrupt::{self, Interrupt, InterruptExt}; |
| 18 | use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut}; | 19 | use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut}; |
| 19 | use crate::{pac, Peripheral}; | 20 | use crate::{pac, Peripheral}; |
| 20 | 21 | ||
| @@ -31,11 +32,6 @@ pub enum Error { | |||
| 31 | BufferNotInRAM, | 32 | BufferNotInRAM, |
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | /// SPIM driver. | ||
| 35 | pub struct Spim<'d, T: Instance> { | ||
| 36 | _p: PeripheralRef<'d, T>, | ||
| 37 | } | ||
| 38 | |||
| 39 | /// SPIM configuration. | 35 | /// SPIM configuration. |
| 40 | #[non_exhaustive] | 36 | #[non_exhaustive] |
| 41 | pub struct Config { | 37 | pub struct Config { |
| @@ -62,11 +58,33 @@ impl Default for Config { | |||
| 62 | } | 58 | } |
| 63 | } | 59 | } |
| 64 | 60 | ||
| 61 | /// Interrupt handler. | ||
| 62 | pub struct InterruptHandler<T: Instance> { | ||
| 63 | _phantom: PhantomData<T>, | ||
| 64 | } | ||
| 65 | |||
| 66 | impl<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. | ||
| 79 | pub struct Spim<'d, T: Instance> { | ||
| 80 | _p: PeripheralRef<'d, T>, | ||
| 81 | } | ||
| 82 | |||
| 65 | impl<'d, T: Instance> Spim<'d, T> { | 83 | impl<'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 |
