aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src
diff options
context:
space:
mode:
authorRichard Dodd <[email protected]>2021-03-24 18:31:11 +0100
committerDario Nieuwenhuis <[email protected]>2021-03-29 00:58:58 +0200
commita08d7814420ed575ead6744f4254bfbb431bbc27 (patch)
treea3a5396c3389917bee1b8e3c4c9ec49bd442234d /embassy-nrf/src
parent806ee120ba4186d3cefbcaf39b84b727089d9268 (diff)
nrf/gpio: allow borrowed pins.
Diffstat (limited to 'embassy-nrf/src')
-rw-r--r--embassy-nrf/src/gpio.rs44
-rw-r--r--embassy-nrf/src/gpiote.rs19
2 files changed, 41 insertions, 22 deletions
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index d48ad3d0e..0d566ff3a 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -1,7 +1,9 @@
1use core::convert::Infallible; 1use core::convert::Infallible;
2use core::hint::unreachable_unchecked; 2use core::hint::unreachable_unchecked;
3use core::marker::PhantomData;
3 4
4use embassy::util::PeripheralBorrow; 5use embassy::util::PeripheralBorrow;
6use embassy_extras::unborrow;
5use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; 7use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
6use gpio::pin_cnf::DRIVE_A; 8use gpio::pin_cnf::DRIVE_A;
7 9
@@ -30,12 +32,15 @@ pub enum Pull {
30} 32}
31 33
32/// GPIO input driver. 34/// GPIO input driver.
33pub struct Input<T: Pin> { 35pub struct Input<'d, T: Pin> {
34 pub(crate) pin: T, 36 pub(crate) pin: T,
37 phantom: PhantomData<&'d mut T>,
35} 38}
36 39
37impl<T: Pin> Input<T> { 40impl<'d, T: Pin> Input<'d, T> {
38 pub fn new(pin: T, pull: Pull) -> Self { 41 pub fn new(pin: impl PeripheralBorrow<Target = T> + 'd, pull: Pull) -> Self {
42 unborrow!(pin);
43
39 pin.conf().write(|w| { 44 pin.conf().write(|w| {
40 w.dir().input(); 45 w.dir().input();
41 w.input().connect(); 46 w.input().connect();
@@ -55,17 +60,20 @@ impl<T: Pin> Input<T> {
55 w 60 w
56 }); 61 });
57 62
58 Self { pin } 63 Self {
64 pin,
65 phantom: PhantomData,
66 }
59 } 67 }
60} 68}
61 69
62impl<T: Pin> Drop for Input<T> { 70impl<'d, T: Pin> Drop for Input<'d, T> {
63 fn drop(&mut self) { 71 fn drop(&mut self) {
64 self.pin.conf().reset(); 72 self.pin.conf().reset();
65 } 73 }
66} 74}
67 75
68impl<T: Pin> InputPin for Input<T> { 76impl<'d, T: Pin> InputPin for Input<'d, T> {
69 type Error = Infallible; 77 type Error = Infallible;
70 78
71 fn is_high(&self) -> Result<bool, Self::Error> { 79 fn is_high(&self) -> Result<bool, Self::Error> {
@@ -108,12 +116,19 @@ pub enum OutputDrive {
108} 116}
109 117
110/// GPIO output driver. 118/// GPIO output driver.
111pub struct Output<T: Pin> { 119pub struct Output<'d, T: Pin> {
112 pin: T, 120 pin: T,
121 phantom: PhantomData<&'d mut T>,
113} 122}
114 123
115impl<T: Pin> Output<T> { 124impl<'d, T: Pin> Output<'d, T> {
116 pub fn new(pin: T, initial_output: Level, drive: OutputDrive) -> Self { 125 pub fn new(
126 pin: impl PeripheralBorrow<Target = T> + 'd,
127 initial_output: Level,
128 drive: OutputDrive,
129 ) -> Self {
130 unborrow!(pin);
131
117 match initial_output { 132 match initial_output {
118 Level::High => pin.set_high(), 133 Level::High => pin.set_high(),
119 Level::Low => pin.set_low(), 134 Level::Low => pin.set_low(),
@@ -139,17 +154,20 @@ impl<T: Pin> Output<T> {
139 w 154 w
140 }); 155 });
141 156
142 Self { pin } 157 Self {
158 pin,
159 phantom: PhantomData,
160 }
143 } 161 }
144} 162}
145 163
146impl<T: Pin> Drop for Output<T> { 164impl<'d, T: Pin> Drop for Output<'d, T> {
147 fn drop(&mut self) { 165 fn drop(&mut self) {
148 self.pin.conf().reset(); 166 self.pin.conf().reset();
149 } 167 }
150} 168}
151 169
152impl<T: Pin> OutputPin for Output<T> { 170impl<'d, T: Pin> OutputPin for Output<'d, T> {
153 type Error = Infallible; 171 type Error = Infallible;
154 172
155 /// Set the output as high. 173 /// Set the output as high.
@@ -175,7 +193,7 @@ impl<T: Pin> OutputPin for Output<T> {
175 } 193 }
176} 194}
177 195
178impl<T: Pin> StatefulOutputPin for Output<T> { 196impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> {
179 /// Is the output pin set as high? 197 /// Is the output pin set as high?
180 fn is_set_high(&self) -> Result<bool, Self::Error> { 198 fn is_set_high(&self) -> Result<bool, Self::Error> {
181 self.is_set_low().map(|v| !v) 199 self.is_set_low().map(|v| !v)
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index dc96a7eba..9a7642c51 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -9,7 +9,7 @@ use core::ptr;
9use core::task::{Context, Poll}; 9use core::task::{Context, Poll};
10use embassy::interrupt::InterruptExt; 10use embassy::interrupt::InterruptExt;
11use embassy::traits::gpio::{WaitForHigh, WaitForLow}; 11use embassy::traits::gpio::{WaitForHigh, WaitForLow};
12use embassy::util::{AtomicWakerRegistration, Signal}; 12use embassy::util::{AtomicWakerRegistration, PeripheralBorrow, Signal};
13use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; 13use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
14 14
15use crate::gpio::sealed::Pin as _; 15use crate::gpio::sealed::Pin as _;
@@ -338,18 +338,19 @@ impl<C: ChannelID, T> OutputChannel<C, T> {
338 */ 338 */
339 339
340/// GPIO input driver with support 340/// GPIO input driver with support
341pub struct PortInput<T: GpioPin> { 341pub struct PortInput<'d, T: GpioPin> {
342 pin: Input<T>, 342 pin: Input<'d, T>,
343} 343}
344impl<T: GpioPin> Unpin for PortInput<T> {}
345 344
346impl<T: GpioPin> PortInput<T> { 345impl<'d, T: GpioPin> Unpin for PortInput<'d, T> {}
347 pub fn new(_init: Initialized, pin: Input<T>) -> Self { 346
347impl<'d, T: GpioPin> PortInput<'d, T> {
348 pub fn new(_init: Initialized, pin: Input<'d, T>) -> Self {
348 Self { pin } 349 Self { pin }
349 } 350 }
350} 351}
351 352
352impl<T: GpioPin> InputPin for PortInput<T> { 353impl<'d, T: GpioPin> InputPin for PortInput<'d, T> {
353 type Error = Infallible; 354 type Error = Infallible;
354 355
355 fn is_high(&self) -> Result<bool, Self::Error> { 356 fn is_high(&self) -> Result<bool, Self::Error> {
@@ -361,7 +362,7 @@ impl<T: GpioPin> InputPin for PortInput<T> {
361 } 362 }
362} 363}
363 364
364impl<T: GpioPin> WaitForHigh for PortInput<T> { 365impl<'d, T: GpioPin> WaitForHigh for PortInput<'d, T> {
365 type Future<'a> = PortInputFuture<'a>; 366 type Future<'a> = PortInputFuture<'a>;
366 367
367 fn wait_for_high<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { 368 fn wait_for_high<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
@@ -374,7 +375,7 @@ impl<T: GpioPin> WaitForHigh for PortInput<T> {
374 } 375 }
375} 376}
376 377
377impl<T: GpioPin> WaitForLow for PortInput<T> { 378impl<'d, T: GpioPin> WaitForLow for PortInput<'d, T> {
378 type Future<'a> = PortInputFuture<'a>; 379 type Future<'a> = PortInputFuture<'a>;
379 380
380 fn wait_for_low<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { 381 fn wait_for_low<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {