|
1 | 1 | //! # General Purpose I/Os
|
| 2 | +//! |
| 3 | +//! # Interfacing with v1 traits |
| 4 | +//! |
| 5 | +//! `embedded-hal` has two versions of the digital traits, `v2` which is used |
| 6 | +//! by this crate and `v1` which is deprecated but still used by a lot of drivers. |
| 7 | +//! If you want to use such a driver with this crate, you need to convert the digital pins to the `v1` type. |
| 8 | +//! |
| 9 | +//! This is done using `embedded-hal::digital::v1_compat::OldOutputPin`. For example: |
| 10 | +//! |
| 11 | +//! ```rust |
| 12 | +//! let nss = gpioa.pa4.into_push_pull_output(&mut gpioa.crl); |
| 13 | +//! let mut mfrc522 = Mfrc522::new(spi, OldOutputPin::from(nss)).unwrap(); |
| 14 | +//! ``` |
| 15 | +//! |
2 | 16 |
|
3 | 17 | use core::marker::PhantomData;
|
4 | 18 |
|
@@ -63,9 +77,10 @@ macro_rules! gpio {
|
63 | 77 | ]) => {
|
64 | 78 | /// GPIO
|
65 | 79 | pub mod $gpiox {
|
| 80 | + use void::Void; |
66 | 81 | use core::marker::PhantomData;
|
67 | 82 |
|
68 |
| - use crate::hal::digital::{InputPin, OutputPin, StatefulOutputPin, toggleable}; |
| 83 | + use crate::hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, toggleable}; |
69 | 84 | use crate::pac::{$gpioy, $GPIOX};
|
70 | 85 |
|
71 | 86 | use crate::rcc::APB2;
|
@@ -143,49 +158,52 @@ macro_rules! gpio {
|
143 | 158 | }
|
144 | 159 |
|
145 | 160 | impl<MODE> OutputPin for $PXx<Output<MODE>> {
|
146 |
| - fn set_high(&mut self) { |
| 161 | + type Error = Void; |
| 162 | + fn set_high(&mut self) -> Result<(), Self::Error> { |
147 | 163 | // NOTE(unsafe) atomic write to a stateless register
|
148 |
| - unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << self.i)) } |
| 164 | + Ok(unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << self.i)) }) |
149 | 165 | }
|
150 | 166 |
|
151 |
| - fn set_low(&mut self) { |
| 167 | + fn set_low(&mut self) -> Result<(), Self::Error> { |
152 | 168 | // NOTE(unsafe) atomic write to a stateless register
|
153 |
| - unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + self.i))) } |
| 169 | + Ok(unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + self.i))) }) |
154 | 170 | }
|
155 | 171 | }
|
156 | 172 |
|
157 | 173 | impl<MODE> InputPin for $PXx<Input<MODE>> {
|
158 |
| - fn is_high(&self) -> bool { |
159 |
| - !self.is_low() |
| 174 | + type Error = Void; |
| 175 | + fn is_high(&self) -> Result<bool, Self::Error> { |
| 176 | + self.is_low().map(|b| !b) |
160 | 177 | }
|
161 | 178 |
|
162 |
| - fn is_low(&self) -> bool { |
| 179 | + fn is_low(&self) -> Result<bool, Self::Error> { |
163 | 180 | // NOTE(unsafe) atomic read with no side effects
|
164 |
| - unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 } |
| 181 | + Ok(unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 }) |
165 | 182 | }
|
166 | 183 | }
|
167 | 184 |
|
168 | 185 | impl <MODE> StatefulOutputPin for $PXx<Output<MODE>> {
|
169 |
| - fn is_set_high(&self) -> bool { |
170 |
| - !self.is_set_low() |
| 186 | + fn is_set_high(&self) -> Result<bool, Self::Error> { |
| 187 | + self.is_set_low().map(|b| !b) |
171 | 188 | }
|
172 | 189 |
|
173 |
| - fn is_set_low(&self) -> bool { |
| 190 | + fn is_set_low(&self) -> Result<bool, Self::Error> { |
174 | 191 | // NOTE(unsafe) atomic read with no side effects
|
175 |
| - unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << self.i) == 0 } |
| 192 | + Ok(unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << self.i) == 0 }) |
176 | 193 | }
|
177 | 194 | }
|
178 | 195 |
|
179 | 196 | impl <MODE> toggleable::Default for $PXx<Output<MODE>> {}
|
180 | 197 |
|
181 | 198 | impl InputPin for $PXx<Output<OpenDrain>> {
|
182 |
| - fn is_high(&self) -> bool { |
183 |
| - !self.is_low() |
| 199 | + type Error = Void; |
| 200 | + fn is_high(&self) -> Result<bool, Self::Error> { |
| 201 | + self.is_low().map(|b| !b) |
184 | 202 | }
|
185 | 203 |
|
186 |
| - fn is_low(&self) -> bool { |
| 204 | + fn is_low(&self) -> Result<bool, Self::Error> { |
187 | 205 | // NOTE(unsafe) atomic read with no side effects
|
188 |
| - unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 } |
| 206 | + Ok(unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 }) |
189 | 207 | }
|
190 | 208 | }
|
191 | 209 |
|
@@ -354,7 +372,7 @@ macro_rules! gpio {
|
354 | 372 | match initial_state {
|
355 | 373 | State::High => res.set_high(),
|
356 | 374 | State::Low => res.set_low(),
|
357 |
| - } |
| 375 | + }.unwrap(); |
358 | 376 |
|
359 | 377 | cr
|
360 | 378 | .cr()
|
@@ -392,7 +410,7 @@ macro_rules! gpio {
|
392 | 410 | match initial_state {
|
393 | 411 | State::High => res.set_high(),
|
394 | 412 | State::Low => res.set_low(),
|
395 |
| - } |
| 413 | + }.unwrap(); |
396 | 414 |
|
397 | 415 | cr
|
398 | 416 | .cr()
|
@@ -437,72 +455,76 @@ macro_rules! gpio {
|
437 | 455 | }
|
438 | 456 |
|
439 | 457 | impl<MODE> OutputPin for $PXi<Output<MODE>> {
|
440 |
| - fn set_high(&mut self) { |
| 458 | + type Error = Void; |
| 459 | + fn set_high(&mut self) -> Result<(), Self::Error> { |
441 | 460 | // NOTE(unsafe) atomic write to a stateless register
|
442 |
| - unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) } |
| 461 | + Ok(unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) }) |
443 | 462 | }
|
444 | 463 |
|
445 |
| - fn set_low(&mut self) { |
| 464 | + fn set_low(&mut self) -> Result<(), Self::Error> { |
446 | 465 | // NOTE(unsafe) atomic write to a stateless register
|
447 |
| - unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + $i))) } |
| 466 | + Ok(unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + $i))) }) |
448 | 467 | }
|
449 | 468 | }
|
450 | 469 |
|
451 | 470 | impl<MODE> StatefulOutputPin for $PXi<Output<MODE>> {
|
452 |
| - fn is_set_high(&self) -> bool { |
453 |
| - !self.is_set_low() |
| 471 | + fn is_set_high(&self) -> Result<bool, Self::Error> { |
| 472 | + self.is_set_low().map(|b| !b) |
454 | 473 | }
|
455 | 474 |
|
456 |
| - fn is_set_low(&self) -> bool { |
| 475 | + fn is_set_low(&self) -> Result<bool, Self::Error> { |
457 | 476 | // NOTE(unsafe) atomic read with no side effects
|
458 |
| - unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << $i) == 0 } |
| 477 | + Ok(unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << $i) == 0 }) |
459 | 478 | }
|
460 | 479 | }
|
461 | 480 |
|
462 | 481 | impl<MODE> toggleable::Default for $PXi<Output<MODE>> {}
|
463 | 482 |
|
464 | 483 | impl<MODE> OutputPin for $PXi<Alternate<MODE>> {
|
465 |
| - fn set_high(&mut self) { |
| 484 | + type Error = Void; |
| 485 | + fn set_high(&mut self) -> Result<(), Self::Error> { |
466 | 486 | // NOTE(unsafe) atomic write to a stateless register
|
467 |
| - unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) } |
| 487 | + Ok(unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) }) |
468 | 488 | }
|
469 | 489 |
|
470 |
| - fn set_low(&mut self) { |
| 490 | + fn set_low(&mut self) -> Result<(), Self::Error> { |
471 | 491 | // NOTE(unsafe) atomic write to a stateless register
|
472 |
| - unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + $i))) } |
| 492 | + Ok(unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + $i))) }) |
473 | 493 | }
|
474 | 494 | }
|
475 | 495 |
|
476 | 496 | impl<MODE> StatefulOutputPin for $PXi<Alternate<MODE>> {
|
477 |
| - fn is_set_high(&self) -> bool { |
478 |
| - !self.is_set_low() |
| 497 | + fn is_set_high(&self) -> Result<bool, Self::Error> { |
| 498 | + self.is_set_low().map(|b| !b) |
479 | 499 | }
|
480 | 500 |
|
481 |
| - fn is_set_low(&self) -> bool { |
| 501 | + fn is_set_low(&self) -> Result<bool, Self::Error> { |
482 | 502 | // NOTE(unsafe) atomic read with no side effects
|
483 |
| - unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << $i) == 0 } |
| 503 | + Ok(unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << $i) == 0 }) |
484 | 504 | }
|
485 | 505 | }
|
486 | 506 |
|
487 | 507 | impl<MODE> InputPin for $PXi<Input<MODE>> {
|
488 |
| - fn is_high(&self) -> bool { |
489 |
| - !self.is_low() |
| 508 | + type Error = Void; |
| 509 | + fn is_high(&self) -> Result<bool, Self::Error> { |
| 510 | + self.is_low().map(|b| !b) |
490 | 511 | }
|
491 | 512 |
|
492 |
| - fn is_low(&self) -> bool { |
| 513 | + fn is_low(&self) -> Result<bool, Self::Error> { |
493 | 514 | // NOTE(unsafe) atomic read with no side effects
|
494 |
| - unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 } |
| 515 | + Ok(unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 }) |
495 | 516 | }
|
496 | 517 | }
|
497 | 518 |
|
498 | 519 | impl InputPin for $PXi<Output<OpenDrain>> {
|
499 |
| - fn is_high(&self) -> bool { |
500 |
| - !self.is_low() |
| 520 | + type Error = Void; |
| 521 | + fn is_high(&self) -> Result<bool, Self::Error> { |
| 522 | + self.is_low().map(|b| !b) |
501 | 523 | }
|
502 | 524 |
|
503 |
| - fn is_low(&self) -> bool { |
| 525 | + fn is_low(&self) -> Result<bool, Self::Error> { |
504 | 526 | // NOTE(unsafe) atomic read with no side effects
|
505 |
| - unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 } |
| 527 | + Ok(unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 }) |
506 | 528 | }
|
507 | 529 | }
|
508 | 530 | )+
|
|
0 commit comments