aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-01-14 22:02:00 +0100
committerDario Nieuwenhuis <[email protected]>2022-01-19 17:59:55 +0100
commit58fc64722c65bbdc209ae0fd1700f03702bbcd08 (patch)
tree77f9412b47259cd4cf4170b0a257b371398d4f2c /embassy-stm32/src
parent52e156b429417bde59d0ea67d11256866f1dcec9 (diff)
stm32/gpio: expose all functionality as inherent methods.
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/exti.rs12
-rw-r--r--embassy-stm32/src/gpio.rs230
2 files changed, 165 insertions, 77 deletions
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
index 552433b87..eded6ba71 100644
--- a/embassy-stm32/src/exti.rs
+++ b/embassy-stm32/src/exti.rs
@@ -94,17 +94,25 @@ impl<'d, T: GpioPin> ExtiInput<'d, T> {
94 pub fn new(pin: Input<'d, T>, _ch: impl Unborrow<Target = T::ExtiChannel> + 'd) -> Self { 94 pub fn new(pin: Input<'d, T>, _ch: impl Unborrow<Target = T::ExtiChannel> + 'd) -> Self {
95 Self { pin } 95 Self { pin }
96 } 96 }
97
98 pub fn is_high(&self) -> bool {
99 self.pin.is_high()
100 }
101
102 pub fn is_low(&self) -> bool {
103 self.pin.is_low()
104 }
97} 105}
98 106
99impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> { 107impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> {
100 type Error = Infallible; 108 type Error = Infallible;
101 109
102 fn is_high(&self) -> Result<bool, Self::Error> { 110 fn is_high(&self) -> Result<bool, Self::Error> {
103 self.pin.is_high() 111 Ok(self.is_high())
104 } 112 }
105 113
106 fn is_low(&self) -> Result<bool, Self::Error> { 114 fn is_low(&self) -> Result<bool, Self::Error> {
107 self.pin.is_low() 115 Ok(self.is_low())
108 } 116 }
109} 117}
110 118
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index 6b4a9285f..57b9ba6b7 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -3,7 +3,7 @@ use core::convert::Infallible;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use embassy::util::Unborrow; 4use embassy::util::Unborrow;
5use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; 5use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
6use embedded_hal::digital::v2::{toggleable, InputPin, OutputPin, StatefulOutputPin}; 6use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
7 7
8use crate::pac; 8use crate::pac;
9use crate::pac::gpio::{self, vals}; 9use crate::pac::gpio::{self, vals};
@@ -113,6 +113,15 @@ impl<'d, T: Pin> Input<'d, T> {
113 phantom: PhantomData, 113 phantom: PhantomData,
114 } 114 }
115 } 115 }
116
117 pub fn is_high(&self) -> bool {
118 !self.is_low()
119 }
120
121 pub fn is_low(&self) -> bool {
122 let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) };
123 state == vals::Idr::LOW
124 }
116} 125}
117 126
118impl<'d, T: Pin> Drop for Input<'d, T> { 127impl<'d, T: Pin> Drop for Input<'d, T> {
@@ -132,19 +141,6 @@ impl<'d, T: Pin> Drop for Input<'d, T> {
132 } 141 }
133} 142}
134 143
135impl<'d, T: Pin> InputPin for Input<'d, T> {
136 type Error = Infallible;
137
138 fn is_high(&self) -> Result<bool, Self::Error> {
139 self.is_low().map(|v| !v)
140 }
141
142 fn is_low(&self) -> Result<bool, Self::Error> {
143 let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) };
144 Ok(state == vals::Idr::LOW)
145 }
146}
147
148/// Digital input or output level. 144/// Digital input or output level.
149#[derive(Debug, Eq, PartialEq)] 145#[derive(Debug, Eq, PartialEq)]
150#[cfg_attr(feature = "defmt", derive(defmt::Format))] 146#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -191,6 +187,36 @@ impl<'d, T: Pin> Output<'d, T> {
191 phantom: PhantomData, 187 phantom: PhantomData,
192 } 188 }
193 } 189 }
190
191 /// Set the output as high.
192 pub fn set_high(&mut self) {
193 self.pin.set_high();
194 }
195
196 /// Set the output as low.
197 pub fn set_low(&mut self) {
198 self.pin.set_low();
199 }
200
201 /// Is the output pin set as high?
202 pub fn is_set_high(&self) -> bool {
203 !self.is_set_low()
204 }
205
206 /// Is the output pin set as low?
207 pub fn is_set_low(&self) -> bool {
208 let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) };
209 state == vals::Odr::LOW
210 }
211
212 /// Toggle pin output
213 pub fn toggle(&mut self) {
214 if self.is_set_low() {
215 self.set_high()
216 } else {
217 self.set_low()
218 }
219 }
194} 220}
195 221
196impl<'d, T: Pin> Drop for Output<'d, T> { 222impl<'d, T: Pin> Drop for Output<'d, T> {
@@ -214,37 +240,6 @@ impl<'d, T: Pin> Drop for Output<'d, T> {
214 } 240 }
215} 241}
216 242
217impl<'d, T: Pin> OutputPin for Output<'d, T> {
218 type Error = Infallible;
219
220 /// Set the output as high.
221 fn set_high(&mut self) -> Result<(), Self::Error> {
222 self.pin.set_high();
223 Ok(())
224 }
225
226 /// Set the output as low.
227 fn set_low(&mut self) -> Result<(), Self::Error> {
228 self.pin.set_low();
229 Ok(())
230 }
231}
232
233impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> {
234 /// Is the output pin set as high?
235 fn is_set_high(&self) -> Result<bool, Self::Error> {
236 self.is_set_low().map(|v| !v)
237 }
238
239 /// Is the output pin set as low?
240 fn is_set_low(&self) -> Result<bool, Self::Error> {
241 let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) };
242 Ok(state == vals::Odr::LOW)
243 }
244}
245
246impl<'d, T: Pin> toggleable::Default for Output<'d, T> {}
247
248/// GPIO output open-drain driver. 243/// GPIO output open-drain driver.
249pub struct OutputOpenDrain<'d, T: Pin> { 244pub struct OutputOpenDrain<'d, T: Pin> {
250 pub(crate) pin: T, 245 pub(crate) pin: T,
@@ -294,6 +289,45 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> {
294 phantom: PhantomData, 289 phantom: PhantomData,
295 } 290 }
296 } 291 }
292
293 pub fn is_high(&self) -> bool {
294 !self.is_low()
295 }
296
297 pub fn is_low(&self) -> bool {
298 let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) };
299 state == vals::Idr::LOW
300 }
301
302 /// Set the output as high.
303 pub fn set_high(&mut self) {
304 self.pin.set_high();
305 }
306
307 /// Set the output as low.
308 pub fn set_low(&mut self) {
309 self.pin.set_low();
310 }
311
312 /// Is the output pin set as high?
313 pub fn is_set_high(&self) -> bool {
314 !self.is_set_low()
315 }
316
317 /// Is the output pin set as low?
318 pub fn is_set_low(&self) -> bool {
319 let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) };
320 state == vals::Odr::LOW
321 }
322
323 /// Toggle pin output
324 pub fn toggle(&mut self) {
325 if self.is_set_low() {
326 self.set_high()
327 } else {
328 self.set_low()
329 }
330 }
297} 331}
298 332
299impl<'d, T: Pin> Drop for OutputOpenDrain<'d, T> { 333impl<'d, T: Pin> Drop for OutputOpenDrain<'d, T> {
@@ -317,36 +351,6 @@ impl<'d, T: Pin> Drop for OutputOpenDrain<'d, T> {
317 } 351 }
318} 352}
319 353
320impl<'d, T: Pin> OutputPin for OutputOpenDrain<'d, T> {
321 type Error = Infallible;
322
323 /// Set the output as high.
324 fn set_high(&mut self) -> Result<(), Self::Error> {
325 self.pin.set_high();
326 Ok(())
327 }
328
329 /// Set the output as low.
330 fn set_low(&mut self) -> Result<(), Self::Error> {
331 self.pin.set_low();
332 Ok(())
333 }
334}
335
336impl<'d, T: Pin> InputPin for OutputOpenDrain<'d, T> {
337 type Error = Infallible;
338
339 fn is_high(&self) -> Result<bool, Self::Error> {
340 self.is_low().map(|v| !v)
341 }
342
343 fn is_low(&self) -> Result<bool, Self::Error> {
344 // NOTE(safety) Atomic read
345 let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as usize) };
346 Ok(state == vals::Idr::LOW)
347 }
348}
349
350pub(crate) mod sealed { 354pub(crate) mod sealed {
351 use super::*; 355 use super::*;
352 356
@@ -612,3 +616,79 @@ pub(crate) unsafe fn init() {
612 }; 616 };
613 } 617 }
614} 618}
619
620mod eh02 {
621 use super::*;
622
623 impl<'d, T: Pin> InputPin for Input<'d, T> {
624 type Error = Infallible;
625
626 fn is_high(&self) -> Result<bool, Self::Error> {
627 Ok(self.is_high())
628 }
629
630 fn is_low(&self) -> Result<bool, Self::Error> {
631 Ok(self.is_low())
632 }
633 }
634
635 impl<'d, T: Pin> OutputPin for Output<'d, T> {
636 type Error = Infallible;
637
638 fn set_high(&mut self) -> Result<(), Self::Error> {
639 Ok(self.set_high())
640 }
641
642 fn set_low(&mut self) -> Result<(), Self::Error> {
643 Ok(self.set_low())
644 }
645 }
646
647 impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> {
648 fn is_set_high(&self) -> Result<bool, Self::Error> {
649 Ok(self.is_set_high())
650 }
651
652 /// Is the output pin set as low?
653 fn is_set_low(&self) -> Result<bool, Self::Error> {
654 Ok(self.is_set_low())
655 }
656 }
657
658 impl<'d, T: Pin> ToggleableOutputPin for Output<'d, T> {
659 type Error = Infallible;
660 fn toggle(&mut self) -> Result<(), Self::Error> {
661 Ok(self.toggle())
662 }
663 }
664
665 impl<'d, T: Pin> OutputPin for OutputOpenDrain<'d, T> {
666 type Error = Infallible;
667
668 fn set_high(&mut self) -> Result<(), Self::Error> {
669 Ok(self.set_high())
670 }
671
672 fn set_low(&mut self) -> Result<(), Self::Error> {
673 Ok(self.set_low())
674 }
675 }
676
677 impl<'d, T: Pin> StatefulOutputPin for OutputOpenDrain<'d, T> {
678 fn is_set_high(&self) -> Result<bool, Self::Error> {
679 Ok(self.is_set_high())
680 }
681
682 /// Is the output pin set as low?
683 fn is_set_low(&self) -> Result<bool, Self::Error> {
684 Ok(self.is_set_low())
685 }
686 }
687
688 impl<'d, T: Pin> ToggleableOutputPin for OutputOpenDrain<'d, T> {
689 type Error = Infallible;
690 fn toggle(&mut self) -> Result<(), Self::Error> {
691 Ok(self.toggle())
692 }
693 }
694}