diff options
Diffstat (limited to 'embassy-nxp/src/gpio')
| -rw-r--r-- | embassy-nxp/src/gpio/lpc55.rs | 157 | ||||
| -rw-r--r-- | embassy-nxp/src/gpio/rt1xxx.rs | 54 |
2 files changed, 52 insertions, 159 deletions
diff --git a/embassy-nxp/src/gpio/lpc55.rs b/embassy-nxp/src/gpio/lpc55.rs index 36ea99d21..6be405463 100644 --- a/embassy-nxp/src/gpio/lpc55.rs +++ b/embassy-nxp/src/gpio/lpc55.rs | |||
| @@ -1,8 +1,11 @@ | |||
| 1 | use embassy_hal_internal::{impl_peripheral, PeripheralType}; | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use embassy_hal_internal::{PeripheralType, impl_peripheral}; | ||
| 4 | |||
| 5 | use crate::Peri; | ||
| 6 | use crate::pac::common::{RW, Reg}; | ||
| 3 | use crate::pac::iocon::vals::{PioDigimode, PioMode}; | 7 | use crate::pac::iocon::vals::{PioDigimode, PioMode}; |
| 4 | use crate::pac::{GPIO, IOCON, SYSCON}; | 8 | use crate::pac::{GPIO, IOCON, SYSCON, iocon}; |
| 5 | use crate::{peripherals, Peri}; | ||
| 6 | 9 | ||
| 7 | pub(crate) fn init() { | 10 | pub(crate) fn init() { |
| 8 | // Enable clocks for GPIO, PINT, and IOCON | 11 | // Enable clocks for GPIO, PINT, and IOCON |
| @@ -38,8 +41,8 @@ pub enum Pull { | |||
| 38 | /// The LPC55 boards have two GPIO banks, each with 32 pins. This enum represents the two banks. | 41 | /// The LPC55 boards have two GPIO banks, each with 32 pins. This enum represents the two banks. |
| 39 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | 42 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] |
| 40 | pub enum Bank { | 43 | pub enum Bank { |
| 41 | Bank0 = 0, | 44 | Gpio0 = 0, |
| 42 | Bank1 = 1, | 45 | Gpio1 = 1, |
| 43 | } | 46 | } |
| 44 | 47 | ||
| 45 | /// GPIO output driver. Internally, this is a specialized [Flex] pin. | 48 | /// GPIO output driver. Internally, this is a specialized [Flex] pin. |
| @@ -109,13 +112,7 @@ impl<'d> Input<'d> { | |||
| 109 | 112 | ||
| 110 | /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. | 113 | /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. |
| 111 | pub fn set_pull(&mut self, pull: Pull) { | 114 | pub fn set_pull(&mut self, pull: Pull) { |
| 112 | match_iocon!(register, self.pin.pin_bank(), self.pin.pin_number(), { | 115 | self.pin.set_pull(pull); |
| 113 | register.modify(|w| match pull { | ||
| 114 | Pull::None => w.set_mode(PioMode::INACTIVE), | ||
| 115 | Pull::Up => w.set_mode(PioMode::PULL_UP), | ||
| 116 | Pull::Down => w.set_mode(PioMode::PULL_DOWN), | ||
| 117 | }); | ||
| 118 | }); | ||
| 119 | } | 116 | } |
| 120 | 117 | ||
| 121 | /// Get the current input level of the pin. | 118 | /// Get the current input level of the pin. |
| @@ -193,11 +190,20 @@ impl<'d> Flex<'d> { | |||
| 193 | 1 << self.pin.pin_number() | 190 | 1 << self.pin.pin_number() |
| 194 | } | 191 | } |
| 195 | 192 | ||
| 193 | /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. | ||
| 194 | pub fn set_pull(&mut self, pull: Pull) { | ||
| 195 | self.pin.pio().modify(|w| match pull { | ||
| 196 | Pull::None => w.set_mode(PioMode::INACTIVE), | ||
| 197 | Pull::Up => w.set_mode(PioMode::PULL_UP), | ||
| 198 | Pull::Down => w.set_mode(PioMode::PULL_DOWN), | ||
| 199 | }); | ||
| 200 | } | ||
| 201 | |||
| 196 | /// Set the pin to digital mode. This is required for using a pin as a GPIO pin. The default | 202 | /// Set the pin to digital mode. This is required for using a pin as a GPIO pin. The default |
| 197 | /// setting for pins is (usually) non-digital. | 203 | /// setting for pins is (usually) non-digital. |
| 198 | fn set_as_digital(&mut self) { | 204 | fn set_as_digital(&mut self) { |
| 199 | match_iocon!(register, self.pin_bank(), self.pin_number(), { | 205 | self.pin.pio().modify(|w| { |
| 200 | register.modify(|w| w.set_digimode(PioDigimode::DIGITAL)); | 206 | w.set_digimode(PioDigimode::DIGITAL); |
| 201 | }); | 207 | }); |
| 202 | } | 208 | } |
| 203 | 209 | ||
| @@ -220,6 +226,14 @@ impl<'d> Flex<'d> { | |||
| 220 | pub(crate) trait SealedPin: Sized { | 226 | pub(crate) trait SealedPin: Sized { |
| 221 | fn pin_bank(&self) -> Bank; | 227 | fn pin_bank(&self) -> Bank; |
| 222 | fn pin_number(&self) -> u8; | 228 | fn pin_number(&self) -> u8; |
| 229 | |||
| 230 | #[inline] | ||
| 231 | fn pio(&self) -> Reg<iocon::regs::Pio, RW> { | ||
| 232 | match self.pin_bank() { | ||
| 233 | Bank::Gpio0 => IOCON.pio0(self.pin_number() as usize), | ||
| 234 | Bank::Gpio1 => IOCON.pio1(self.pin_number() as usize), | ||
| 235 | } | ||
| 236 | } | ||
| 223 | } | 237 | } |
| 224 | 238 | ||
| 225 | /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an | 239 | /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an |
| @@ -242,8 +256,8 @@ pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static { | |||
| 242 | 256 | ||
| 243 | /// Type-erased GPIO pin. | 257 | /// Type-erased GPIO pin. |
| 244 | pub struct AnyPin { | 258 | pub struct AnyPin { |
| 245 | pin_bank: Bank, | 259 | pub(crate) pin_bank: Bank, |
| 246 | pin_number: u8, | 260 | pub(crate) pin_number: u8, |
| 247 | } | 261 | } |
| 248 | 262 | ||
| 249 | impl AnyPin { | 263 | impl AnyPin { |
| @@ -272,47 +286,13 @@ impl SealedPin for AnyPin { | |||
| 272 | } | 286 | } |
| 273 | } | 287 | } |
| 274 | 288 | ||
| 275 | /// Match the pin bank and number of a pin to the corresponding IOCON register. | ||
| 276 | /// | ||
| 277 | /// # Example | ||
| 278 | /// ``` | ||
| 279 | /// use embassy_nxp::gpio::Bank; | ||
| 280 | /// use embassy_nxp::pac_utils::{iocon_reg, match_iocon}; | ||
| 281 | /// | ||
| 282 | /// // Make pin PIO1_6 digital and set it to pull-down mode. | ||
| 283 | /// match_iocon!(register, Bank::Bank1, 6, { | ||
| 284 | /// register.modify(|w|{ | ||
| 285 | /// w.set_mode(PioMode::PULL_DOWN); | ||
| 286 | /// w.set_digimode(PioDigimode::DIGITAL); | ||
| 287 | /// | ||
| 288 | /// } | ||
| 289 | /// }); | ||
| 290 | /// ``` | ||
| 291 | macro_rules! match_iocon { | ||
| 292 | ($register:ident, $pin_bank:expr, $pin_number:expr, $action:expr) => { | ||
| 293 | match $pin_bank { | ||
| 294 | Bank::Bank0 => { | ||
| 295 | let $register = IOCON.pio0($pin_number as usize); | ||
| 296 | $action; | ||
| 297 | } | ||
| 298 | |||
| 299 | Bank::Bank1 => { | ||
| 300 | let $register = IOCON.pio1($pin_number as usize); | ||
| 301 | $action; | ||
| 302 | } | ||
| 303 | } | ||
| 304 | }; | ||
| 305 | } | ||
| 306 | |||
| 307 | pub(crate) use match_iocon; | ||
| 308 | |||
| 309 | macro_rules! impl_pin { | 289 | macro_rules! impl_pin { |
| 310 | ($name:ident, $bank:expr, $pin_num:expr) => { | 290 | ($name:ident, $bank:ident, $pin_num:expr) => { |
| 311 | impl Pin for peripherals::$name {} | 291 | impl crate::gpio::Pin for peripherals::$name {} |
| 312 | impl SealedPin for peripherals::$name { | 292 | impl crate::gpio::SealedPin for peripherals::$name { |
| 313 | #[inline] | 293 | #[inline] |
| 314 | fn pin_bank(&self) -> Bank { | 294 | fn pin_bank(&self) -> crate::gpio::Bank { |
| 315 | $bank | 295 | crate::gpio::Bank::$bank |
| 316 | } | 296 | } |
| 317 | 297 | ||
| 318 | #[inline] | 298 | #[inline] |
| @@ -323,6 +303,8 @@ macro_rules! impl_pin { | |||
| 323 | 303 | ||
| 324 | impl From<peripherals::$name> for crate::gpio::AnyPin { | 304 | impl From<peripherals::$name> for crate::gpio::AnyPin { |
| 325 | fn from(val: peripherals::$name) -> Self { | 305 | fn from(val: peripherals::$name) -> Self { |
| 306 | use crate::gpio::SealedPin; | ||
| 307 | |||
| 326 | Self { | 308 | Self { |
| 327 | pin_bank: val.pin_bank(), | 309 | pin_bank: val.pin_bank(), |
| 328 | pin_number: val.pin_number(), | 310 | pin_number: val.pin_number(), |
| @@ -331,68 +313,3 @@ macro_rules! impl_pin { | |||
| 331 | } | 313 | } |
| 332 | }; | 314 | }; |
| 333 | } | 315 | } |
| 334 | |||
| 335 | impl_pin!(PIO0_0, Bank::Bank0, 0); | ||
| 336 | impl_pin!(PIO0_1, Bank::Bank0, 1); | ||
| 337 | impl_pin!(PIO0_2, Bank::Bank0, 2); | ||
| 338 | impl_pin!(PIO0_3, Bank::Bank0, 3); | ||
| 339 | impl_pin!(PIO0_4, Bank::Bank0, 4); | ||
| 340 | impl_pin!(PIO0_5, Bank::Bank0, 5); | ||
| 341 | impl_pin!(PIO0_6, Bank::Bank0, 6); | ||
| 342 | impl_pin!(PIO0_7, Bank::Bank0, 7); | ||
| 343 | impl_pin!(PIO0_8, Bank::Bank0, 8); | ||
| 344 | impl_pin!(PIO0_9, Bank::Bank0, 9); | ||
| 345 | impl_pin!(PIO0_10, Bank::Bank0, 10); | ||
| 346 | impl_pin!(PIO0_11, Bank::Bank0, 11); | ||
| 347 | impl_pin!(PIO0_12, Bank::Bank0, 12); | ||
| 348 | impl_pin!(PIO0_13, Bank::Bank0, 13); | ||
| 349 | impl_pin!(PIO0_14, Bank::Bank0, 14); | ||
| 350 | impl_pin!(PIO0_15, Bank::Bank0, 15); | ||
| 351 | impl_pin!(PIO0_16, Bank::Bank0, 16); | ||
| 352 | impl_pin!(PIO0_17, Bank::Bank0, 17); | ||
| 353 | impl_pin!(PIO0_18, Bank::Bank0, 18); | ||
| 354 | impl_pin!(PIO0_19, Bank::Bank0, 19); | ||
| 355 | impl_pin!(PIO0_20, Bank::Bank0, 20); | ||
| 356 | impl_pin!(PIO0_21, Bank::Bank0, 21); | ||
| 357 | impl_pin!(PIO0_22, Bank::Bank0, 22); | ||
| 358 | impl_pin!(PIO0_23, Bank::Bank0, 23); | ||
| 359 | impl_pin!(PIO0_24, Bank::Bank0, 24); | ||
| 360 | impl_pin!(PIO0_25, Bank::Bank0, 25); | ||
| 361 | impl_pin!(PIO0_26, Bank::Bank0, 26); | ||
| 362 | impl_pin!(PIO0_27, Bank::Bank0, 27); | ||
| 363 | impl_pin!(PIO0_28, Bank::Bank0, 28); | ||
| 364 | impl_pin!(PIO0_29, Bank::Bank0, 29); | ||
| 365 | impl_pin!(PIO0_30, Bank::Bank0, 30); | ||
| 366 | impl_pin!(PIO0_31, Bank::Bank0, 31); | ||
| 367 | impl_pin!(PIO1_0, Bank::Bank1, 0); | ||
| 368 | impl_pin!(PIO1_1, Bank::Bank1, 1); | ||
| 369 | impl_pin!(PIO1_2, Bank::Bank1, 2); | ||
| 370 | impl_pin!(PIO1_3, Bank::Bank1, 3); | ||
| 371 | impl_pin!(PIO1_4, Bank::Bank1, 4); | ||
| 372 | impl_pin!(PIO1_5, Bank::Bank1, 5); | ||
| 373 | impl_pin!(PIO1_6, Bank::Bank1, 6); | ||
| 374 | impl_pin!(PIO1_7, Bank::Bank1, 7); | ||
| 375 | impl_pin!(PIO1_8, Bank::Bank1, 8); | ||
| 376 | impl_pin!(PIO1_9, Bank::Bank1, 9); | ||
| 377 | impl_pin!(PIO1_10, Bank::Bank1, 10); | ||
| 378 | impl_pin!(PIO1_11, Bank::Bank1, 11); | ||
| 379 | impl_pin!(PIO1_12, Bank::Bank1, 12); | ||
| 380 | impl_pin!(PIO1_13, Bank::Bank1, 13); | ||
| 381 | impl_pin!(PIO1_14, Bank::Bank1, 14); | ||
| 382 | impl_pin!(PIO1_15, Bank::Bank1, 15); | ||
| 383 | impl_pin!(PIO1_16, Bank::Bank1, 16); | ||
| 384 | impl_pin!(PIO1_17, Bank::Bank1, 17); | ||
| 385 | impl_pin!(PIO1_18, Bank::Bank1, 18); | ||
| 386 | impl_pin!(PIO1_19, Bank::Bank1, 19); | ||
| 387 | impl_pin!(PIO1_20, Bank::Bank1, 20); | ||
| 388 | impl_pin!(PIO1_21, Bank::Bank1, 21); | ||
| 389 | impl_pin!(PIO1_22, Bank::Bank1, 22); | ||
| 390 | impl_pin!(PIO1_23, Bank::Bank1, 23); | ||
| 391 | impl_pin!(PIO1_24, Bank::Bank1, 24); | ||
| 392 | impl_pin!(PIO1_25, Bank::Bank1, 25); | ||
| 393 | impl_pin!(PIO1_26, Bank::Bank1, 26); | ||
| 394 | impl_pin!(PIO1_27, Bank::Bank1, 27); | ||
| 395 | impl_pin!(PIO1_28, Bank::Bank1, 28); | ||
| 396 | impl_pin!(PIO1_29, Bank::Bank1, 29); | ||
| 397 | impl_pin!(PIO1_30, Bank::Bank1, 30); | ||
| 398 | impl_pin!(PIO1_31, Bank::Bank1, 31); | ||
diff --git a/embassy-nxp/src/gpio/rt1xxx.rs b/embassy-nxp/src/gpio/rt1xxx.rs index 1d60a0d51..8a560310c 100644 --- a/embassy-nxp/src/gpio/rt1xxx.rs +++ b/embassy-nxp/src/gpio/rt1xxx.rs | |||
| @@ -5,13 +5,13 @@ use core::ops::Not; | |||
| 5 | use core::pin::Pin as FuturePin; | 5 | use core::pin::Pin as FuturePin; |
| 6 | use core::task::{Context, Poll}; | 6 | use core::task::{Context, Poll}; |
| 7 | 7 | ||
| 8 | use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; | 8 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | use nxp_pac::gpio::vals::Icr; | 10 | use nxp_pac::gpio::vals::Icr; |
| 11 | use nxp_pac::iomuxc::vals::Pus; | 11 | use nxp_pac::iomuxc::vals::Pus; |
| 12 | 12 | ||
| 13 | use crate::chip::{mux_address, pad_address}; | 13 | use crate::chip::{iomuxc_mux, iomuxc_pad}; |
| 14 | use crate::pac::common::{Reg, RW}; | 14 | use crate::pac::common::{RW, Reg}; |
| 15 | use crate::pac::gpio::Gpio; | 15 | use crate::pac::gpio::Gpio; |
| 16 | #[cfg(feature = "rt")] | 16 | #[cfg(feature = "rt")] |
| 17 | use crate::pac::interrupt; | 17 | use crate::pac::interrupt; |
| @@ -121,6 +121,10 @@ pub enum Bank { | |||
| 121 | /// Bank 5 | 121 | /// Bank 5 |
| 122 | #[cfg(gpio5)] | 122 | #[cfg(gpio5)] |
| 123 | Gpio5, | 123 | Gpio5, |
| 124 | |||
| 125 | #[cfg(gpio10)] | ||
| 126 | /// Bank 10 | ||
| 127 | Gpio10, | ||
| 124 | } | 128 | } |
| 125 | 129 | ||
| 126 | /// GPIO flexible pin. | 130 | /// GPIO flexible pin. |
| @@ -656,6 +660,8 @@ static GPIO3_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; | |||
| 656 | static GPIO4_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; | 660 | static GPIO4_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; |
| 657 | #[cfg(gpio5)] | 661 | #[cfg(gpio5)] |
| 658 | static GPIO5_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; | 662 | static GPIO5_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; |
| 663 | #[cfg(gpio10)] | ||
| 664 | static GPIO10_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; | ||
| 659 | 665 | ||
| 660 | /// Sealed trait for pins. This trait is sealed and cannot be implemented outside of this crate. | 666 | /// Sealed trait for pins. This trait is sealed and cannot be implemented outside of this crate. |
| 661 | pub(crate) trait SealedPin: Sized { | 667 | pub(crate) trait SealedPin: Sized { |
| @@ -676,13 +682,15 @@ pub(crate) trait SealedPin: Sized { | |||
| 676 | Bank::Gpio4 => pac::GPIO4, | 682 | Bank::Gpio4 => pac::GPIO4, |
| 677 | #[cfg(gpio5)] | 683 | #[cfg(gpio5)] |
| 678 | Bank::Gpio5 => pac::GPIO5, | 684 | Bank::Gpio5 => pac::GPIO5, |
| 685 | #[cfg(gpio10)] | ||
| 686 | Bank::Gpio10 => pac::GPIO10, | ||
| 679 | } | 687 | } |
| 680 | } | 688 | } |
| 681 | 689 | ||
| 682 | #[inline] | 690 | #[inline] |
| 683 | fn mux(&self) -> Reg<MuxCtl, RW> { | 691 | fn mux(&self) -> Reg<MuxCtl, RW> { |
| 684 | // SAFETY: The generated mux address table is valid since it is generated from the SVD files. | 692 | // SAFETY: The generated mux address table is valid since it is generated from the SVD files. |
| 685 | let address = unsafe { mux_address(self._bank(), self.pin_number()).unwrap_unchecked() }; | 693 | let address = unsafe { iomuxc_mux(self._bank(), self.pin_number()).unwrap_unchecked() }; |
| 686 | 694 | ||
| 687 | // SAFETY: The register at the address is an instance of MuxCtl. | 695 | // SAFETY: The register at the address is an instance of MuxCtl. |
| 688 | unsafe { Reg::from_ptr(address as *mut _) } | 696 | unsafe { Reg::from_ptr(address as *mut _) } |
| @@ -690,8 +698,7 @@ pub(crate) trait SealedPin: Sized { | |||
| 690 | 698 | ||
| 691 | #[inline] | 699 | #[inline] |
| 692 | fn pad(&self) -> Reg<Ctl, RW> { | 700 | fn pad(&self) -> Reg<Ctl, RW> { |
| 693 | // SAFETY: The generated pad address table is valid since it is generated from the SVD files. | 701 | let address = iomuxc_pad(self._bank(), self.pin_number()); |
| 694 | let address = unsafe { pad_address(self._bank(), self.pin_number()).unwrap_unchecked() }; | ||
| 695 | 702 | ||
| 696 | // SAFETY: The register at the address is an instance of Ctl. | 703 | // SAFETY: The register at the address is an instance of Ctl. |
| 697 | unsafe { Reg::from_ptr(address as *mut _) } | 704 | unsafe { Reg::from_ptr(address as *mut _) } |
| @@ -709,6 +716,8 @@ pub(crate) trait SealedPin: Sized { | |||
| 709 | Bank::Gpio4 => &GPIO4_WAKERS[self.pin_number() as usize], | 716 | Bank::Gpio4 => &GPIO4_WAKERS[self.pin_number() as usize], |
| 710 | #[cfg(gpio5)] | 717 | #[cfg(gpio5)] |
| 711 | Bank::Gpio5 => &GPIO5_WAKERS[self.pin_number() as usize], | 718 | Bank::Gpio5 => &GPIO5_WAKERS[self.pin_number() as usize], |
| 719 | #[cfg(gpio10)] | ||
| 720 | Bank::Gpio10 => &GPIO10_WAKERS[self.pin_number() as usize], | ||
| 712 | } | 721 | } |
| 713 | } | 722 | } |
| 714 | } | 723 | } |
| @@ -793,39 +802,6 @@ impl<'d> Future for InputFuture<'d> { | |||
| 793 | } | 802 | } |
| 794 | } | 803 | } |
| 795 | 804 | ||
| 796 | /// A macro to generate all GPIO pins. | ||
| 797 | /// | ||
| 798 | /// This generates a lookup table for IOMUX register addresses. | ||
| 799 | macro_rules! impl_gpio { | ||
| 800 | ( | ||
| 801 | $($name: ident($bank: ident, $pin_number: expr);)* | ||
| 802 | ) => { | ||
| 803 | #[inline] | ||
| 804 | pub(crate) const fn pad_address(bank: crate::gpio::Bank, pin: u8) -> Option<u32> { | ||
| 805 | match (bank, pin) { | ||
| 806 | $( | ||
| 807 | (crate::gpio::Bank::$bank, $pin_number) => Some(crate::chip::_generated::iomuxc::pads::$name), | ||
| 808 | )* | ||
| 809 | _ => None | ||
| 810 | } | ||
| 811 | } | ||
| 812 | |||
| 813 | #[inline] | ||
| 814 | pub(crate) const fn mux_address(bank: crate::gpio::Bank, pin: u8) -> Option<u32> { | ||
| 815 | match (bank, pin) { | ||
| 816 | $( | ||
| 817 | (crate::gpio::Bank::$bank, $pin_number) => Some(crate::chip::_generated::iomuxc::muxes::$name), | ||
| 818 | )* | ||
| 819 | _ => None | ||
| 820 | } | ||
| 821 | } | ||
| 822 | |||
| 823 | $( | ||
| 824 | impl_pin!($name, $bank, $pin_number); | ||
| 825 | )* | ||
| 826 | }; | ||
| 827 | } | ||
| 828 | |||
| 829 | macro_rules! impl_pin { | 805 | macro_rules! impl_pin { |
| 830 | ($name: ident, $bank: ident, $pin_num: expr) => { | 806 | ($name: ident, $bank: ident, $pin_num: expr) => { |
| 831 | impl crate::gpio::Pin for crate::peripherals::$name {} | 807 | impl crate::gpio::Pin for crate::peripherals::$name {} |
