aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/modules/ROOT/examples/basic/src/main.rs5
-rw-r--r--embassy-nrf/src/gpio.rs340
-rw-r--r--embassy-nrf/src/gpiote.rs106
-rw-r--r--examples/nrf/src/bin/blinky.rs6
-rw-r--r--examples/nrf/src/bin/mpsc.rs5
-rw-r--r--examples/nrf/src/bin/spim.rs17
6 files changed, 219 insertions, 260 deletions
diff --git a/docs/modules/ROOT/examples/basic/src/main.rs b/docs/modules/ROOT/examples/basic/src/main.rs
index 2a9b1facc..8394f73b7 100644
--- a/docs/modules/ROOT/examples/basic/src/main.rs
+++ b/docs/modules/ROOT/examples/basic/src/main.rs
@@ -14,14 +14,13 @@ use embassy_nrf::{
14 peripherals::P0_13, 14 peripherals::P0_13,
15 Peripherals, 15 Peripherals,
16}; 16};
17use embedded_hal::digital::v2::OutputPin;
18 17
19#[embassy::task] 18#[embassy::task]
20async fn blinker(mut led: Output<'static, P0_13>, interval: Duration) { 19async fn blinker(mut led: Output<'static, P0_13>, interval: Duration) {
21 loop { 20 loop {
22 unwrap!(led.set_high()); 21 led.set_high();
23 Timer::after(interval).await; 22 Timer::after(interval).await;
24 unwrap!(led.set_low()); 23 led.set_low();
25 Timer::after(interval).await; 24 Timer::after(interval).await;
26 } 25 }
27} 26}
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index cb06f0971..ddc84cf5d 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -1,7 +1,6 @@
1#![macro_use] 1#![macro_use]
2 2
3use core::convert::Infallible; 3use core::convert::Infallible;
4use core::future::Future;
5use core::hint::unreachable_unchecked; 4use core::hint::unreachable_unchecked;
6use core::marker::PhantomData; 5use core::marker::PhantomData;
7 6
@@ -38,26 +37,23 @@ pub enum Pull {
38 37
39/// GPIO input driver. 38/// GPIO input driver.
40pub struct Input<'d, T: Pin> { 39pub struct Input<'d, T: Pin> {
41 pub(crate) pin: T, 40 pub(crate) pin: FlexPin<'d, T>,
42 phantom: PhantomData<&'d mut T>,
43} 41}
44 42
45impl<'d, T: Pin> Input<'d, T> { 43impl<'d, T: Pin> Input<'d, T> {
46 pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self { 44 pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self {
47 unborrow!(pin); 45 let mut pin = FlexPin::new(pin);
46 pin.set_as_input(pull);
48 47
49 init_input(&pin, pull); 48 Self { pin }
49 }
50 50
51 Self { 51 fn is_high(&self) -> bool {
52 pin, 52 self.pin.is_high()
53 phantom: PhantomData,
54 }
55 } 53 }
56}
57 54
58impl<'d, T: Pin> Drop for Input<'d, T> { 55 fn is_low(&self) -> bool {
59 fn drop(&mut self) { 56 self.pin.is_low()
60 self.pin.conf().reset();
61 } 57 }
62} 58}
63 59
@@ -65,65 +61,11 @@ impl<'d, T: Pin> InputPin for Input<'d, T> {
65 type Error = Infallible; 61 type Error = Infallible;
66 62
67 fn is_high(&self) -> Result<bool, Self::Error> { 63 fn is_high(&self) -> Result<bool, Self::Error> {
68 self.is_low().map(|v| !v) 64 Ok(self.is_high())
69 } 65 }
70 66
71 fn is_low(&self) -> Result<bool, Self::Error> { 67 fn is_low(&self) -> Result<bool, Self::Error> {
72 Ok(self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0) 68 Ok(self.is_low())
73 }
74}
75
76#[cfg(feature = "gpiote")]
77impl<'d, T: Pin> embassy::traits::gpio::WaitForHigh for Input<'d, T> {
78 type Future<'a>
79 where
80 Self: 'a,
81 = impl Future<Output = ()> + Unpin + 'a;
82
83 fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> {
84 self.pin.conf().modify(|_, w| w.sense().high());
85
86 crate::gpiote::PortInputFuture {
87 pin_port: self.pin.pin_port(),
88 phantom: PhantomData,
89 }
90 }
91}
92
93#[cfg(feature = "gpiote")]
94impl<'d, T: Pin> embassy::traits::gpio::WaitForLow for Input<'d, T> {
95 type Future<'a>
96 where
97 Self: 'a,
98 = impl Future<Output = ()> + Unpin + 'a;
99
100 fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> {
101 self.pin.conf().modify(|_, w| w.sense().low());
102
103 crate::gpiote::PortInputFuture {
104 pin_port: self.pin.pin_port(),
105 phantom: PhantomData,
106 }
107 }
108}
109
110#[cfg(feature = "gpiote")]
111impl<'d, T: Pin> embassy::traits::gpio::WaitForAnyEdge for Input<'d, T> {
112 type Future<'a>
113 where
114 Self: 'a,
115 = impl Future<Output = ()> + Unpin + 'a;
116
117 fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
118 if self.is_high().ok().unwrap() {
119 self.pin.conf().modify(|_, w| w.sense().low());
120 } else {
121 self.pin.conf().modify(|_, w| w.sense().high());
122 }
123 crate::gpiote::PortInputFuture {
124 pin_port: self.pin.pin_port(),
125 phantom: PhantomData,
126 }
127 } 69 }
128} 70}
129 71
@@ -160,8 +102,7 @@ pub enum OutputDrive {
160 102
161/// GPIO output driver. 103/// GPIO output driver.
162pub struct Output<'d, T: Pin> { 104pub struct Output<'d, T: Pin> {
163 pub(crate) pin: T, 105 pub(crate) pin: FlexPin<'d, T>,
164 phantom: PhantomData<&'d mut T>,
165} 106}
166 107
167impl<'d, T: Pin> Output<'d, T> { 108impl<'d, T: Pin> Output<'d, T> {
@@ -170,63 +111,56 @@ impl<'d, T: Pin> Output<'d, T> {
170 initial_output: Level, 111 initial_output: Level,
171 drive: OutputDrive, 112 drive: OutputDrive,
172 ) -> Self { 113 ) -> Self {
173 unborrow!(pin); 114 let mut pin = FlexPin::new(pin);
174
175 match initial_output { 115 match initial_output {
176 Level::High => pin.set_high(), 116 Level::High => pin.set_high(),
177 Level::Low => pin.set_low(), 117 Level::Low => pin.set_low(),
178 } 118 }
119 pin.set_as_output(drive);
179 120
180 init_output(&pin, drive); 121 Self { pin }
122 }
181 123
182 Self { 124 /// Set the output as high.
183 pin, 125 pub fn set_high(&mut self) {
184 phantom: PhantomData, 126 self.pin.set_high()
185 }
186 } 127 }
187}
188 128
189impl<'d, T: Pin> Drop for Output<'d, T> { 129 /// Set the output as low.
190 fn drop(&mut self) { 130 pub fn set_low(&mut self) {
191 self.pin.conf().reset(); 131 self.pin.set_low()
132 }
133
134 /// Is the output pin set as high?
135 pub fn is_set_high(&self) -> bool {
136 self.pin.is_set_high()
137 }
138
139 /// Is the output pin set as low?
140 pub fn is_set_low(&self) -> bool {
141 self.pin.is_set_low()
192 } 142 }
193} 143}
194 144
195impl<'d, T: Pin> OutputPin for Output<'d, T> { 145impl<'d, T: Pin> OutputPin for Output<'d, T> {
196 type Error = Infallible; 146 type Error = Infallible;
197 147
198 /// Set the output as high.
199 fn set_high(&mut self) -> Result<(), Self::Error> { 148 fn set_high(&mut self) -> Result<(), Self::Error> {
200 unsafe { 149 Ok(self.set_high())
201 self.pin
202 .block()
203 .outset
204 .write(|w| w.bits(1u32 << self.pin.pin()));
205 }
206 Ok(())
207 } 150 }
208 151
209 /// Set the output as low.
210 fn set_low(&mut self) -> Result<(), Self::Error> { 152 fn set_low(&mut self) -> Result<(), Self::Error> {
211 unsafe { 153 Ok(self.set_low())
212 self.pin
213 .block()
214 .outclr
215 .write(|w| w.bits(1u32 << self.pin.pin()));
216 }
217 Ok(())
218 } 154 }
219} 155}
220 156
221impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> { 157impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> {
222 /// Is the output pin set as high?
223 fn is_set_high(&self) -> Result<bool, Self::Error> { 158 fn is_set_high(&self) -> Result<bool, Self::Error> {
224 self.is_set_low().map(|v| !v) 159 Ok(self.is_set_high())
225 } 160 }
226 161
227 /// Is the output pin set as low?
228 fn is_set_low(&self) -> Result<bool, Self::Error> { 162 fn is_set_low(&self) -> Result<bool, Self::Error> {
229 Ok(self.pin.block().out.read().bits() & (1 << self.pin.pin()) == 0) 163 Ok(self.is_set_low())
230 } 164 }
231} 165}
232 166
@@ -256,7 +190,24 @@ impl<'d, T: Pin> FlexPin<'d, T> {
256 190
257 /// Put the pin into input mode. 191 /// Put the pin into input mode.
258 pub fn set_as_input(&mut self, pull: Pull) { 192 pub fn set_as_input(&mut self, pull: Pull) {
259 init_input(&self.pin, pull); 193 self.pin.conf().write(|w| {
194 w.dir().input();
195 w.input().connect();
196 match pull {
197 Pull::None => {
198 w.pull().disabled();
199 }
200 Pull::Up => {
201 w.pull().pullup();
202 }
203 Pull::Down => {
204 w.pull().pulldown();
205 }
206 }
207 w.drive().s0s1();
208 w.sense().disabled();
209 w
210 });
260 } 211 }
261 212
262 /// Put the pin into output mode. 213 /// Put the pin into output mode.
@@ -264,13 +215,59 @@ impl<'d, T: Pin> FlexPin<'d, T> {
264 /// The pin level will be whatever was set before (or low by default). If you want it to begin 215 /// The pin level will be whatever was set before (or low by default). If you want it to begin
265 /// at a specific level, call `set_high`/`set_low` on the pin first. 216 /// at a specific level, call `set_high`/`set_low` on the pin first.
266 pub fn set_as_output(&mut self, drive: OutputDrive) { 217 pub fn set_as_output(&mut self, drive: OutputDrive) {
267 init_output(&self.pin, drive); 218 let drive = match drive {
219 OutputDrive::Standard => DRIVE_A::S0S1,
220 OutputDrive::HighDrive0Standard1 => DRIVE_A::H0S1,
221 OutputDrive::Standard0HighDrive1 => DRIVE_A::S0H1,
222 OutputDrive::HighDrive => DRIVE_A::H0H1,
223 OutputDrive::Disconnect0Standard1 => DRIVE_A::D0S1,
224 OutputDrive::Disconnect0HighDrive1 => DRIVE_A::D0H1,
225 OutputDrive::Standard0Disconnect1 => DRIVE_A::S0D1,
226 OutputDrive::HighDrive0Disconnect1 => DRIVE_A::H0D1,
227 };
228
229 self.pin.conf().write(|w| {
230 w.dir().output();
231 w.input().disconnect();
232 w.pull().disabled();
233 w.drive().variant(drive);
234 w.sense().disabled();
235 w
236 });
268 } 237 }
269 238
270 /// Put the pin into disconnected mode. 239 /// Put the pin into disconnected mode.
271 pub fn set_as_disconnected(&mut self) { 240 pub fn set_as_disconnected(&mut self) {
272 self.pin.conf().reset(); 241 self.pin.conf().reset();
273 } 242 }
243
244 pub fn is_high(&self) -> bool {
245 !self.is_low()
246 }
247
248 pub fn is_low(&self) -> bool {
249 self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0
250 }
251
252 /// Set the output as high.
253 pub fn set_high(&mut self) {
254 self.pin.set_high()
255 }
256
257 /// Set the output as low.
258 pub fn set_low(&mut self) {
259 self.pin.set_low()
260 }
261
262 /// Is the output pin set as high?
263 pub fn is_set_high(&self) -> bool {
264 !self.is_set_low()
265 }
266
267 /// Is the output pin set as low?
268 pub fn is_set_low(&self) -> bool {
269 self.pin.block().out.read().bits() & (1 << self.pin.pin()) == 0
270 }
274} 271}
275 272
276impl<'d, T: Pin> Drop for FlexPin<'d, T> { 273impl<'d, T: Pin> Drop for FlexPin<'d, T> {
@@ -286,103 +283,33 @@ impl<'d, T: Pin> InputPin for FlexPin<'d, T> {
286 type Error = Infallible; 283 type Error = Infallible;
287 284
288 fn is_high(&self) -> Result<bool, Self::Error> { 285 fn is_high(&self) -> Result<bool, Self::Error> {
289 self.is_low().map(|v| !v) 286 Ok(self.is_high())
290 } 287 }
291 288
292 fn is_low(&self) -> Result<bool, Self::Error> { 289 fn is_low(&self) -> Result<bool, Self::Error> {
293 Ok(self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0) 290 Ok(self.is_low())
294 } 291 }
295} 292}
296 293
297impl<'d, T: Pin> OutputPin for FlexPin<'d, T> { 294impl<'d, T: Pin> OutputPin for FlexPin<'d, T> {
298 type Error = Infallible; 295 type Error = Infallible;
299 296
300 /// Set the output as high.
301 fn set_high(&mut self) -> Result<(), Self::Error> { 297 fn set_high(&mut self) -> Result<(), Self::Error> {
302 unsafe { 298 Ok(self.set_high())
303 self.pin
304 .block()
305 .outset
306 .write(|w| w.bits(1u32 << self.pin.pin()));
307 }
308 Ok(())
309 } 299 }
310 300
311 /// Set the output as low.
312 fn set_low(&mut self) -> Result<(), Self::Error> { 301 fn set_low(&mut self) -> Result<(), Self::Error> {
313 unsafe { 302 Ok(self.set_low())
314 self.pin
315 .block()
316 .outclr
317 .write(|w| w.bits(1u32 << self.pin.pin()));
318 }
319 Ok(())
320 } 303 }
321} 304}
322 305
323impl<'d, T: Pin> StatefulOutputPin for FlexPin<'d, T> { 306impl<'d, T: Pin> StatefulOutputPin for FlexPin<'d, T> {
324 /// Is the output pin set as high?
325 fn is_set_high(&self) -> Result<bool, Self::Error> { 307 fn is_set_high(&self) -> Result<bool, Self::Error> {
326 self.is_set_low().map(|v| !v) 308 Ok(self.is_set_high())
327 } 309 }
328 310
329 /// Is the output pin set as low?
330 fn is_set_low(&self) -> Result<bool, Self::Error> { 311 fn is_set_low(&self) -> Result<bool, Self::Error> {
331 Ok(self.pin.block().out.read().bits() & (1 << self.pin.pin()) == 0) 312 Ok(self.is_set_low())
332 }
333}
334
335#[cfg(feature = "gpiote")]
336impl<'d, T: Pin> embassy::traits::gpio::WaitForHigh for FlexPin<'d, T> {
337 type Future<'a>
338 where
339 Self: 'a,
340 = impl Future<Output = ()> + Unpin + 'a;
341
342 fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> {
343 self.pin.conf().modify(|_, w| w.sense().high());
344
345 crate::gpiote::PortInputFuture {
346 pin_port: self.pin.pin_port(),
347 phantom: PhantomData,
348 }
349 }
350}
351
352#[cfg(feature = "gpiote")]
353impl<'d, T: Pin> embassy::traits::gpio::WaitForLow for FlexPin<'d, T> {
354 type Future<'a>
355 where
356 Self: 'a,
357 = impl Future<Output = ()> + Unpin + 'a;
358
359 fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> {
360 self.pin.conf().modify(|_, w| w.sense().low());
361
362 crate::gpiote::PortInputFuture {
363 pin_port: self.pin.pin_port(),
364 phantom: PhantomData,
365 }
366 }
367}
368
369#[cfg(feature = "gpiote")]
370impl<'d, T: Pin> embassy::traits::gpio::WaitForAnyEdge for FlexPin<'d, T> {
371 type Future<'a>
372 where
373 Self: 'a,
374 = impl Future<Output = ()> + Unpin + 'a;
375
376 fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
377 if self.is_high().ok().unwrap() {
378 self.pin.conf().modify(|_, w| w.sense().low());
379 } else {
380 self.pin.conf().modify(|_, w| w.sense().high());
381 }
382 crate::gpiote::PortInputFuture {
383 pin_port: self.pin.pin_port(),
384 phantom: PhantomData,
385 }
386 } 313 }
387} 314}
388 315
@@ -493,55 +420,6 @@ impl sealed::Pin for AnyPin {
493 } 420 }
494} 421}
495 422
496// =====================
497
498/// Set up a pin for input
499#[inline]
500fn init_input<T: Pin>(pin: &T, pull: Pull) {
501 pin.conf().write(|w| {
502 w.dir().input();
503 w.input().connect();
504 match pull {
505 Pull::None => {
506 w.pull().disabled();
507 }
508 Pull::Up => {
509 w.pull().pullup();
510 }
511 Pull::Down => {
512 w.pull().pulldown();
513 }
514 }
515 w.drive().s0s1();
516 w.sense().disabled();
517 w
518 });
519}
520
521/// Set up a pin for output
522#[inline]
523fn init_output<T: Pin>(pin: &T, drive: OutputDrive) {
524 let drive = match drive {
525 OutputDrive::Standard => DRIVE_A::S0S1,
526 OutputDrive::HighDrive0Standard1 => DRIVE_A::H0S1,
527 OutputDrive::Standard0HighDrive1 => DRIVE_A::S0H1,
528 OutputDrive::HighDrive => DRIVE_A::H0H1,
529 OutputDrive::Disconnect0Standard1 => DRIVE_A::D0S1,
530 OutputDrive::Disconnect0HighDrive1 => DRIVE_A::D0H1,
531 OutputDrive::Standard0Disconnect1 => DRIVE_A::S0D1,
532 OutputDrive::HighDrive0Disconnect1 => DRIVE_A::H0D1,
533 };
534
535 pin.conf().write(|w| {
536 w.dir().output();
537 w.input().disconnect();
538 w.pull().disabled();
539 w.drive().variant(drive);
540 w.sense().disabled();
541 w
542 });
543}
544
545// ==================== 423// ====================
546 424
547pub trait OptionalPin: Unborrow<Target = Self> + sealed::OptionalPin + Sized { 425pub trait OptionalPin: Unborrow<Target = Self> + sealed::OptionalPin + Sized {
@@ -601,9 +479,7 @@ pub(crate) fn deconfigure_pin(psel_bits: u32) {
601 if psel_bits & 0x8000_0000 != 0 { 479 if psel_bits & 0x8000_0000 != 0 {
602 return; 480 return;
603 } 481 }
604 unsafe { 482 unsafe { AnyPin::steal(psel_bits as _).conf().reset() }
605 AnyPin::steal(psel_bits as _).conf().reset();
606 }
607} 483}
608 484
609// ==================== 485// ====================
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 4b595c589..99dfd1ebd 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -5,11 +5,11 @@ use core::task::{Context, Poll};
5use embassy::interrupt::{Interrupt, InterruptExt}; 5use embassy::interrupt::{Interrupt, InterruptExt};
6use embassy::waitqueue::AtomicWaker; 6use embassy::waitqueue::AtomicWaker;
7use embassy_hal_common::unsafe_impl_unborrow; 7use embassy_hal_common::unsafe_impl_unborrow;
8use embedded_hal::digital::v2::{InputPin, StatefulOutputPin}; 8use embedded_hal::digital::v2::InputPin;
9use futures::future::poll_fn; 9use futures::future::poll_fn;
10 10
11use crate::gpio::sealed::Pin as _; 11use crate::gpio::sealed::Pin as _;
12use crate::gpio::{AnyPin, Input, Output, Pin as GpioPin}; 12use crate::gpio::{AnyPin, FlexPin, Input, Output, Pin as GpioPin};
13use crate::pac; 13use crate::pac;
14use crate::ppi::{Event, Task}; 14use crate::ppi::{Event, Task};
15use crate::{interrupt, peripherals}; 15use crate::{interrupt, peripherals};
@@ -177,11 +177,11 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> {
177 InputChannelPolarity::Toggle => w.mode().event().polarity().toggle(), 177 InputChannelPolarity::Toggle => w.mode().event().polarity().toggle(),
178 }; 178 };
179 #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] 179 #[cfg(any(feature = "nrf52833", feature = "nrf52840"))]
180 w.port().bit(match pin.pin.port() { 180 w.port().bit(match pin.pin.pin.port() {
181 crate::gpio::Port::Port0 => false, 181 crate::gpio::Port::Port0 => false,
182 crate::gpio::Port::Port1 => true, 182 crate::gpio::Port::Port1 => true,
183 }); 183 });
184 unsafe { w.psel().bits(pin.pin.pin()) } 184 unsafe { w.psel().bits(pin.pin.pin.pin()) }
185 }); 185 });
186 186
187 g.events_in[num].reset(); 187 g.events_in[num].reset();
@@ -250,7 +250,7 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
250 250
251 g.config[num].write(|w| { 251 g.config[num].write(|w| {
252 w.mode().task(); 252 w.mode().task();
253 match pin.is_set_high().unwrap() { 253 match pin.is_set_high() {
254 true => w.outinit().high(), 254 true => w.outinit().high(),
255 false => w.outinit().low(), 255 false => w.outinit().low(),
256 }; 256 };
@@ -260,11 +260,11 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
260 OutputChannelPolarity::Toggle => w.polarity().toggle(), 260 OutputChannelPolarity::Toggle => w.polarity().toggle(),
261 }; 261 };
262 #[cfg(any(feature = "nrf52833", feature = "nrf52840"))] 262 #[cfg(any(feature = "nrf52833", feature = "nrf52840"))]
263 w.port().bit(match pin.pin.port() { 263 w.port().bit(match pin.pin.pin.port() {
264 crate::gpio::Port::Port0 => false, 264 crate::gpio::Port::Port0 => false,
265 crate::gpio::Port::Port1 => true, 265 crate::gpio::Port::Port1 => true,
266 }); 266 });
267 unsafe { w.psel().bits(pin.pin.pin()) } 267 unsafe { w.psel().bits(pin.pin.pin.pin()) }
268 }); 268 });
269 269
270 OutputChannel { ch, _pin: pin } 270 OutputChannel { ch, _pin: pin }
@@ -311,9 +311,11 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
311 } 311 }
312} 312}
313 313
314// =======================
315
314pub(crate) struct PortInputFuture<'a> { 316pub(crate) struct PortInputFuture<'a> {
315 pub(crate) pin_port: u8, 317 pin_port: u8,
316 pub(crate) phantom: PhantomData<&'a mut AnyPin>, 318 phantom: PhantomData<&'a mut AnyPin>,
317} 319}
318 320
319impl<'a> Unpin for PortInputFuture<'a> {} 321impl<'a> Unpin for PortInputFuture<'a> {}
@@ -340,6 +342,92 @@ impl<'a> Future for PortInputFuture<'a> {
340 } 342 }
341} 343}
342 344
345impl<'d, T: GpioPin> embassy::traits::gpio::WaitForHigh for Input<'d, T> {
346 type Future<'a>
347 where
348 Self: 'a,
349 = impl Future<Output = ()> + Unpin + 'a;
350
351 fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> {
352 self.pin.wait_for_high()
353 }
354}
355
356impl<'d, T: GpioPin> embassy::traits::gpio::WaitForLow for Input<'d, T> {
357 type Future<'a>
358 where
359 Self: 'a,
360 = impl Future<Output = ()> + Unpin + 'a;
361
362 fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> {
363 self.pin.wait_for_low()
364 }
365}
366
367impl<'d, T: GpioPin> embassy::traits::gpio::WaitForAnyEdge for Input<'d, T> {
368 type Future<'a>
369 where
370 Self: 'a,
371 = impl Future<Output = ()> + Unpin + 'a;
372
373 fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
374 self.pin.wait_for_any_edge()
375 }
376}
377
378impl<'d, T: GpioPin> embassy::traits::gpio::WaitForHigh for FlexPin<'d, T> {
379 type Future<'a>
380 where
381 Self: 'a,
382 = impl Future<Output = ()> + Unpin + 'a;
383
384 fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> {
385 self.pin.conf().modify(|_, w| w.sense().high());
386
387 PortInputFuture {
388 pin_port: self.pin.pin_port(),
389 phantom: PhantomData,
390 }
391 }
392}
393
394impl<'d, T: GpioPin> embassy::traits::gpio::WaitForLow for FlexPin<'d, T> {
395 type Future<'a>
396 where
397 Self: 'a,
398 = impl Future<Output = ()> + Unpin + 'a;
399
400 fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> {
401 self.pin.conf().modify(|_, w| w.sense().low());
402
403 PortInputFuture {
404 pin_port: self.pin.pin_port(),
405 phantom: PhantomData,
406 }
407 }
408}
409
410impl<'d, T: GpioPin> embassy::traits::gpio::WaitForAnyEdge for FlexPin<'d, T> {
411 type Future<'a>
412 where
413 Self: 'a,
414 = impl Future<Output = ()> + Unpin + 'a;
415
416 fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
417 if self.is_high() {
418 self.pin.conf().modify(|_, w| w.sense().low());
419 } else {
420 self.pin.conf().modify(|_, w| w.sense().high());
421 }
422 PortInputFuture {
423 pin_port: self.pin.pin_port(),
424 phantom: PhantomData,
425 }
426 }
427}
428
429// =======================
430
343mod sealed { 431mod sealed {
344 pub trait Channel {} 432 pub trait Channel {}
345} 433}
diff --git a/examples/nrf/src/bin/blinky.rs b/examples/nrf/src/bin/blinky.rs
index a12fe58ff..0fc004ed8 100644
--- a/examples/nrf/src/bin/blinky.rs
+++ b/examples/nrf/src/bin/blinky.rs
@@ -5,21 +5,19 @@
5#[path = "../example_common.rs"] 5#[path = "../example_common.rs"]
6mod example_common; 6mod example_common;
7 7
8use defmt::unwrap;
9use embassy::executor::Spawner; 8use embassy::executor::Spawner;
10use embassy::time::{Duration, Timer}; 9use embassy::time::{Duration, Timer};
11use embassy_nrf::gpio::{Level, Output, OutputDrive}; 10use embassy_nrf::gpio::{Level, Output, OutputDrive};
12use embassy_nrf::Peripherals; 11use embassy_nrf::Peripherals;
13use embedded_hal::digital::v2::OutputPin;
14 12
15#[embassy::main] 13#[embassy::main]
16async fn main(_spawner: Spawner, p: Peripherals) { 14async fn main(_spawner: Spawner, p: Peripherals) {
17 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); 15 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
18 16
19 loop { 17 loop {
20 unwrap!(led.set_high()); 18 led.set_high();
21 Timer::after(Duration::from_millis(300)).await; 19 Timer::after(Duration::from_millis(300)).await;
22 unwrap!(led.set_low()); 20 led.set_low();
23 Timer::after(Duration::from_millis(300)).await; 21 Timer::after(Duration::from_millis(300)).await;
24 } 22 }
25} 23}
diff --git a/examples/nrf/src/bin/mpsc.rs b/examples/nrf/src/bin/mpsc.rs
index c85b7c282..454fb9541 100644
--- a/examples/nrf/src/bin/mpsc.rs
+++ b/examples/nrf/src/bin/mpsc.rs
@@ -13,7 +13,6 @@ use embassy::time::{Duration, Timer};
13use embassy::util::Forever; 13use embassy::util::Forever;
14use embassy_nrf::gpio::{Level, Output, OutputDrive}; 14use embassy_nrf::gpio::{Level, Output, OutputDrive};
15use embassy_nrf::Peripherals; 15use embassy_nrf::Peripherals;
16use embedded_hal::digital::v2::OutputPin;
17 16
18enum LedState { 17enum LedState {
19 On, 18 On,
@@ -53,8 +52,8 @@ async fn main(spawner: Spawner, p: Peripherals) {
53 Err(TryRecvError::Closed) => break, 52 Err(TryRecvError::Closed) => break,
54 }; 53 };
55 match maybe_message { 54 match maybe_message {
56 Some(LedState::On) => unwrap!(led.set_high()), 55 Some(LedState::On) => led.set_high(),
57 Some(LedState::Off) => unwrap!(led.set_low()), 56 Some(LedState::Off) => led.set_low(),
58 _ => (), 57 _ => (),
59 } 58 }
60 } 59 }
diff --git a/examples/nrf/src/bin/spim.rs b/examples/nrf/src/bin/spim.rs
index d34ca0b85..fc31d140a 100644
--- a/examples/nrf/src/bin/spim.rs
+++ b/examples/nrf/src/bin/spim.rs
@@ -10,7 +10,6 @@ use embassy_nrf::gpio::{Level, Output, OutputDrive};
10use embassy_nrf::Peripherals; 10use embassy_nrf::Peripherals;
11use embassy_nrf::{interrupt, spim}; 11use embassy_nrf::{interrupt, spim};
12use embassy_traits::spi::FullDuplex; 12use embassy_traits::spi::FullDuplex;
13use embedded_hal::digital::v2::*;
14use example_common::*; 13use example_common::*;
15 14
16#[embassy::main] 15#[embassy::main]
@@ -29,12 +28,12 @@ async fn main(_spawner: Spawner, p: Peripherals) {
29 28
30 // softreset 29 // softreset
31 cortex_m::asm::delay(10); 30 cortex_m::asm::delay(10);
32 unwrap!(ncs.set_low()); 31 ncs.set_low();
33 cortex_m::asm::delay(5); 32 cortex_m::asm::delay(5);
34 let tx = [0xFF]; 33 let tx = [0xFF];
35 unwrap!(spim.read_write(&mut [], &tx).await); 34 unwrap!(spim.read_write(&mut [], &tx).await);
36 cortex_m::asm::delay(10); 35 cortex_m::asm::delay(10);
37 unwrap!(ncs.set_high()); 36 ncs.set_high();
38 37
39 cortex_m::asm::delay(100000); 38 cortex_m::asm::delay(100000);
40 39
@@ -42,31 +41,31 @@ async fn main(_spawner: Spawner, p: Peripherals) {
42 41
43 // read ESTAT 42 // read ESTAT
44 cortex_m::asm::delay(5000); 43 cortex_m::asm::delay(5000);
45 unwrap!(ncs.set_low()); 44 ncs.set_low();
46 cortex_m::asm::delay(5000); 45 cortex_m::asm::delay(5000);
47 let tx = [0b000_11101, 0]; 46 let tx = [0b000_11101, 0];
48 unwrap!(spim.read_write(&mut rx, &tx).await); 47 unwrap!(spim.read_write(&mut rx, &tx).await);
49 cortex_m::asm::delay(5000); 48 cortex_m::asm::delay(5000);
50 unwrap!(ncs.set_high()); 49 ncs.set_high();
51 info!("estat: {=[?]}", rx); 50 info!("estat: {=[?]}", rx);
52 51
53 // Switch to bank 3 52 // Switch to bank 3
54 cortex_m::asm::delay(10); 53 cortex_m::asm::delay(10);
55 unwrap!(ncs.set_low()); 54 ncs.set_low();
56 cortex_m::asm::delay(5); 55 cortex_m::asm::delay(5);
57 let tx = [0b100_11111, 0b11]; 56 let tx = [0b100_11111, 0b11];
58 unwrap!(spim.read_write(&mut rx, &tx).await); 57 unwrap!(spim.read_write(&mut rx, &tx).await);
59 cortex_m::asm::delay(10); 58 cortex_m::asm::delay(10);
60 unwrap!(ncs.set_high()); 59 ncs.set_high();
61 60
62 // read EREVID 61 // read EREVID
63 cortex_m::asm::delay(10); 62 cortex_m::asm::delay(10);
64 unwrap!(ncs.set_low()); 63 ncs.set_low();
65 cortex_m::asm::delay(5); 64 cortex_m::asm::delay(5);
66 let tx = [0b000_10010, 0]; 65 let tx = [0b000_10010, 0];
67 unwrap!(spim.read_write(&mut rx, &tx).await); 66 unwrap!(spim.read_write(&mut rx, &tx).await);
68 cortex_m::asm::delay(10); 67 cortex_m::asm::delay(10);
69 unwrap!(ncs.set_high()); 68 ncs.set_high();
70 69
71 info!("erevid: {=[?]}", rx); 70 info!("erevid: {=[?]}", rx);
72} 71}