aboutsummaryrefslogtreecommitdiff
path: root/embassy-nxp/src/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-nxp/src/gpio')
-rw-r--r--embassy-nxp/src/gpio/lpc55.rs157
-rw-r--r--embassy-nxp/src/gpio/rt1xxx.rs54
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 @@
1use embassy_hal_internal::{impl_peripheral, PeripheralType}; 1#![macro_use]
2 2
3use embassy_hal_internal::{PeripheralType, impl_peripheral};
4
5use crate::Peri;
6use crate::pac::common::{RW, Reg};
3use crate::pac::iocon::vals::{PioDigimode, PioMode}; 7use crate::pac::iocon::vals::{PioDigimode, PioMode};
4use crate::pac::{GPIO, IOCON, SYSCON}; 8use crate::pac::{GPIO, IOCON, SYSCON, iocon};
5use crate::{peripherals, Peri};
6 9
7pub(crate) fn init() { 10pub(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)]
40pub enum Bank { 43pub 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> {
220pub(crate) trait SealedPin: Sized { 226pub(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.
244pub struct AnyPin { 258pub 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
249impl AnyPin { 263impl 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/// ```
291macro_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
307pub(crate) use match_iocon;
308
309macro_rules! impl_pin { 289macro_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
335impl_pin!(PIO0_0, Bank::Bank0, 0);
336impl_pin!(PIO0_1, Bank::Bank0, 1);
337impl_pin!(PIO0_2, Bank::Bank0, 2);
338impl_pin!(PIO0_3, Bank::Bank0, 3);
339impl_pin!(PIO0_4, Bank::Bank0, 4);
340impl_pin!(PIO0_5, Bank::Bank0, 5);
341impl_pin!(PIO0_6, Bank::Bank0, 6);
342impl_pin!(PIO0_7, Bank::Bank0, 7);
343impl_pin!(PIO0_8, Bank::Bank0, 8);
344impl_pin!(PIO0_9, Bank::Bank0, 9);
345impl_pin!(PIO0_10, Bank::Bank0, 10);
346impl_pin!(PIO0_11, Bank::Bank0, 11);
347impl_pin!(PIO0_12, Bank::Bank0, 12);
348impl_pin!(PIO0_13, Bank::Bank0, 13);
349impl_pin!(PIO0_14, Bank::Bank0, 14);
350impl_pin!(PIO0_15, Bank::Bank0, 15);
351impl_pin!(PIO0_16, Bank::Bank0, 16);
352impl_pin!(PIO0_17, Bank::Bank0, 17);
353impl_pin!(PIO0_18, Bank::Bank0, 18);
354impl_pin!(PIO0_19, Bank::Bank0, 19);
355impl_pin!(PIO0_20, Bank::Bank0, 20);
356impl_pin!(PIO0_21, Bank::Bank0, 21);
357impl_pin!(PIO0_22, Bank::Bank0, 22);
358impl_pin!(PIO0_23, Bank::Bank0, 23);
359impl_pin!(PIO0_24, Bank::Bank0, 24);
360impl_pin!(PIO0_25, Bank::Bank0, 25);
361impl_pin!(PIO0_26, Bank::Bank0, 26);
362impl_pin!(PIO0_27, Bank::Bank0, 27);
363impl_pin!(PIO0_28, Bank::Bank0, 28);
364impl_pin!(PIO0_29, Bank::Bank0, 29);
365impl_pin!(PIO0_30, Bank::Bank0, 30);
366impl_pin!(PIO0_31, Bank::Bank0, 31);
367impl_pin!(PIO1_0, Bank::Bank1, 0);
368impl_pin!(PIO1_1, Bank::Bank1, 1);
369impl_pin!(PIO1_2, Bank::Bank1, 2);
370impl_pin!(PIO1_3, Bank::Bank1, 3);
371impl_pin!(PIO1_4, Bank::Bank1, 4);
372impl_pin!(PIO1_5, Bank::Bank1, 5);
373impl_pin!(PIO1_6, Bank::Bank1, 6);
374impl_pin!(PIO1_7, Bank::Bank1, 7);
375impl_pin!(PIO1_8, Bank::Bank1, 8);
376impl_pin!(PIO1_9, Bank::Bank1, 9);
377impl_pin!(PIO1_10, Bank::Bank1, 10);
378impl_pin!(PIO1_11, Bank::Bank1, 11);
379impl_pin!(PIO1_12, Bank::Bank1, 12);
380impl_pin!(PIO1_13, Bank::Bank1, 13);
381impl_pin!(PIO1_14, Bank::Bank1, 14);
382impl_pin!(PIO1_15, Bank::Bank1, 15);
383impl_pin!(PIO1_16, Bank::Bank1, 16);
384impl_pin!(PIO1_17, Bank::Bank1, 17);
385impl_pin!(PIO1_18, Bank::Bank1, 18);
386impl_pin!(PIO1_19, Bank::Bank1, 19);
387impl_pin!(PIO1_20, Bank::Bank1, 20);
388impl_pin!(PIO1_21, Bank::Bank1, 21);
389impl_pin!(PIO1_22, Bank::Bank1, 22);
390impl_pin!(PIO1_23, Bank::Bank1, 23);
391impl_pin!(PIO1_24, Bank::Bank1, 24);
392impl_pin!(PIO1_25, Bank::Bank1, 25);
393impl_pin!(PIO1_26, Bank::Bank1, 26);
394impl_pin!(PIO1_27, Bank::Bank1, 27);
395impl_pin!(PIO1_28, Bank::Bank1, 28);
396impl_pin!(PIO1_29, Bank::Bank1, 29);
397impl_pin!(PIO1_30, Bank::Bank1, 30);
398impl_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;
5use core::pin::Pin as FuturePin; 5use core::pin::Pin as FuturePin;
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; 8use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use nxp_pac::gpio::vals::Icr; 10use nxp_pac::gpio::vals::Icr;
11use nxp_pac::iomuxc::vals::Pus; 11use nxp_pac::iomuxc::vals::Pus;
12 12
13use crate::chip::{mux_address, pad_address}; 13use crate::chip::{iomuxc_mux, iomuxc_pad};
14use crate::pac::common::{Reg, RW}; 14use crate::pac::common::{RW, Reg};
15use crate::pac::gpio::Gpio; 15use crate::pac::gpio::Gpio;
16#[cfg(feature = "rt")] 16#[cfg(feature = "rt")]
17use crate::pac::interrupt; 17use 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];
656static GPIO4_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; 660static GPIO4_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32];
657#[cfg(gpio5)] 661#[cfg(gpio5)]
658static GPIO5_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; 662static GPIO5_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32];
663#[cfg(gpio10)]
664static 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.
661pub(crate) trait SealedPin: Sized { 667pub(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.
799macro_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
829macro_rules! impl_pin { 805macro_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 {}