diff options
Diffstat (limited to 'embassy-rp/src/gpio.rs')
| -rw-r--r-- | embassy-rp/src/gpio.rs | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs index af0837f6a..f79bf8948 100644 --- a/embassy-rp/src/gpio.rs +++ b/embassy-rp/src/gpio.rs | |||
| @@ -26,6 +26,7 @@ static QSPI_WAKERS: [AtomicWaker; QSPI_PIN_COUNT] = [const { AtomicWaker::new() | |||
| 26 | 26 | ||
| 27 | /// Represents a digital input or output level. | 27 | /// Represents a digital input or output level. |
| 28 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | 28 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] |
| 29 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 29 | pub enum Level { | 30 | pub enum Level { |
| 30 | /// Logical low. | 31 | /// Logical low. |
| 31 | Low, | 32 | Low, |
| @@ -53,6 +54,7 @@ impl From<Level> for bool { | |||
| 53 | 54 | ||
| 54 | /// Represents a pull setting for an input. | 55 | /// Represents a pull setting for an input. |
| 55 | #[derive(Debug, Clone, Copy, Eq, PartialEq)] | 56 | #[derive(Debug, Clone, Copy, Eq, PartialEq)] |
| 57 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 56 | pub enum Pull { | 58 | pub enum Pull { |
| 57 | /// No pull. | 59 | /// No pull. |
| 58 | None, | 60 | None, |
| @@ -64,6 +66,7 @@ pub enum Pull { | |||
| 64 | 66 | ||
| 65 | /// Drive strength of an output | 67 | /// Drive strength of an output |
| 66 | #[derive(Debug, Eq, PartialEq)] | 68 | #[derive(Debug, Eq, PartialEq)] |
| 69 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 67 | pub enum Drive { | 70 | pub enum Drive { |
| 68 | /// 2 mA drive. | 71 | /// 2 mA drive. |
| 69 | _2mA, | 72 | _2mA, |
| @@ -76,6 +79,7 @@ pub enum Drive { | |||
| 76 | } | 79 | } |
| 77 | /// Slew rate of an output | 80 | /// Slew rate of an output |
| 78 | #[derive(Debug, Eq, PartialEq)] | 81 | #[derive(Debug, Eq, PartialEq)] |
| 82 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 79 | pub enum SlewRate { | 83 | pub enum SlewRate { |
| 80 | /// Fast slew rate. | 84 | /// Fast slew rate. |
| 81 | Fast, | 85 | Fast, |
| @@ -85,6 +89,7 @@ pub enum SlewRate { | |||
| 85 | 89 | ||
| 86 | /// A GPIO bank with up to 32 pins. | 90 | /// A GPIO bank with up to 32 pins. |
| 87 | #[derive(Debug, Eq, PartialEq)] | 91 | #[derive(Debug, Eq, PartialEq)] |
| 92 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 88 | pub enum Bank { | 93 | pub enum Bank { |
| 89 | /// Bank 0. | 94 | /// Bank 0. |
| 90 | Bank0 = 0, | 95 | Bank0 = 0, |
| @@ -108,6 +113,8 @@ pub struct DormantWakeConfig { | |||
| 108 | } | 113 | } |
| 109 | 114 | ||
| 110 | /// GPIO input driver. | 115 | /// GPIO input driver. |
| 116 | #[derive(Debug)] | ||
| 117 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 111 | pub struct Input<'d> { | 118 | pub struct Input<'d> { |
| 112 | pin: Flex<'d>, | 119 | pin: Flex<'d>, |
| 113 | } | 120 | } |
| @@ -146,6 +153,12 @@ impl<'d> Input<'d> { | |||
| 146 | self.pin.get_level() | 153 | self.pin.get_level() |
| 147 | } | 154 | } |
| 148 | 155 | ||
| 156 | /// Configure the input logic inversion of this pin. | ||
| 157 | #[inline] | ||
| 158 | pub fn set_inversion(&mut self, invert: bool) { | ||
| 159 | self.pin.set_input_inversion(invert) | ||
| 160 | } | ||
| 161 | |||
| 149 | /// Wait until the pin is high. If it is already high, return immediately. | 162 | /// Wait until the pin is high. If it is already high, return immediately. |
| 150 | #[inline] | 163 | #[inline] |
| 151 | pub async fn wait_for_high(&mut self) { | 164 | pub async fn wait_for_high(&mut self) { |
| @@ -352,6 +365,8 @@ impl<'d> Future for InputFuture<'d> { | |||
| 352 | } | 365 | } |
| 353 | 366 | ||
| 354 | /// GPIO output driver. | 367 | /// GPIO output driver. |
| 368 | #[derive(Debug)] | ||
| 369 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 355 | pub struct Output<'d> { | 370 | pub struct Output<'d> { |
| 356 | pin: Flex<'d>, | 371 | pin: Flex<'d>, |
| 357 | } | 372 | } |
| @@ -382,6 +397,12 @@ impl<'d> Output<'d> { | |||
| 382 | self.pin.set_slew_rate(slew_rate) | 397 | self.pin.set_slew_rate(slew_rate) |
| 383 | } | 398 | } |
| 384 | 399 | ||
| 400 | /// Configure the output logic inversion of this pin. | ||
| 401 | #[inline] | ||
| 402 | pub fn set_inversion(&mut self, invert: bool) { | ||
| 403 | self.pin.set_output_inversion(invert) | ||
| 404 | } | ||
| 405 | |||
| 385 | /// Set the output as high. | 406 | /// Set the output as high. |
| 386 | #[inline] | 407 | #[inline] |
| 387 | pub fn set_high(&mut self) { | 408 | pub fn set_high(&mut self) { |
| @@ -433,6 +454,8 @@ impl<'d> Output<'d> { | |||
| 433 | } | 454 | } |
| 434 | 455 | ||
| 435 | /// GPIO output open-drain. | 456 | /// GPIO output open-drain. |
| 457 | #[derive(Debug)] | ||
| 458 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 436 | pub struct OutputOpenDrain<'d> { | 459 | pub struct OutputOpenDrain<'d> { |
| 437 | pin: Flex<'d>, | 460 | pin: Flex<'d>, |
| 438 | } | 461 | } |
| @@ -580,6 +603,8 @@ impl<'d> OutputOpenDrain<'d> { | |||
| 580 | /// This pin can be either an input or output pin. The output level register bit will remain | 603 | /// This pin can be either an input or output pin. The output level register bit will remain |
| 581 | /// set while not in output mode, so the pin's level will be 'remembered' when it is not in output | 604 | /// set while not in output mode, so the pin's level will be 'remembered' when it is not in output |
| 582 | /// mode. | 605 | /// mode. |
| 606 | #[derive(Debug)] | ||
| 607 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 583 | pub struct Flex<'d> { | 608 | pub struct Flex<'d> { |
| 584 | pin: Peri<'d, AnyPin>, | 609 | pin: Peri<'d, AnyPin>, |
| 585 | } | 610 | } |
| @@ -685,6 +710,30 @@ impl<'d> Flex<'d> { | |||
| 685 | self.pin.sio_oe().value_xor().write_value(self.bit()) | 710 | self.pin.sio_oe().value_xor().write_value(self.bit()) |
| 686 | } | 711 | } |
| 687 | 712 | ||
| 713 | /// Configure the input logic inversion of this pin. | ||
| 714 | #[inline] | ||
| 715 | pub fn set_input_inversion(&mut self, invert: bool) { | ||
| 716 | self.pin.gpio().ctrl().modify(|w| { | ||
| 717 | w.set_inover(if invert { | ||
| 718 | pac::io::vals::Inover::INVERT | ||
| 719 | } else { | ||
| 720 | pac::io::vals::Inover::NORMAL | ||
| 721 | }) | ||
| 722 | }); | ||
| 723 | } | ||
| 724 | |||
| 725 | /// Configure the output logic inversion of this pin. | ||
| 726 | #[inline] | ||
| 727 | pub fn set_output_inversion(&mut self, invert: bool) { | ||
| 728 | self.pin.gpio().ctrl().modify(|w| { | ||
| 729 | w.set_outover(if invert { | ||
| 730 | pac::io::vals::Outover::INVERT | ||
| 731 | } else { | ||
| 732 | pac::io::vals::Outover::NORMAL | ||
| 733 | }) | ||
| 734 | }); | ||
| 735 | } | ||
| 736 | |||
| 688 | /// Get whether the pin input level is high. | 737 | /// Get whether the pin input level is high. |
| 689 | #[inline] | 738 | #[inline] |
| 690 | pub fn is_high(&self) -> bool { | 739 | pub fn is_high(&self) -> bool { |
| @@ -815,6 +864,8 @@ impl<'d> Drop for Flex<'d> { | |||
| 815 | self.pin.pad_ctrl().write(|_| {}); | 864 | self.pin.pad_ctrl().write(|_| {}); |
| 816 | self.pin.gpio().ctrl().write(|w| { | 865 | self.pin.gpio().ctrl().write(|w| { |
| 817 | w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL as _); | 866 | w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL as _); |
| 867 | w.set_inover(pac::io::vals::Inover::NORMAL); | ||
| 868 | w.set_outover(pac::io::vals::Outover::NORMAL); | ||
| 818 | }); | 869 | }); |
| 819 | self.pin.io().int_dormant_wake().inte(idx / 8).write_clear(|w| { | 870 | self.pin.io().int_dormant_wake().inte(idx / 8).write_clear(|w| { |
| 820 | w.set_edge_high(idx % 8, true); | 871 | w.set_edge_high(idx % 8, true); |
| @@ -826,6 +877,8 @@ impl<'d> Drop for Flex<'d> { | |||
| 826 | } | 877 | } |
| 827 | 878 | ||
| 828 | /// Dormant wake driver. | 879 | /// Dormant wake driver. |
| 880 | #[derive(Debug)] | ||
| 881 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 829 | pub struct DormantWake<'w> { | 882 | pub struct DormantWake<'w> { |
| 830 | pin: Peri<'w, AnyPin>, | 883 | pin: Peri<'w, AnyPin>, |
| 831 | cfg: DormantWakeConfig, | 884 | cfg: DormantWakeConfig, |
| @@ -932,6 +985,8 @@ pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static { | |||
| 932 | } | 985 | } |
| 933 | 986 | ||
| 934 | /// Type-erased GPIO pin | 987 | /// Type-erased GPIO pin |
| 988 | #[derive(Debug)] | ||
| 989 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 935 | pub struct AnyPin { | 990 | pub struct AnyPin { |
| 936 | pin_bank: u8, | 991 | pin_bank: u8, |
| 937 | } | 992 | } |
