aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-03-05 21:37:21 +0100
committerDario Nieuwenhuis <[email protected]>2023-03-06 00:17:51 +0100
commit96788ac93a1e98ef8d9d5e8d80d5102aef34d45d (patch)
tree0c8f5a4bc0364f6abfa5de47bae59ca4978cbf54 /embassy-nrf
parentc66b28e759dc42c5f802336385a66eb8a82dab9a (diff)
nrf/qspi: switch to new interrupt binding.
Diffstat (limited to 'embassy-nrf')
-rw-r--r--embassy-nrf/src/qspi.rs65
1 files changed, 35 insertions, 30 deletions
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index d514e0274..7f004b9fc 100644
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.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::ptr; 7use core::ptr;
7use core::task::Poll; 8use core::task::Poll;
8 9
@@ -11,12 +12,12 @@ use embassy_hal_common::{into_ref, PeripheralRef};
11use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; 12use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
12 13
13use crate::gpio::{self, Pin as GpioPin}; 14use crate::gpio::{self, Pin as GpioPin};
14use crate::interrupt::{Interrupt, InterruptExt}; 15use crate::interrupt::{self, Interrupt, InterruptExt};
15pub use crate::pac::qspi::ifconfig0::{ 16pub use crate::pac::qspi::ifconfig0::{
16 ADDRMODE_A as AddressMode, PPSIZE_A as WritePageSize, READOC_A as ReadOpcode, WRITEOC_A as WriteOpcode, 17 ADDRMODE_A as AddressMode, PPSIZE_A as WritePageSize, READOC_A as ReadOpcode, WRITEOC_A as WriteOpcode,
17}; 18};
18pub use crate::pac::qspi::ifconfig1::SPIMODE_A as SpiMode; 19pub use crate::pac::qspi::ifconfig1::SPIMODE_A as SpiMode;
19use crate::{pac, Peripheral}; 20use crate::Peripheral;
20 21
21/// Deep power-down config. 22/// Deep power-down config.
22pub struct DeepPowerDownConfig { 23pub struct DeepPowerDownConfig {
@@ -114,9 +115,26 @@ pub enum Error {
114 // TODO add "not in data memory" error and check for it 115 // TODO add "not in data memory" error and check for it
115} 116}
116 117
118/// Interrupt handler.
119pub struct InterruptHandler<T: Instance> {
120 _phantom: PhantomData<T>,
121}
122
123impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> {
124 unsafe fn on_interrupt() {
125 let r = T::regs();
126 let s = T::state();
127
128 if r.events_ready.read().bits() != 0 {
129 s.waker.wake();
130 r.intenclr.write(|w| w.ready().clear());
131 }
132 }
133}
134
117/// QSPI flash driver. 135/// QSPI flash driver.
118pub struct Qspi<'d, T: Instance> { 136pub struct Qspi<'d, T: Instance> {
119 irq: PeripheralRef<'d, T::Interrupt>, 137 _peri: PeripheralRef<'d, T>,
120 dpm_enabled: bool, 138 dpm_enabled: bool,
121 capacity: u32, 139 capacity: u32,
122} 140}
@@ -124,8 +142,8 @@ pub struct Qspi<'d, T: Instance> {
124impl<'d, T: Instance> Qspi<'d, T> { 142impl<'d, T: Instance> Qspi<'d, T> {
125 /// Create a new QSPI driver. 143 /// Create a new QSPI driver.
126 pub fn new( 144 pub fn new(
127 _qspi: impl Peripheral<P = T> + 'd, 145 qspi: impl Peripheral<P = T> + 'd,
128 irq: impl Peripheral<P = T::Interrupt> + 'd, 146 _irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
129 sck: impl Peripheral<P = impl GpioPin> + 'd, 147 sck: impl Peripheral<P = impl GpioPin> + 'd,
130 csn: impl Peripheral<P = impl GpioPin> + 'd, 148 csn: impl Peripheral<P = impl GpioPin> + 'd,
131 io0: impl Peripheral<P = impl GpioPin> + 'd, 149 io0: impl Peripheral<P = impl GpioPin> + 'd,
@@ -134,7 +152,7 @@ impl<'d, T: Instance> Qspi<'d, T> {
134 io3: impl Peripheral<P = impl GpioPin> + 'd, 152 io3: impl Peripheral<P = impl GpioPin> + 'd,
135 config: Config, 153 config: Config,
136 ) -> Self { 154 ) -> Self {
137 into_ref!(irq, sck, csn, io0, io1, io2, io3); 155 into_ref!(qspi, sck, csn, io0, io1, io2, io3);
138 156
139 let r = T::regs(); 157 let r = T::regs();
140 158
@@ -189,16 +207,15 @@ impl<'d, T: Instance> Qspi<'d, T> {
189 w 207 w
190 }); 208 });
191 209
192 irq.set_handler(Self::on_interrupt); 210 unsafe { T::Interrupt::steal() }.unpend();
193 irq.unpend(); 211 unsafe { T::Interrupt::steal() }.enable();
194 irq.enable();
195 212
196 // Enable it 213 // Enable it
197 r.enable.write(|w| w.enable().enabled()); 214 r.enable.write(|w| w.enable().enabled());
198 215
199 let res = Self { 216 let res = Self {
217 _peri: qspi,
200 dpm_enabled: config.deep_power_down.is_some(), 218 dpm_enabled: config.deep_power_down.is_some(),
201 irq,
202 capacity: config.capacity, 219 capacity: config.capacity,
203 }; 220 };
204 221
@@ -212,16 +229,6 @@ impl<'d, T: Instance> Qspi<'d, T> {
212 res 229 res
213 } 230 }
214 231
215 fn on_interrupt(_: *mut ()) {
216 let r = T::regs();
217 let s = T::state();
218
219 if r.events_ready.read().bits() != 0 {
220 s.ready_waker.wake();
221 r.intenclr.write(|w| w.ready().clear());
222 }
223 }
224
225 /// Do a custom QSPI instruction. 232 /// Do a custom QSPI instruction.
226 pub async fn custom_instruction(&mut self, opcode: u8, req: &[u8], resp: &mut [u8]) -> Result<(), Error> { 233 pub async fn custom_instruction(&mut self, opcode: u8, req: &[u8], resp: &mut [u8]) -> Result<(), Error> {
227 let ondrop = OnDrop::new(Self::blocking_wait_ready); 234 let ondrop = OnDrop::new(Self::blocking_wait_ready);
@@ -310,7 +317,7 @@ impl<'d, T: Instance> Qspi<'d, T> {
310 poll_fn(move |cx| { 317 poll_fn(move |cx| {
311 let r = T::regs(); 318 let r = T::regs();
312 let s = T::state(); 319 let s = T::state();
313 s.ready_waker.register(cx.waker()); 320 s.waker.register(cx.waker());
314 if r.events_ready.read().bits() != 0 { 321 if r.events_ready.read().bits() != 0 {
315 return Poll::Ready(()); 322 return Poll::Ready(());
316 } 323 }
@@ -525,8 +532,6 @@ impl<'d, T: Instance> Drop for Qspi<'d, T> {
525 532
526 r.enable.write(|w| w.enable().disabled()); 533 r.enable.write(|w| w.enable().disabled());
527 534
528 self.irq.disable();
529
530 // Note: we do NOT deconfigure CSN here. If DPM is in use and we disconnect CSN, 535 // Note: we do NOT deconfigure CSN here. If DPM is in use and we disconnect CSN,
531 // leaving it floating, the flash chip might read it as zero which would cause it to 536 // leaving it floating, the flash chip might read it as zero which would cause it to
532 // spuriously exit DPM. 537 // spuriously exit DPM.
@@ -624,27 +629,27 @@ mod _eh1 {
624pub(crate) mod sealed { 629pub(crate) mod sealed {
625 use embassy_sync::waitqueue::AtomicWaker; 630 use embassy_sync::waitqueue::AtomicWaker;
626 631
627 use super::*; 632 /// Peripheral static state
628
629 pub struct State { 633 pub struct State {
630 pub ready_waker: AtomicWaker, 634 pub waker: AtomicWaker,
631 } 635 }
636
632 impl State { 637 impl State {
633 pub const fn new() -> Self { 638 pub const fn new() -> Self {
634 Self { 639 Self {
635 ready_waker: AtomicWaker::new(), 640 waker: AtomicWaker::new(),
636 } 641 }
637 } 642 }
638 } 643 }
639 644
640 pub trait Instance { 645 pub trait Instance {
641 fn regs() -> &'static pac::qspi::RegisterBlock; 646 fn regs() -> &'static crate::pac::qspi::RegisterBlock;
642 fn state() -> &'static State; 647 fn state() -> &'static State;
643 } 648 }
644} 649}
645 650
646/// QSPI peripheral instance. 651/// QSPI peripheral instance.
647pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static { 652pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
648 /// Interrupt for this peripheral. 653 /// Interrupt for this peripheral.
649 type Interrupt: Interrupt; 654 type Interrupt: Interrupt;
650} 655}
@@ -652,7 +657,7 @@ pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
652macro_rules! impl_qspi { 657macro_rules! impl_qspi {
653 ($type:ident, $pac_type:ident, $irq:ident) => { 658 ($type:ident, $pac_type:ident, $irq:ident) => {
654 impl crate::qspi::sealed::Instance for peripherals::$type { 659 impl crate::qspi::sealed::Instance for peripherals::$type {
655 fn regs() -> &'static pac::qspi::RegisterBlock { 660 fn regs() -> &'static crate::pac::qspi::RegisterBlock {
656 unsafe { &*pac::$pac_type::ptr() } 661 unsafe { &*pac::$pac_type::ptr() }
657 } 662 }
658 fn state() -> &'static crate::qspi::sealed::State { 663 fn state() -> &'static crate::qspi::sealed::State {