From 19bb3668669710dbd1d17dc5fb0dee6d915f012e Mon Sep 17 00:00:00 2001 From: Roi Bachynskyi Date: Sat, 30 Aug 2025 14:25:25 +0300 Subject: lpc55: gpio rewritten --- embassy-nxp/Cargo.toml | 6 +- embassy-nxp/src/chips/lpc55.rs | 2 +- embassy-nxp/src/gpio/lpc55.rs | 360 +++++------------------------------------ 3 files changed, 44 insertions(+), 324 deletions(-) diff --git a/embassy-nxp/Cargo.toml b/embassy-nxp/Cargo.toml index ab0bfbfd7..c66354ee2 100644 --- a/embassy-nxp/Cargo.toml +++ b/embassy-nxp/Cargo.toml @@ -37,13 +37,13 @@ embedded-io = "0.6.1" embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } ## Chip dependencies lpc55-pac = { version = "0.5.0", optional = true } -nxp-pac = { version = "0.1.0", optional = true, git = "https://github.com/i509VCB/nxp-pac", rev = "be4dd0936c20d5897364a381b1d95a99514c1e7e" } +nxp-pac = { version = "0.1.0", optional = true, git = "https://github.com/IrinaCh524/nxp-pac", rev = "d452e366105012ddd8ba332a9ab86e1931508235" } imxrt-rt = { version = "0.1.7", optional = true, features = ["device"] } [build-dependencies] cfg_aliases = "0.2.1" -nxp-pac = { version = "0.1.0", git = "https://github.com/i509VCB/nxp-pac", rev = "be4dd0936c20d5897364a381b1d95a99514c1e7e", features = ["metadata"], optional = true } +nxp-pac = { version = "0.1.0", git = "https://github.com/IrinaCh524/nxp-pac", rev = "d452e366105012ddd8ba332a9ab86e1931508235", features = ["metadata"], optional = true } proc-macro2 = "1.0.95" quote = "1.0.15" @@ -79,6 +79,6 @@ _rt1xxx = [] _time_driver = ["dep:embassy-time-driver", "dep:embassy-time-queue-utils"] #! ### Chip selection features -lpc55 = ["dep:lpc55-pac"] +lpc55 = ["nxp-pac/lpc55s69_core0"] mimxrt1011 = ["nxp-pac/mimxrt1011", "_rt1xxx", "dep:imxrt-rt"] mimxrt1062 = ["nxp-pac/mimxrt1062", "_rt1xxx", "dep:imxrt-rt"] diff --git a/embassy-nxp/src/chips/lpc55.rs b/embassy-nxp/src/chips/lpc55.rs index e168ced00..711bff3e7 100644 --- a/embassy-nxp/src/chips/lpc55.rs +++ b/embassy-nxp/src/chips/lpc55.rs @@ -1,4 +1,4 @@ -pub use lpc55_pac as pac; +pub use nxp_pac as pac; embassy_hal_internal::peripherals! { // External pins. These are not only GPIOs, they are multi-purpose pins and can be used by other diff --git a/embassy-nxp/src/gpio/lpc55.rs b/embassy-nxp/src/gpio/lpc55.rs index 8f407bb3a..36ea99d21 100644 --- a/embassy-nxp/src/gpio/lpc55.rs +++ b/embassy-nxp/src/gpio/lpc55.rs @@ -1,12 +1,17 @@ use embassy_hal_internal::{impl_peripheral, PeripheralType}; +use crate::pac::iocon::vals::{PioDigimode, PioMode}; +use crate::pac::{GPIO, IOCON, SYSCON}; use crate::{peripherals, Peri}; pub(crate) fn init() { // Enable clocks for GPIO, PINT, and IOCON - syscon_reg() - .ahbclkctrl0 - .modify(|_, w| w.gpio0().enable().gpio1().enable().mux().enable().iocon().enable()); + SYSCON.ahbclkctrl0().modify(|w| { + w.set_gpio0(true); + w.set_gpio1(true); + w.set_mux(true); + w.set_iocon(true); + }); info!("GPIO initialized"); } @@ -59,21 +64,24 @@ impl<'d> Output<'d> { } pub fn set_high(&mut self) { - gpio_reg().set[self.pin.pin_bank() as usize].write(|w| unsafe { w.bits(self.pin.bit()) }) + GPIO.set(self.pin.pin_bank() as usize) + .write(|w| w.set_setp(self.pin.bit())); } pub fn set_low(&mut self) { - gpio_reg().clr[self.pin.pin_bank() as usize].write(|w| unsafe { w.bits(self.pin.bit()) }) + GPIO.clr(self.pin.pin_bank() as usize) + .write(|w| w.set_clrp(self.pin.bit())); } pub fn toggle(&mut self) { - gpio_reg().not[self.pin.pin_bank() as usize].write(|w| unsafe { w.bits(self.pin.bit()) }) + GPIO.not(self.pin.pin_bank() as usize) + .write(|w| w.set_notp(self.pin.bit())); } /// Get the current output level of the pin. Note that the value returned by this function is /// the voltage level reported by the pin, not the value set by the output driver. pub fn level(&self) -> Level { - let bits = gpio_reg().pin[self.pin.pin_bank() as usize].read().bits(); + let bits = GPIO.pin(self.pin.pin_bank() as usize).read().port(); if bits & self.pin.bit() != 0 { Level::High } else { @@ -101,18 +109,18 @@ impl<'d> Input<'d> { /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. pub fn set_pull(&mut self, pull: Pull) { - match_iocon!(register, iocon_reg(), self.pin.pin_bank(), self.pin.pin_number(), { - register.modify(|_, w| match pull { - Pull::None => w.mode().inactive(), - Pull::Up => w.mode().pull_up(), - Pull::Down => w.mode().pull_down(), + match_iocon!(register, self.pin.pin_bank(), self.pin.pin_number(), { + register.modify(|w| match pull { + Pull::None => w.set_mode(PioMode::INACTIVE), + Pull::Up => w.set_mode(PioMode::PULL_UP), + Pull::Down => w.set_mode(PioMode::PULL_DOWN), }); }); } /// Get the current input level of the pin. pub fn read(&self) -> Level { - let bits = gpio_reg().pin[self.pin.pin_bank() as usize].read().bits(); + let bits = GPIO.pin(self.pin.pin_bank() as usize).read().port(); if bits & self.pin.bit() != 0 { Level::High } else { @@ -188,8 +196,8 @@ impl<'d> Flex<'d> { /// Set the pin to digital mode. This is required for using a pin as a GPIO pin. The default /// setting for pins is (usually) non-digital. fn set_as_digital(&mut self) { - match_iocon!(register, iocon_reg(), self.pin_bank(), self.pin_number(), { - register.modify(|_, w| w.digimode().digital()); + match_iocon!(register, self.pin_bank(), self.pin_number(), { + register.modify(|w| w.set_digimode(PioDigimode::DIGITAL)); }); } @@ -197,12 +205,14 @@ impl<'d> Flex<'d> { /// function handles itself. pub fn set_as_output(&mut self) { self.set_as_digital(); - gpio_reg().dirset[self.pin.pin_bank() as usize].write(|w| unsafe { w.dirsetp().bits(self.bit()) }) + GPIO.dirset(self.pin.pin_bank() as usize) + .write(|w| w.set_dirsetp(self.bit())) } pub fn set_as_input(&mut self) { self.set_as_digital(); - gpio_reg().dirclr[self.pin.pin_bank() as usize].write(|w| unsafe { w.dirclrp().bits(self.bit()) }) + GPIO.dirclr(self.pin.pin_bank() as usize) + .write(|w| w.set_dirclrp(self.bit())) } } @@ -262,52 +272,6 @@ impl SealedPin for AnyPin { } } -/// Get the GPIO register block. This is used to configure all GPIO pins. -/// -/// # Safety -/// Due to the type system of peripherals, access to the settings of a single pin is possible only -/// by a single thread at a time. Read/Write operations on a single registers are NOT atomic. You -/// must ensure that the GPIO registers are not accessed concurrently by multiple threads. -pub(crate) fn gpio_reg() -> &'static lpc55_pac::gpio::RegisterBlock { - unsafe { &*lpc55_pac::GPIO::ptr() } -} - -/// Get the IOCON register block. -/// -/// # Safety -/// Read/Write operations on a single registers are NOT atomic. You must ensure that the GPIO -/// registers are not accessed concurrently by multiple threads. -pub(crate) fn iocon_reg() -> &'static lpc55_pac::iocon::RegisterBlock { - unsafe { &*lpc55_pac::IOCON::ptr() } -} - -/// Get the INPUTMUX register block. -/// -/// # Safety -/// Read/Write operations on a single registers are NOT atomic. You must ensure that the GPIO -/// registers are not accessed concurrently by multiple threads. -pub(crate) fn inputmux_reg() -> &'static lpc55_pac::inputmux::RegisterBlock { - unsafe { &*lpc55_pac::INPUTMUX::ptr() } -} - -/// Get the SYSCON register block. -/// -/// # Safety -/// Read/Write operations on a single registers are NOT atomic. You must ensure that the GPIO -/// registers are not accessed concurrently by multiple threads. -pub(crate) fn syscon_reg() -> &'static lpc55_pac::syscon::RegisterBlock { - unsafe { &*lpc55_pac::SYSCON::ptr() } -} - -/// Get the PINT register block. -/// -/// # Safety -/// Read/Write operations on a single registers are NOT atomic. You must ensure that the GPIO -/// registers are not accessed concurrently by multiple threads. -pub(crate) fn pint_reg() -> &'static lpc55_pac::pint::RegisterBlock { - unsafe { &*lpc55_pac::PINT::ptr() } -} - /// Match the pin bank and number of a pin to the corresponding IOCON register. /// /// # Example @@ -316,270 +280,26 @@ pub(crate) fn pint_reg() -> &'static lpc55_pac::pint::RegisterBlock { /// use embassy_nxp::pac_utils::{iocon_reg, match_iocon}; /// /// // Make pin PIO1_6 digital and set it to pull-down mode. -/// match_iocon!(register, iocon_reg(), Bank::Bank1, 6, { -/// register.modify(|_, w| w.mode().pull_down().digimode().digital()); +/// match_iocon!(register, Bank::Bank1, 6, { +/// register.modify(|w|{ +/// w.set_mode(PioMode::PULL_DOWN); +/// w.set_digimode(PioDigimode::DIGITAL); +/// +/// } /// }); /// ``` macro_rules! match_iocon { - ($register:ident, $iocon_register:expr, $pin_bank:expr, $pin_number:expr, $action:expr) => { - match ($pin_bank, $pin_number) { - (Bank::Bank0, 0) => { - let $register = &($iocon_register).pio0_0; - $action; - } - (Bank::Bank0, 1) => { - let $register = &($iocon_register).pio0_1; - $action; - } - (Bank::Bank0, 2) => { - let $register = &($iocon_register).pio0_2; - $action; - } - (Bank::Bank0, 3) => { - let $register = &($iocon_register).pio0_3; - $action; - } - (Bank::Bank0, 4) => { - let $register = &($iocon_register).pio0_4; - $action; - } - (Bank::Bank0, 5) => { - let $register = &($iocon_register).pio0_5; - $action; - } - (Bank::Bank0, 6) => { - let $register = &($iocon_register).pio0_6; - $action; - } - (Bank::Bank0, 7) => { - let $register = &($iocon_register).pio0_7; - $action; - } - (Bank::Bank0, 8) => { - let $register = &($iocon_register).pio0_8; - $action; - } - (Bank::Bank0, 9) => { - let $register = &($iocon_register).pio0_9; - $action; - } - (Bank::Bank0, 10) => { - let $register = &($iocon_register).pio0_10; + ($register:ident, $pin_bank:expr, $pin_number:expr, $action:expr) => { + match $pin_bank { + Bank::Bank0 => { + let $register = IOCON.pio0($pin_number as usize); $action; } - (Bank::Bank0, 11) => { - let $register = &($iocon_register).pio0_11; - $action; - } - (Bank::Bank0, 12) => { - let $register = &($iocon_register).pio0_12; - $action; - } - (Bank::Bank0, 13) => { - let $register = &($iocon_register).pio0_13; - $action; - } - (Bank::Bank0, 14) => { - let $register = &($iocon_register).pio0_14; - $action; - } - (Bank::Bank0, 15) => { - let $register = &($iocon_register).pio0_15; - $action; - } - (Bank::Bank0, 16) => { - let $register = &($iocon_register).pio0_16; - $action; - } - (Bank::Bank0, 17) => { - let $register = &($iocon_register).pio0_17; - $action; - } - (Bank::Bank0, 18) => { - let $register = &($iocon_register).pio0_18; - $action; - } - (Bank::Bank0, 19) => { - let $register = &($iocon_register).pio0_19; - $action; - } - (Bank::Bank0, 20) => { - let $register = &($iocon_register).pio0_20; - $action; - } - (Bank::Bank0, 21) => { - let $register = &($iocon_register).pio0_21; - $action; - } - (Bank::Bank0, 22) => { - let $register = &($iocon_register).pio0_22; - $action; - } - (Bank::Bank0, 23) => { - let $register = &($iocon_register).pio0_23; - $action; - } - (Bank::Bank0, 24) => { - let $register = &($iocon_register).pio0_24; - $action; - } - (Bank::Bank0, 25) => { - let $register = &($iocon_register).pio0_25; - $action; - } - (Bank::Bank0, 26) => { - let $register = &($iocon_register).pio0_26; - $action; - } - (Bank::Bank0, 27) => { - let $register = &($iocon_register).pio0_27; - $action; - } - (Bank::Bank0, 28) => { - let $register = &($iocon_register).pio0_28; - $action; - } - (Bank::Bank0, 29) => { - let $register = &($iocon_register).pio0_29; - $action; - } - (Bank::Bank0, 30) => { - let $register = &($iocon_register).pio0_30; - $action; - } - (Bank::Bank0, 31) => { - let $register = &($iocon_register).pio0_31; - $action; - } - (Bank::Bank1, 0) => { - let $register = &($iocon_register).pio1_0; - $action; - } - (Bank::Bank1, 1) => { - let $register = &($iocon_register).pio1_1; - $action; - } - (Bank::Bank1, 2) => { - let $register = &($iocon_register).pio1_2; - $action; - } - (Bank::Bank1, 3) => { - let $register = &($iocon_register).pio1_3; - $action; - } - (Bank::Bank1, 4) => { - let $register = &($iocon_register).pio1_4; - $action; - } - (Bank::Bank1, 5) => { - let $register = &($iocon_register).pio1_5; - $action; - } - (Bank::Bank1, 6) => { - let $register = &($iocon_register).pio1_6; - $action; - } - (Bank::Bank1, 7) => { - let $register = &($iocon_register).pio1_7; - $action; - } - (Bank::Bank1, 8) => { - let $register = &($iocon_register).pio1_8; - $action; - } - (Bank::Bank1, 9) => { - let $register = &($iocon_register).pio1_9; - $action; - } - (Bank::Bank1, 10) => { - let $register = &($iocon_register).pio1_10; - $action; - } - (Bank::Bank1, 11) => { - let $register = &($iocon_register).pio1_11; - $action; - } - (Bank::Bank1, 12) => { - let $register = &($iocon_register).pio1_12; - $action; - } - (Bank::Bank1, 13) => { - let $register = &($iocon_register).pio1_13; - $action; - } - (Bank::Bank1, 14) => { - let $register = &($iocon_register).pio1_14; - $action; - } - (Bank::Bank1, 15) => { - let $register = &($iocon_register).pio1_15; - $action; - } - (Bank::Bank1, 16) => { - let $register = &($iocon_register).pio1_16; - $action; - } - (Bank::Bank1, 17) => { - let $register = &($iocon_register).pio1_17; - $action; - } - (Bank::Bank1, 18) => { - let $register = &($iocon_register).pio1_18; - $action; - } - (Bank::Bank1, 19) => { - let $register = &($iocon_register).pio1_19; - $action; - } - (Bank::Bank1, 20) => { - let $register = &($iocon_register).pio1_20; - $action; - } - (Bank::Bank1, 21) => { - let $register = &($iocon_register).pio1_21; - $action; - } - (Bank::Bank1, 22) => { - let $register = &($iocon_register).pio1_22; - $action; - } - (Bank::Bank1, 23) => { - let $register = &($iocon_register).pio1_23; - $action; - } - (Bank::Bank1, 24) => { - let $register = &($iocon_register).pio1_24; - $action; - } - (Bank::Bank1, 25) => { - let $register = &($iocon_register).pio1_25; - $action; - } - (Bank::Bank1, 26) => { - let $register = &($iocon_register).pio1_26; - $action; - } - (Bank::Bank1, 27) => { - let $register = &($iocon_register).pio1_27; - $action; - } - (Bank::Bank1, 28) => { - let $register = &($iocon_register).pio1_28; - $action; - } - (Bank::Bank1, 29) => { - let $register = &($iocon_register).pio1_29; - $action; - } - (Bank::Bank1, 30) => { - let $register = &($iocon_register).pio1_30; - $action; - } - (Bank::Bank1, 31) => { - let $register = &($iocon_register).pio1_31; + + Bank::Bank1 => { + let $register = IOCON.pio1($pin_number as usize); $action; } - _ => unreachable!(), } }; } -- cgit