aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-03-21 20:54:09 +0100
committerDario Nieuwenhuis <[email protected]>2021-03-29 00:58:57 +0200
commitec7309962a8f427732a0c6fc7c29713923b39028 (patch)
treea45096b7309e2660cb8749b5e459f97312896870
parent16bb6fd6ac34646f498424459b8eb6863635b119 (diff)
nrf/qspi: update to new api
-rw-r--r--embassy-nrf-examples/src/bin/qspi.rs49
-rw-r--r--embassy-nrf/src/qspi.rs378
-rw-r--r--embassy-traits/src/flash.rs14
3 files changed, 206 insertions, 235 deletions
diff --git a/embassy-nrf-examples/src/bin/qspi.rs b/embassy-nrf-examples/src/bin/qspi.rs
index 7d8a45f78..a08969881 100644
--- a/embassy-nrf-examples/src/bin/qspi.rs
+++ b/embassy-nrf-examples/src/bin/qspi.rs
@@ -6,12 +6,12 @@
6 6
7#[path = "../example_common.rs"] 7#[path = "../example_common.rs"]
8mod example_common; 8mod example_common;
9use embassy_nrf::peripherals::Peripherals;
9use example_common::*; 10use example_common::*;
10 11
11use cortex_m_rt::entry; 12use cortex_m_rt::entry;
12use defmt::{assert_eq, panic}; 13use defmt::{assert_eq, panic};
13use futures::pin_mut; 14use futures::pin_mut;
14use nrf52840_hal::gpio;
15 15
16use embassy::executor::{task, Executor}; 16use embassy::executor::{task, Executor};
17use embassy::traits::flash::Flash; 17use embassy::traits::flash::Flash;
@@ -27,43 +27,16 @@ struct AlignedBuf([u8; 4096]);
27 27
28#[task] 28#[task]
29async fn run() { 29async fn run() {
30 let p = unwrap!(embassy_nrf::pac::Peripherals::take()); 30 let p = unsafe { Peripherals::steal() };
31 31
32 let port0 = gpio::p0::Parts::new(p.P0); 32 let csn = p.p0_17;
33 33 let sck = p.p0_19;
34 let pins = qspi::Pins { 34 let io0 = p.p0_20;
35 csn: port0 35 let io1 = p.p0_21;
36 .p0_17 36 let io2 = p.p0_22;
37 .into_push_pull_output(gpio::Level::High) 37 let io3 = p.p0_23;
38 .degrade(),
39 sck: port0
40 .p0_19
41 .into_push_pull_output(gpio::Level::High)
42 .degrade(),
43 io0: port0
44 .p0_20
45 .into_push_pull_output(gpio::Level::High)
46 .degrade(),
47 io1: port0
48 .p0_21
49 .into_push_pull_output(gpio::Level::High)
50 .degrade(),
51 io2: Some(
52 port0
53 .p0_22
54 .into_push_pull_output(gpio::Level::High)
55 .degrade(),
56 ),
57 io3: Some(
58 port0
59 .p0_23
60 .into_push_pull_output(gpio::Level::High)
61 .degrade(),
62 ),
63 };
64 38
65 let config = qspi::Config { 39 let config = qspi::Config {
66 pins,
67 read_opcode: qspi::ReadOpcode::READ4IO, 40 read_opcode: qspi::ReadOpcode::READ4IO,
68 write_opcode: qspi::WriteOpcode::PP4IO, 41 write_opcode: qspi::WriteOpcode::PP4IO,
69 xip_offset: 0, 42 xip_offset: 0,
@@ -72,7 +45,7 @@ async fn run() {
72 }; 45 };
73 46
74 let irq = interrupt::take!(QSPI); 47 let irq = interrupt::take!(QSPI);
75 let q = qspi::Qspi::new(p.QSPI, irq, config); 48 let q = qspi::Qspi::new(p.qspi, irq, sck, csn, io0, io1, io2, io3, config);
76 pin_mut!(q); 49 pin_mut!(q);
77 50
78 let mut id = [1; 3]; 51 let mut id = [1; 3];
@@ -83,7 +56,7 @@ async fn run() {
83 info!("id: {}", id); 56 info!("id: {}", id);
84 57
85 // Read status register 58 // Read status register
86 let mut status = [0; 1]; 59 let mut status = [4; 1];
87 q.as_mut() 60 q.as_mut()
88 .custom_instruction(0x05, &[], &mut status) 61 .custom_instruction(0x05, &[], &mut status)
89 .await 62 .await
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index 026660cba..39428c62c 100644
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.rs
@@ -1,13 +1,15 @@
1use core::future::Future; 1use core::future::Future;
2use core::marker::PhantomData;
2use core::pin::Pin; 3use core::pin::Pin;
3use core::task::Poll; 4use core::task::Poll;
4 5
6use embassy::interrupt::Interrupt;
5use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; 7use embassy_extras::peripheral::{PeripheralMutex, PeripheralState};
6 8
7use crate::fmt::{assert, assert_eq, *}; 9use crate::fmt::{assert, assert_eq, *};
8use crate::hal::gpio::{Output, Pin as GpioPin, PushPull}; 10use crate::gpio::Pin as GpioPin;
9use crate::interrupt::{self}; 11use crate::interrupt::{self};
10use crate::pac::QSPI; 12use crate::{pac, peripherals};
11 13
12pub use crate::pac::qspi::ifconfig0::ADDRMODE_A as AddressMode; 14pub use crate::pac::qspi::ifconfig0::ADDRMODE_A as AddressMode;
13pub use crate::pac::qspi::ifconfig0::PPSIZE_A as WritePageSize; 15pub use crate::pac::qspi::ifconfig0::PPSIZE_A as WritePageSize;
@@ -25,25 +27,15 @@ pub use crate::pac::qspi::ifconfig0::WRITEOC_A as WriteOpcode;
25// - set gpio in high drive 27// - set gpio in high drive
26 28
27use embassy::traits::flash::{Error, Flash}; 29use embassy::traits::flash::{Error, Flash};
28use embassy::util::{DropBomb, WakerRegistration}; 30use embassy::util::{wake_on_interrupt, DropBomb, PeripheralBorrow, WakerRegistration};
29use futures::future::poll_fn; 31use futures::future::poll_fn;
30 32
31pub struct Pins {
32 pub sck: GpioPin<Output<PushPull>>,
33 pub csn: GpioPin<Output<PushPull>>,
34 pub io0: GpioPin<Output<PushPull>>,
35 pub io1: GpioPin<Output<PushPull>>,
36 pub io2: Option<GpioPin<Output<PushPull>>>,
37 pub io3: Option<GpioPin<Output<PushPull>>>,
38}
39
40pub struct DeepPowerDownConfig { 33pub struct DeepPowerDownConfig {
41 pub enter_time: u16, 34 pub enter_time: u16,
42 pub exit_time: u16, 35 pub exit_time: u16,
43} 36}
44 37
45pub struct Config { 38pub struct Config {
46 pub pins: Pins,
47 pub xip_offset: u32, 39 pub xip_offset: u32,
48 pub read_opcode: ReadOpcode, 40 pub read_opcode: ReadOpcode,
49 pub write_opcode: WriteOpcode, 41 pub write_opcode: WriteOpcode,
@@ -51,55 +43,54 @@ pub struct Config {
51 pub deep_power_down: Option<DeepPowerDownConfig>, 43 pub deep_power_down: Option<DeepPowerDownConfig>,
52} 44}
53 45
54struct State { 46pub struct Qspi<'d, T: Instance> {
55 inner: QSPI, 47 qspi: T,
56 waker: WakerRegistration, 48 irq: T::Interrupt,
49 phantom: PhantomData<&'d mut T>,
57} 50}
58 51
59pub struct Qspi { 52impl<'d, T: Instance> Qspi<'d, T> {
60 inner: PeripheralMutex<State>, 53 pub fn new(
61} 54 qspi: impl PeripheralBorrow<Target = T> + 'd,
55 irq: impl PeripheralBorrow<Target = T::Interrupt> + 'd,
56 sck: impl PeripheralBorrow<Target = impl GpioPin> + 'd,
57 csn: impl PeripheralBorrow<Target = impl GpioPin> + 'd,
58 io0: impl PeripheralBorrow<Target = impl GpioPin> + 'd,
59 io1: impl PeripheralBorrow<Target = impl GpioPin> + 'd,
60 io2: impl PeripheralBorrow<Target = impl GpioPin> + 'd,
61 io3: impl PeripheralBorrow<Target = impl GpioPin> + 'd,
62 config: Config,
63 ) -> Self {
64 let mut qspi = unsafe { qspi.unborrow() };
65 let irq = unsafe { irq.unborrow() };
66 let sck = unsafe { sck.unborrow() };
67 let csn = unsafe { csn.unborrow() };
68 let io0 = unsafe { io0.unborrow() };
69 let io1 = unsafe { io1.unborrow() };
70 let io2 = unsafe { io2.unborrow() };
71 let io3 = unsafe { io3.unborrow() };
72
73 let r = qspi.regs();
74
75 for cnf in &[
76 sck.conf(),
77 csn.conf(),
78 io0.conf(),
79 io1.conf(),
80 io2.conf(),
81 io3.conf(),
82 ] {
83 cnf.write(|w| w.dir().output().drive().h0h1());
84 }
62 85
63impl Qspi { 86 r.psel.sck.write(|w| unsafe { w.bits(sck.psel_bits()) });
64 pub fn new(qspi: QSPI, irq: interrupt::QSPI, config: Config) -> Self { 87 r.psel.csn.write(|w| unsafe { w.bits(csn.psel_bits()) });
65 qspi.psel.sck.write(|w| { 88 r.psel.io0.write(|w| unsafe { w.bits(io0.psel_bits()) });
66 let pin = &config.pins.sck; 89 r.psel.io1.write(|w| unsafe { w.bits(io1.psel_bits()) });
67 unsafe { w.bits(pin.psel_bits()) }; 90 r.psel.io2.write(|w| unsafe { w.bits(io2.psel_bits()) });
68 w.connect().connected() 91 r.psel.io3.write(|w| unsafe { w.bits(io3.psel_bits()) });
69 });
70 qspi.psel.csn.write(|w| {
71 let pin = &config.pins.csn;
72 unsafe { w.bits(pin.psel_bits()) };
73 w.connect().connected()
74 });
75 qspi.psel.io0.write(|w| {
76 let pin = &config.pins.io0;
77 unsafe { w.bits(pin.psel_bits()) };
78 w.connect().connected()
79 });
80 qspi.psel.io1.write(|w| {
81 let pin = &config.pins.io1;
82 unsafe { w.bits(pin.psel_bits()) };
83 w.connect().connected()
84 });
85 qspi.psel.io2.write(|w| {
86 if let Some(ref pin) = config.pins.io2 {
87 unsafe { w.bits(pin.psel_bits()) };
88 w.connect().connected()
89 } else {
90 w.connect().disconnected()
91 }
92 });
93 qspi.psel.io3.write(|w| {
94 if let Some(ref pin) = config.pins.io3 {
95 unsafe { w.bits(pin.psel_bits()) };
96 w.connect().connected()
97 } else {
98 w.connect().disconnected()
99 }
100 });
101 92
102 qspi.ifconfig0.write(|mut w| { 93 r.ifconfig0.write(|mut w| {
103 w = w.addrmode().variant(AddressMode::_24BIT); 94 w = w.addrmode().variant(AddressMode::_24BIT);
104 if config.deep_power_down.is_some() { 95 if config.deep_power_down.is_some() {
105 w = w.dpmenable().enable(); 96 w = w.dpmenable().enable();
@@ -113,14 +104,14 @@ impl Qspi {
113 }); 104 });
114 105
115 if let Some(dpd) = &config.deep_power_down { 106 if let Some(dpd) = &config.deep_power_down {
116 qspi.dpmdur.write(|mut w| unsafe { 107 r.dpmdur.write(|mut w| unsafe {
117 w = w.enter().bits(dpd.enter_time); 108 w = w.enter().bits(dpd.enter_time);
118 w = w.exit().bits(dpd.exit_time); 109 w = w.exit().bits(dpd.exit_time);
119 w 110 w
120 }) 111 })
121 } 112 }
122 113
123 qspi.ifconfig1.write(|w| { 114 r.ifconfig1.write(|w| {
124 let w = unsafe { w.sckdelay().bits(80) }; 115 let w = unsafe { w.sckdelay().bits(80) };
125 let w = w.dpmen().exit(); 116 let w = w.dpmen().exit();
126 let w = w.spimode().mode0(); 117 let w = w.spimode().mode0();
@@ -128,48 +119,42 @@ impl Qspi {
128 w 119 w
129 }); 120 });
130 121
131 qspi.xipoffset 122 r.xipoffset
132 .write(|w| unsafe { w.xipoffset().bits(config.xip_offset) }); 123 .write(|w| unsafe { w.xipoffset().bits(config.xip_offset) });
133 124
134 // Enable it 125 // Enable it
135 qspi.enable.write(|w| w.enable().enabled()); 126 r.enable.write(|w| w.enable().enabled());
136 127
137 qspi.events_ready.reset(); 128 r.events_ready.reset();
138 qspi.tasks_activate.write(|w| w.tasks_activate().bit(true)); 129 r.tasks_activate.write(|w| w.tasks_activate().bit(true));
139 while qspi.events_ready.read().bits() == 0 {} 130 while r.events_ready.read().bits() == 0 {}
140 qspi.events_ready.reset(); 131 r.events_ready.reset();
141 132
142 Self { 133 Self {
143 inner: PeripheralMutex::new( 134 qspi,
144 State { 135 irq,
145 inner: qspi, 136 phantom: PhantomData,
146 waker: WakerRegistration::new(),
147 },
148 irq,
149 ),
150 } 137 }
151 } 138 }
152 139
153 pub fn sleep(self: Pin<&mut Self>) { 140 pub fn sleep(mut self: Pin<&mut Self>) {
154 self.inner().with(|s, _| { 141 let r = unsafe { self.as_mut().get_unchecked_mut() }.qspi.regs();
155 info!("flash: sleeping"); 142
156 info!("flash: state = {:?}", s.inner.status.read().bits()); 143 info!("flash: sleeping");
157 s.inner.ifconfig1.modify(|_, w| w.dpmen().enter()); 144 info!("flash: state = {:?}", r.status.read().bits());
158 info!("flash: state = {:?}", s.inner.status.read().bits()); 145 r.ifconfig1.modify(|_, w| w.dpmen().enter());
159 cortex_m::asm::delay(1000000); 146 info!("flash: state = {:?}", r.status.read().bits());
160 info!("flash: state = {:?}", s.inner.status.read().bits()); 147 cortex_m::asm::delay(1000000);
161 148 info!("flash: state = {:?}", r.status.read().bits());
162 s.inner 149
163 .tasks_deactivate 150 r.tasks_deactivate.write(|w| w.tasks_deactivate().set_bit());
164 .write(|w| w.tasks_deactivate().set_bit());
165 });
166 } 151 }
167 152
168 pub async fn custom_instruction<'a>( 153 pub async fn custom_instruction(
169 mut self: Pin<&'a mut Self>, 154 mut self: Pin<&mut Self>,
170 opcode: u8, 155 opcode: u8,
171 req: &'a [u8], 156 req: &[u8],
172 resp: &'a mut [u8], 157 resp: &mut [u8],
173 ) -> Result<(), Error> { 158 ) -> Result<(), Error> {
174 let bomb = DropBomb::new(); 159 let bomb = DropBomb::new();
175 160
@@ -192,69 +177,73 @@ impl Qspi {
192 177
193 let len = core::cmp::max(req.len(), resp.len()) as u8; 178 let len = core::cmp::max(req.len(), resp.len()) as u8;
194 179
195 self.as_mut().inner().with(|s, _| { 180 let r = unsafe { self.as_mut().get_unchecked_mut() }.qspi.regs();
196 s.inner.cinstrdat0.write(|w| unsafe { w.bits(dat0) }); 181 r.cinstrdat0.write(|w| unsafe { w.bits(dat0) });
197 s.inner.cinstrdat1.write(|w| unsafe { w.bits(dat1) }); 182 r.cinstrdat1.write(|w| unsafe { w.bits(dat1) });
198 183
199 s.inner.events_ready.reset(); 184 r.events_ready.reset();
200 s.inner.intenset.write(|w| w.ready().set()); 185 r.intenset.write(|w| w.ready().set());
201 186
202 s.inner.cinstrconf.write(|w| { 187 r.cinstrconf.write(|w| {
203 let w = unsafe { w.opcode().bits(opcode) }; 188 let w = unsafe { w.opcode().bits(opcode) };
204 let w = unsafe { w.length().bits(len + 1) }; 189 let w = unsafe { w.length().bits(len + 1) };
205 let w = w.lio2().bit(true); 190 let w = w.lio2().bit(true);
206 let w = w.lio3().bit(true); 191 let w = w.lio3().bit(true);
207 let w = w.wipwait().bit(true); 192 let w = w.wipwait().bit(true);
208 let w = w.wren().bit(true); 193 let w = w.wren().bit(true);
209 let w = w.lfen().bit(false); 194 let w = w.lfen().bit(false);
210 let w = w.lfstop().bit(false); 195 let w = w.lfstop().bit(false);
211 w 196 w
212 });
213 }); 197 });
214 198
215 self.as_mut().wait_ready().await; 199 self.as_mut().wait_ready().await;
216 200
217 self.as_mut().inner().with(|s, _| { 201 let r = unsafe { self.as_mut().get_unchecked_mut() }.qspi.regs();
218 let dat0 = s.inner.cinstrdat0.read().bits(); 202
219 let dat1 = s.inner.cinstrdat1.read().bits(); 203 let dat0 = r.cinstrdat0.read().bits();
220 for i in 0..4 { 204 let dat1 = r.cinstrdat1.read().bits();
221 if i < resp.len() { 205 for i in 0..4 {
222 resp[i] = (dat0 >> (i * 8)) as u8; 206 if i < resp.len() {
223 } 207 resp[i] = (dat0 >> (i * 8)) as u8;
224 } 208 }
225 for i in 0..4 { 209 }
226 if i + 4 < resp.len() { 210 for i in 0..4 {
227 resp[i] = (dat1 >> (i * 8)) as u8; 211 if i + 4 < resp.len() {
228 } 212 resp[i] = (dat1 >> (i * 8)) as u8;
229 } 213 }
230 }); 214 }
231 215
232 bomb.defuse(); 216 bomb.defuse();
233 217
234 Ok(()) 218 Ok(())
235 } 219 }
236 220
237 fn inner(self: Pin<&mut Self>) -> Pin<&mut PeripheralMutex<State>> { 221 async fn wait_ready(self: Pin<&mut Self>) {
238 unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) } 222 let this = unsafe { self.get_unchecked_mut() };
239 }
240 223
241 fn wait_ready<'a>(mut self: Pin<&'a mut Self>) -> impl Future<Output = ()> + 'a {
242 poll_fn(move |cx| { 224 poll_fn(move |cx| {
243 self.as_mut().inner().with(|s, _irq| { 225 let r = this.qspi.regs();
244 if s.inner.events_ready.read().bits() != 0 { 226
245 return Poll::Ready(()); 227 if r.events_ready.read().bits() != 0 {
246 } 228 r.events_ready.reset();
247 s.waker.register(cx.waker()); 229 return Poll::Ready(());
248 Poll::Pending 230 }
249 }) 231
232 wake_on_interrupt(&mut this.irq, cx.waker());
233
234 Poll::Pending
250 }) 235 })
236 .await
251 } 237 }
252} 238}
253 239
254impl Flash for Qspi { 240impl<'d, T: Instance> Flash for Qspi<'d, T> {
255 type ReadFuture<'a> = impl Future<Output = Result<(), Error>> + 'a; 241 #[rustfmt::skip]
256 type WriteFuture<'a> = impl Future<Output = Result<(), Error>> + 'a; 242 type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a;
257 type ErasePageFuture<'a> = impl Future<Output = Result<(), Error>> + 'a; 243 #[rustfmt::skip]
244 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a;
245 #[rustfmt::skip]
246 type ErasePageFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a;
258 247
259 fn read<'a>( 248 fn read<'a>(
260 mut self: Pin<&'a mut Self>, 249 mut self: Pin<&'a mut Self>,
@@ -268,26 +257,21 @@ impl Flash for Qspi {
268 assert_eq!(data.len() as u32 % 4, 0); 257 assert_eq!(data.len() as u32 % 4, 0);
269 assert_eq!(address as u32 % 4, 0); 258 assert_eq!(address as u32 % 4, 0);
270 259
271 self.as_mut().inner().with(|s, _| { 260 let r = unsafe { self.as_mut().get_unchecked_mut() }.qspi.regs();
272 s.inner 261
273 .read 262 r.read
274 .src 263 .src
275 .write(|w| unsafe { w.src().bits(address as u32) }); 264 .write(|w| unsafe { w.src().bits(address as u32) });
276 s.inner 265 r.read
277 .read 266 .dst
278 .dst 267 .write(|w| unsafe { w.dst().bits(data.as_ptr() as u32) });
279 .write(|w| unsafe { w.dst().bits(data.as_ptr() as u32) }); 268 r.read
280 s.inner 269 .cnt
281 .read 270 .write(|w| unsafe { w.cnt().bits(data.len() as u32) });
282 .cnt 271
283 .write(|w| unsafe { w.cnt().bits(data.len() as u32) }); 272 r.events_ready.reset();
284 273 r.intenset.write(|w| w.ready().set());
285 s.inner.events_ready.reset(); 274 r.tasks_readstart.write(|w| w.tasks_readstart().bit(true));
286 s.inner.intenset.write(|w| w.ready().set());
287 s.inner
288 .tasks_readstart
289 .write(|w| w.tasks_readstart().bit(true));
290 });
291 275
292 self.as_mut().wait_ready().await; 276 self.as_mut().wait_ready().await;
293 277
@@ -309,26 +293,20 @@ impl Flash for Qspi {
309 assert_eq!(data.len() as u32 % 4, 0); 293 assert_eq!(data.len() as u32 % 4, 0);
310 assert_eq!(address as u32 % 4, 0); 294 assert_eq!(address as u32 % 4, 0);
311 295
312 self.as_mut().inner().with(|s, _| { 296 let r = unsafe { self.as_mut().get_unchecked_mut() }.qspi.regs();
313 s.inner 297 r.write
314 .write 298 .src
315 .src 299 .write(|w| unsafe { w.src().bits(data.as_ptr() as u32) });
316 .write(|w| unsafe { w.src().bits(data.as_ptr() as u32) }); 300 r.write
317 s.inner 301 .dst
318 .write 302 .write(|w| unsafe { w.dst().bits(address as u32) });
319 .dst 303 r.write
320 .write(|w| unsafe { w.dst().bits(address as u32) }); 304 .cnt
321 s.inner 305 .write(|w| unsafe { w.cnt().bits(data.len() as u32) });
322 .write 306
323 .cnt 307 r.events_ready.reset();
324 .write(|w| unsafe { w.cnt().bits(data.len() as u32) }); 308 r.intenset.write(|w| w.ready().set());
325 309 r.tasks_writestart.write(|w| w.tasks_writestart().bit(true));
326 s.inner.events_ready.reset();
327 s.inner.intenset.write(|w| w.ready().set());
328 s.inner
329 .tasks_writestart
330 .write(|w| w.tasks_writestart().bit(true));
331 });
332 310
333 self.as_mut().wait_ready().await; 311 self.as_mut().wait_ready().await;
334 312
@@ -344,19 +322,15 @@ impl Flash for Qspi {
344 322
345 assert_eq!(address as u32 % 4096, 0); 323 assert_eq!(address as u32 % 4096, 0);
346 324
347 self.as_mut().inner().with(|s, _| { 325 let r = unsafe { self.as_mut().get_unchecked_mut() }.qspi.regs();
348 s.inner 326 r.erase
349 .erase 327 .ptr
350 .ptr 328 .write(|w| unsafe { w.ptr().bits(address as u32) });
351 .write(|w| unsafe { w.ptr().bits(address as u32) }); 329 r.erase.len.write(|w| w.len()._4kb());
352 s.inner.erase.len.write(|w| w.len()._4kb());
353 330
354 s.inner.events_ready.reset(); 331 r.events_ready.reset();
355 s.inner.intenset.write(|w| w.ready().set()); 332 r.intenset.write(|w| w.ready().set());
356 s.inner 333 r.tasks_erasestart.write(|w| w.tasks_erasestart().bit(true));
357 .tasks_erasestart
358 .write(|w| w.tasks_erasestart().bit(true));
359 });
360 334
361 self.as_mut().wait_ready().await; 335 self.as_mut().wait_ready().await;
362 336
@@ -383,13 +357,29 @@ impl Flash for Qspi {
383 } 357 }
384} 358}
385 359
386impl PeripheralState for State { 360mod sealed {
387 type Interrupt = interrupt::QSPI; 361 use super::*;
388 362
389 fn on_interrupt(&mut self) { 363 pub trait Instance {
390 if self.inner.events_ready.read().bits() != 0 { 364 fn regs(&mut self) -> &pac::qspi::RegisterBlock;
391 self.inner.intenclr.write(|w| w.ready().clear());
392 self.waker.wake()
393 }
394 } 365 }
395} 366}
367
368pub trait Instance: sealed::Instance + 'static {
369 type Interrupt: Interrupt;
370}
371
372macro_rules! make_impl {
373 ($type:ident, $irq:ident) => {
374 impl sealed::Instance for peripherals::$type {
375 fn regs(&mut self) -> &pac::qspi::RegisterBlock {
376 unsafe { &*pac::$type::ptr() }
377 }
378 }
379 impl Instance for peripherals::$type {
380 type Interrupt = interrupt::$irq;
381 }
382 };
383}
384
385make_impl!(QSPI, QSPI);
diff --git a/embassy-traits/src/flash.rs b/embassy-traits/src/flash.rs
index 145cc7684..3adaa3a0a 100644
--- a/embassy-traits/src/flash.rs
+++ b/embassy-traits/src/flash.rs
@@ -11,9 +11,17 @@ pub enum Error {
11} 11}
12 12
13pub trait Flash { 13pub trait Flash {
14 type ReadFuture<'a>: Future<Output = Result<(), Error>>; 14 type ReadFuture<'a>: Future<Output = Result<(), Error>>
15 type WriteFuture<'a>: Future<Output = Result<(), Error>>; 15 where
16 type ErasePageFuture<'a>: Future<Output = Result<(), Error>>; 16 Self: 'a;
17
18 type WriteFuture<'a>: Future<Output = Result<(), Error>>
19 where
20 Self: 'a;
21
22 type ErasePageFuture<'a>: Future<Output = Result<(), Error>>
23 where
24 Self: 'a;
17 25
18 /// Reads data from the flash device. 26 /// Reads data from the flash device.
19 /// 27 ///