nrf52840_platform/
gpio.rs

1use crate::error;
2use core::fmt;
3use core::pin;
4use core::task;
5use nrf52840_hal::gpio;
6use nrf52840_hal::gpio::p0;
7use nrf52840_hal::gpio::p1;
8
9pub struct Pin<P>(P)
10where
11    P: Unpin + ?Sized;
12
13macro_rules! gpio {
14    ($($m:ident: $mtyp:ident => [$($name:ident: $typ:ident,)*],)*) => {
15    $(
16        #[derive(Debug)]
17        pub(crate) struct $mtyp {
18            $(pub(crate) $name: Option<Pin<$m::$typ<gpio::Input<gpio::Floating>>>>,)*
19        }
20
21        impl $mtyp {
22            pub(crate) fn new(port: nrf52840_hal::nrf52840_pac::$mtyp) -> Self {
23                use gpio::GpioExt;
24
25                let port = port.split();
26
27                Self {
28                    $($name: Some(Pin(port.$name)),)*
29                }
30            }
31        }
32    )*
33    $($(
34        impl<S> embedded_platform::gpio::Pin for Pin<$m::$typ<S>> where S: Unpin {
35            type Error = error::Error;
36        }
37
38        impl<S> embedded_platform::gpio::InputPin for Pin<$m::$typ<gpio::Input<S>>> where S: Unpin {
39            fn poll_get(
40                self: pin::Pin<&mut Self>,
41                _cx: &mut task::Context<'_>,
42            ) -> task::Poll<Result<bool, Self::Error>> {
43                use embedded_hal::digital::v2::InputPin;
44                task::Poll::Ready(Ok(self.0.is_high().unwrap()))
45            }
46        }
47
48        impl<S> embedded_platform::gpio::OutputPin for Pin<$m::$typ<gpio::Output<S>>> where S: Unpin {
49            fn poll_set(
50                mut self: pin::Pin<&mut Self>,
51                _cx: &mut task::Context<'_>,
52                high: bool,
53            ) -> task::Poll<Result<(), Self::Error>> {
54                use embedded_hal::digital::v2::OutputPin;
55
56                let this = &mut *self;
57                task::Poll::Ready(Ok(if high { this.0.set_high().unwrap() } else { this.0.set_low().unwrap() }))
58            }
59        }
60
61        impl<S> embedded_platform::gpio::IntoFloatingInputPin for Pin<$m::$typ<S>> where S: Unpin {
62            type FloatingInputPin = Pin<$m::$typ<gpio::Input<gpio::Floating>>>;
63
64            fn into_floating_input_pin(self) -> Result<Self::FloatingInputPin, Self::Error> {
65                Ok(Pin(self.0.into_floating_input()))
66            }
67        }
68
69        impl<S> embedded_platform::gpio::IntoPullDownInputPin for Pin<$m::$typ<S>> where S: Unpin {
70            type PullDownInputPin = Pin<$m::$typ<gpio::Input<gpio::PullDown>>>;
71
72            fn into_pull_down_input_pin(self) -> Result<Self::PullDownInputPin, Self::Error> {
73                Ok(Pin(self.0.into_pulldown_input()))
74            }
75        }
76
77        impl<S> embedded_platform::gpio::IntoPullUpInputPin for Pin<$m::$typ<S>> where S: Unpin {
78            type PullUpInputPin = Pin<$m::$typ<gpio::Input<gpio::PullUp>>>;
79
80            fn into_pull_up_input_pin(self) -> Result<Self::PullUpInputPin, Self::Error> {
81                Ok(Pin(self.0.into_pullup_input()))
82            }
83        }
84
85        impl<S> embedded_platform::gpio::IntoPushPullOutputPin for Pin<$m::$typ<S>> where S: Unpin {
86            type PushPullOutputPin = Pin<$m::$typ<gpio::Output<gpio::PushPull>>>;
87
88            fn into_push_pull_output_pin(self, initial_high: bool) -> Result<Self::PushPullOutputPin, Self::Error> {
89                Ok(Pin(self.0.into_push_pull_output(if initial_high { gpio::Level::High } else { gpio::Level::Low })))
90            }
91        }
92
93        impl<S> embedded_platform::gpio::IntoOpenDrainOutputPin for Pin<$m::$typ<S>> where S: Unpin {
94            type OpenDrainOutputPin = Pin<$m::$typ<gpio::Output<gpio::OpenDrain>>>;
95
96            fn into_open_drain_output_pin(self, initial_high: bool) -> Result<Self::OpenDrainOutputPin, Self::Error> {
97                Ok(Pin(self.0.into_open_drain_output(gpio::OpenDrainConfig::Disconnect0Standard1, if initial_high { gpio::Level::High } else { gpio::Level::Low })))
98            }
99        }
100
101        impl<S> fmt::Debug for Pin<$m::$typ<gpio::Input<S>>> where S: Unpin {
102            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103                // TODO: display current GPIO state
104                f.debug_struct(stringify!($typ)).finish()
105            }
106        }
107
108        impl<S> fmt::Debug for Pin<$m::$typ<gpio::Output<S>>> where S: Unpin {
109            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110                // TODO: display current GPIO state
111                f.debug_struct(stringify!($typ)).finish()
112            }
113        }
114    )*)*
115    };
116}
117
118gpio! {
119    p0: P0 => [
120        p0_00: P0_00,
121        p0_01: P0_01,
122        p0_02: P0_02,
123        p0_03: P0_03,
124        p0_04: P0_04,
125        p0_05: P0_05,
126        p0_06: P0_06,
127        p0_07: P0_07,
128        p0_08: P0_08,
129        p0_09: P0_09,
130        p0_10: P0_10,
131        p0_11: P0_11,
132        p0_12: P0_12,
133        p0_13: P0_13,
134        p0_14: P0_14,
135        p0_15: P0_15,
136        p0_16: P0_16,
137        p0_17: P0_17,
138        p0_18: P0_18,
139        p0_19: P0_19,
140        p0_20: P0_20,
141        p0_21: P0_21,
142        p0_22: P0_22,
143        p0_23: P0_23,
144        p0_24: P0_24,
145        p0_25: P0_25,
146        p0_26: P0_26,
147        p0_27: P0_27,
148        p0_28: P0_28,
149        p0_29: P0_29,
150        p0_30: P0_30,
151        p0_31: P0_31,
152    ],
153    p1: P1 => [
154        p1_00: P1_00,
155        p1_01: P1_01,
156        p1_02: P1_02,
157        p1_03: P1_03,
158        p1_04: P1_04,
159        p1_05: P1_05,
160        p1_06: P1_06,
161        p1_07: P1_07,
162        p1_08: P1_08,
163        p1_09: P1_09,
164        p1_10: P1_10,
165        p1_11: P1_11,
166        p1_12: P1_12,
167        p1_13: P1_13,
168        p1_14: P1_14,
169        p1_15: P1_15,
170    ],
171}