From 05bf2d0438fe8c41d0fe26b85106ff73a6e273e9 Mon Sep 17 00:00:00 2001 From: James Munns Date: Tue, 25 Nov 2025 18:08:13 +0100 Subject: Wire up Lpuart pins (#43) Allow the HAL lpuart driver to correctly configure pins as requested on init. --- Cargo.lock | 2 +- examples/Cargo.lock | 2 +- examples/src/bin/adc_interrupt.rs | 26 +--- examples/src/bin/adc_polling.rs | 31 +---- examples/src/bin/hello.rs | 3 - examples/src/bin/lpuart_buffered.rs | 29 ++--- examples/src/bin/lpuart_polling.rs | 12 +- examples/src/bin/rtc_alarm.rs | 33 +----- examples/src/lib.rs | 9 -- src/clocks/config.rs | 5 + src/clocks/mod.rs | 5 + src/interrupt.rs | 2 +- src/lib.rs | 1 + src/lpuart/buffered.rs | 20 ++-- src/lpuart/mod.rs | 231 ++++++++++++++++++++++++------------ src/pins.rs | 34 ------ 16 files changed, 205 insertions(+), 240 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb6c142ef..314120a47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -324,7 +324,7 @@ checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "mcxa-pac" version = "0.1.0" -source = "git+https://github.com/OpenDevicePartnership/mcxa-pac#9a857ec9780527679978b42cc60288aeef03baa2" +source = "git+https://github.com/OpenDevicePartnership/mcxa-pac#e18dfb52500ca77b8d8326662b966a80251182ca" dependencies = [ "cortex-m", "cortex-m-rt", diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 56ae41d48..263807120 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -442,7 +442,7 @@ checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "mcxa-pac" version = "0.1.0" -source = "git+https://github.com/OpenDevicePartnership/mcxa-pac#9a857ec9780527679978b42cc60288aeef03baa2" +source = "git+https://github.com/OpenDevicePartnership/mcxa-pac#e18dfb52500ca77b8d8326662b966a80251182ca" dependencies = [ "cortex-m", "cortex-m-rt", diff --git a/examples/src/bin/adc_interrupt.rs b/examples/src/bin/adc_interrupt.rs index 0d3a75a28..83d8046b3 100644 --- a/examples/src/bin/adc_interrupt.rs +++ b/examples/src/bin/adc_interrupt.rs @@ -6,7 +6,6 @@ use embassy_mcxa_examples::init_adc_pins; use hal::adc::{LpadcConfig, TriggerPriorityPolicy}; use hal::clocks::periph_helpers::{AdcClockSel, Div4}; use hal::clocks::PoweredClock; -use hal::lpuart::{Config, Lpuart}; use hal::pac::adc1::cfg::{Pwrsel, Refsel}; use hal::pac::adc1::cmdl1::{Adch, Mode}; use hal::pac::adc1::ctrl::CalAvgs; @@ -26,26 +25,7 @@ static KEEP_ADC: unsafe extern "C" fn() = ADC1; async fn main(_spawner: Spawner) { let p = hal::init(hal::config::Config::default()); - // Create UART configuration - let config = Config { - baudrate_bps: 115_200, - enable_tx: true, - enable_rx: true, - ..Default::default() - }; - - // Create UART instance using LPUART2 with P2_2 as TX and P2_3 as RX - unsafe { - embassy_mcxa_examples::init_uart2_pins(); - } - let mut uart = Lpuart::new_blocking( - p.LPUART2, // Peripheral - p.P2_2, // TX pin - p.P2_3, // RX pin - config, - ) - .unwrap(); - uart.write_str_blocking("\r\n=== ADC interrupt Example ===\r\n"); + defmt::info!("ADC interrupt Example"); unsafe { init_adc_pins(); @@ -81,7 +61,7 @@ async fn main(_spawner: Spawner) { conv_trigger_config.enable_hardware_trigger = false; adc.set_conv_trigger_config(0, &conv_trigger_config); - uart.write_str_blocking("\r\n=== ADC configuration done... ===\r\n"); + defmt::info!("ADC configuration done..."); adc.enable_interrupt(0x1); @@ -98,7 +78,7 @@ async fn main(_spawner: Spawner) { while !adc.is_interrupt_triggered() { // Wait until the interrupt is triggered } - uart.write_str_blocking("\r\n*** ADC interrupt TRIGGERED! ***\r\n"); + defmt::info!("*** ADC interrupt TRIGGERED! ***"); //TBD need to print the value } } diff --git a/examples/src/bin/adc_polling.rs b/examples/src/bin/adc_polling.rs index 02ac321b5..ddf3f586b 100644 --- a/examples/src/bin/adc_polling.rs +++ b/examples/src/bin/adc_polling.rs @@ -1,19 +1,15 @@ #![no_std] #![no_main] -use core::fmt::Write; - use embassy_executor::Spawner; -use embassy_mcxa_examples::{init_adc_pins, init_uart2_pins}; +use embassy_mcxa_examples::init_adc_pins; use hal::adc::{ConvResult, LpadcConfig, TriggerPriorityPolicy}; use hal::clocks::periph_helpers::{AdcClockSel, Div4}; use hal::clocks::PoweredClock; -use hal::lpuart::{Config, Lpuart}; use hal::pac::adc1::cfg::{Pwrsel, Refsel}; use hal::pac::adc1::cmdl1::{Adch, Mode}; use hal::pac::adc1::ctrl::CalAvgs; use hal::pac::adc1::tctrl::Tcmd; -use heapless::String; use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; const G_LPADC_RESULT_SHIFT: u32 = 0; @@ -22,28 +18,11 @@ const G_LPADC_RESULT_SHIFT: u32 = 0; async fn main(_spawner: Spawner) { let p = hal::init(hal::config::Config::default()); - // Create UART configuration - let config = Config { - baudrate_bps: 115_200, - enable_tx: true, - enable_rx: true, - ..Default::default() - }; - - // Create UART instance using LPUART2 with P2_2 as TX and P2_3 as RX unsafe { - init_uart2_pins(); init_adc_pins(); } - let mut uart = Lpuart::new_blocking( - p.LPUART2, // Peripheral - p.P2_2, // TX pin - p.P2_3, // RX pin - config, - ) - .unwrap(); - uart.write_str_blocking("\r\n=== ADC polling Example ===\r\n"); + defmt::info!("=== ADC polling Example ==="); let adc_config = LpadcConfig { enable_in_doze_mode: true, @@ -75,7 +54,7 @@ async fn main(_spawner: Spawner) { conv_trigger_config.enable_hardware_trigger = false; adc.set_conv_trigger_config(0, &conv_trigger_config); - uart.write_str_blocking("\r\n=== ADC configuration done... ===\r\n"); + defmt::info!("=== ADC configuration done... ==="); loop { adc.do_software_trigger(1); @@ -84,8 +63,6 @@ async fn main(_spawner: Spawner) { result = hal::adc::get_conv_result(); } let value = result.unwrap().conv_value >> G_LPADC_RESULT_SHIFT; - let mut buf: String<16> = String::new(); // adjust size as needed - write!(buf, "\r\nvalue: {}\r\n", value).unwrap(); - uart.write_str_blocking(&buf); + defmt::info!("value: {=u16}", value); } } diff --git a/examples/src/bin/hello.rs b/examples/src/bin/hello.rs index 0362480c1..f426d1898 100644 --- a/examples/src/bin/hello.rs +++ b/examples/src/bin/hello.rs @@ -27,9 +27,6 @@ async fn main(_spawner: Spawner) { }; // Create UART instance using LPUART2 with P2_2 as TX and P2_3 as RX - unsafe { - embassy_mcxa_examples::init_uart2_pins(); - } let mut uart = Lpuart::new_blocking( p.LPUART2, // Peripheral p.P2_2, // TX pin diff --git a/examples/src/bin/lpuart_buffered.rs b/examples/src/bin/lpuart_buffered.rs index 4c9294f57..7f77d557d 100644 --- a/examples/src/bin/lpuart_buffered.rs +++ b/examples/src/bin/lpuart_buffered.rs @@ -2,39 +2,28 @@ #![no_main] use embassy_executor::Spawner; -use embassy_mcxa as hal; -use embassy_mcxa::interrupt::typelevel::Handler; +use embassy_mcxa::clocks::config::Div8; use embassy_mcxa::lpuart::buffered::BufferedLpuart; use embassy_mcxa::lpuart::Config; use embassy_mcxa::{bind_interrupts, lpuart}; -use embassy_mcxa_examples::init_uart2_pins; -use embedded_io_async::{Read, Write}; +use embedded_io_async::Write; +use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; // Bind OS_EVENT for timers plus LPUART2 IRQ for the buffered driver bind_interrupts!(struct Irqs { LPUART2 => lpuart::buffered::BufferedInterruptHandler::; }); -// Wrapper function for the interrupt handler -unsafe extern "C" fn lpuart2_handler() { - lpuart::buffered::BufferedInterruptHandler::::on_interrupt(); -} - #[embassy_executor::main] async fn main(_spawner: Spawner) { - let p = hal::init(hal::config::Config::default()); - - unsafe { - hal::interrupt::install_irq_handler(hal::pac::Interrupt::LPUART2, lpuart2_handler); - } + let mut cfg = hal::config::Config::default(); + cfg.clock_cfg.sirc.fro_12m_enabled = true; + cfg.clock_cfg.sirc.fro_lf_div = Some(Div8::no_div()); + let p = hal::init(cfg); // Configure NVIC for LPUART2 hal::interrupt::LPUART2.configure_for_uart(hal::interrupt::Priority::P3); - unsafe { - init_uart2_pins(); - } - // UART configuration (enable both TX and RX) let config = Config { baudrate_bps: 115_200, @@ -69,7 +58,7 @@ async fn main(_spawner: Spawner) { // Echo loop let mut buf = [0u8; 4]; loop { - rx.read_exact(&mut buf[..]).await.unwrap(); - tx.write_all(&buf[..]).await.unwrap(); + let used = rx.read(&mut buf).await.unwrap(); + tx.write_all(&buf[..used]).await.unwrap(); } } diff --git a/examples/src/bin/lpuart_polling.rs b/examples/src/bin/lpuart_polling.rs index c8666e64a..9cea418cc 100644 --- a/examples/src/bin/lpuart_polling.rs +++ b/examples/src/bin/lpuart_polling.rs @@ -2,22 +2,20 @@ #![no_main] use embassy_executor::Spawner; -use embassy_mcxa_examples::init_uart2_pins; +use embassy_mcxa::clocks::config::Div8; use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; use crate::hal::lpuart::{Config, Lpuart}; #[embassy_executor::main] async fn main(_spawner: Spawner) { - let p = hal::init(hal::config::Config::default()); + let mut cfg = hal::config::Config::default(); + cfg.clock_cfg.sirc.fro_12m_enabled = true; + cfg.clock_cfg.sirc.fro_lf_div = Some(Div8::no_div()); + let p = hal::init(cfg); defmt::info!("boot"); - // Board-level init for UART2 clocks and pins. - unsafe { - init_uart2_pins(); - } - // Create UART configuration let config = Config { baudrate_bps: 115_200, diff --git a/examples/src/bin/rtc_alarm.rs b/examples/src/bin/rtc_alarm.rs index 6f8a77101..a7800a2d1 100644 --- a/examples/src/bin/rtc_alarm.rs +++ b/examples/src/bin/rtc_alarm.rs @@ -3,7 +3,6 @@ use embassy_executor::Spawner; use embassy_mcxa as hal; -use hal::lpuart::{Config, Lpuart}; use hal::rtc::{RtcDateTime, RtcInterruptEnable}; use hal::InterruptExt; @@ -24,27 +23,7 @@ static KEEP_RTC: unsafe extern "C" fn() = RTC; async fn main(_spawner: Spawner) { let p = hal::init(hal::config::Config::default()); - // Create UART configuration - let config = Config { - baudrate_bps: 115_200, - enable_tx: true, - enable_rx: true, - ..Default::default() - }; - - // Create UART instance using LPUART2 with P2_2 as TX and P2_3 as RX - unsafe { - embassy_mcxa_examples::init_uart2_pins(); - } - let mut uart = Lpuart::new_blocking( - p.LPUART2, // Peripheral - p.P2_2, // TX pin - p.P2_3, // RX pin - config, - ) - .unwrap(); - - uart.write_str_blocking("\r\n=== RTC Alarm Example ===\r\n"); + defmt::info!("=== RTC Alarm Example ==="); let rtc_config = hal::rtc::get_default_config(); @@ -61,14 +40,14 @@ async fn main(_spawner: Spawner) { rtc.stop(); - uart.write_str_blocking("Time set to: 2025-10-15 14:30:00\r\n"); + defmt::info!("Time set to: 2025-10-15 14:30:00"); rtc.set_datetime(now); let mut alarm = now; alarm.second += 10; rtc.set_alarm(alarm); - uart.write_str_blocking("Alarm set for: 2025-10-15 14:30:10 (+10 seconds)\r\n"); + defmt::info!("Alarm set for: 2025-10-15 14:30:10 (+10 seconds)"); rtc.set_interrupt(RtcInterruptEnable::RTC_ALARM_INTERRUPT_ENABLE); @@ -82,14 +61,14 @@ async fn main(_spawner: Spawner) { rtc.start(); - uart.write_str_blocking("RTC started, waiting for alarm...\r\n"); + defmt::info!("RTC started, waiting for alarm..."); loop { if rtc.is_alarm_triggered() { - uart.write_str_blocking("\r\n*** ALARM TRIGGERED! ***\r\n"); + defmt::info!("*** ALARM TRIGGERED! ***"); break; } } - uart.write_str_blocking("Example complete - Test PASSED!\r\n"); + defmt::info!("Example complete - Test PASSED!"); } diff --git a/examples/src/lib.rs b/examples/src/lib.rs index f5f6124c0..2573a6adc 100644 --- a/examples/src/lib.rs +++ b/examples/src/lib.rs @@ -7,15 +7,6 @@ use hal::{clocks, pins}; use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; -/// Initialize clocks and pin muxing for UART2 debug console. -/// Safe to call multiple times; writes are idempotent for our use. -pub unsafe fn init_uart2_pins() { - // NOTE: Lpuart has been updated to properly enable + reset its own clocks. - // GPIO has not. - _ = clocks::enable_and_reset::(&clocks::periph_helpers::NoConfig); - pins::configure_uart2_pins_port2(); -} - /// Initialize clocks and pin muxing for ADC. pub unsafe fn init_adc_pins() { // NOTE: Lpuart has been updated to properly enable + reset its own clocks. diff --git a/src/clocks/config.rs b/src/clocks/config.rs index a517afcca..0563b8917 100644 --- a/src/clocks/config.rs +++ b/src/clocks/config.rs @@ -21,6 +21,11 @@ impl Div8 { Self(n) } + /// Divide by one, or no division + pub const fn no_div() -> Self { + Self(0) + } + /// Store a specific divisor value that will divide the source /// by `n`. e.g. `Div8::from_divisor(1)` will divide the source /// by 1, and `Div8::from_divisor(256)` will divide the source diff --git a/src/clocks/mod.rs b/src/clocks/mod.rs index 948355079..cd6318c4b 100644 --- a/src/clocks/mod.rs +++ b/src/clocks/mod.rs @@ -928,6 +928,11 @@ pub(crate) mod gate { #[cfg(not(feature = "time"))] impl_cc_gate!(OSTIMER0, mrcc_glb_cc1, mrcc_glb_rst1, ostimer0, OsTimerConfig); + impl_cc_gate!(LPUART0, mrcc_glb_cc0, mrcc_glb_rst0, lpuart0, LpuartConfig); + impl_cc_gate!(LPUART1, mrcc_glb_cc0, mrcc_glb_rst0, lpuart1, LpuartConfig); impl_cc_gate!(LPUART2, mrcc_glb_cc0, mrcc_glb_rst0, lpuart2, LpuartConfig); + impl_cc_gate!(LPUART3, mrcc_glb_cc0, mrcc_glb_rst0, lpuart3, LpuartConfig); + impl_cc_gate!(LPUART4, mrcc_glb_cc0, mrcc_glb_rst0, lpuart4, LpuartConfig); + impl_cc_gate!(LPUART5, mrcc_glb_cc1, mrcc_glb_rst1, lpuart5, LpuartConfig); impl_cc_gate!(ADC1, mrcc_glb_cc1, mrcc_glb_rst1, adc1, AdcConfig); } diff --git a/src/interrupt.rs b/src/interrupt.rs index 134ff03fd..4d409067a 100644 --- a/src/interrupt.rs +++ b/src/interrupt.rs @@ -7,7 +7,7 @@ #![allow(clippy::missing_safety_doc)] mod generated { - embassy_hal_internal::interrupt_mod!(OS_EVENT, LPUART2, RTC, ADC1); + embassy_hal_internal::interrupt_mod!(OS_EVENT, LPUART0, LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, RTC, ADC1,); } use core::sync::atomic::{AtomicU16, AtomicU32, Ordering}; diff --git a/src/lib.rs b/src/lib.rs index 95e6b3479..f9dda67d9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,6 +88,7 @@ embassy_hal_internal::peripherals!( LPUART2, LPUART3, LPUART4, + LPUART5, MAU0, MBC0, diff --git a/src/lpuart/buffered.rs b/src/lpuart/buffered.rs index 7b575c086..6f41c33c9 100644 --- a/src/lpuart/buffered.rs +++ b/src/lpuart/buffered.rs @@ -123,28 +123,24 @@ impl<'a> BufferedLpuart<'a> { config: Config, ) -> Result { // Configure pins if provided - let tx_pin = tx_pin.map(|pin| { + let tx_pin: Option> = tx_pin.map(|pin| { pin.as_tx(); - let converted: Peri<'a, AnyPin> = pin.into(); - converted + pin.into() }); - let rx_pin = rx_pin.map(|pin| { + let rx_pin: Option> = rx_pin.map(|pin| { pin.as_rx(); - let converted: Peri<'a, AnyPin> = pin.into(); - converted + pin.into() }); - let rts_pin = rts_pin.map(|pin| { + let rts_pin: Option> = rts_pin.map(|pin| { pin.as_rts(); - let converted: Peri<'a, AnyPin> = pin.into(); - converted + pin.into() }); - let cts_pin = cts_pin.map(|pin| { + let cts_pin: Option> = cts_pin.map(|pin| { pin.as_cts(); - let converted: Peri<'a, AnyPin> = pin.into(); - converted + pin.into() }); let state = T::buffered_state(); diff --git a/src/lpuart/mod.rs b/src/lpuart/mod.rs index f069f6567..911c2a8e9 100644 --- a/src/lpuart/mod.rs +++ b/src/lpuart/mod.rs @@ -5,11 +5,12 @@ use paste::paste; use crate::clocks::periph_helpers::{Div4, LpuartClockSel, LpuartConfig}; use crate::clocks::{enable_and_reset, ClockError, Gate, PoweredClock}; +use crate::gpio::SealedPin; use crate::pac::lpuart0::baud::Sbns as StopBits; use crate::pac::lpuart0::ctrl::{Idlecfg as IdleConfig, Ilt as IdleType, Pt as Parity, M as DataBits}; use crate::pac::lpuart0::modir::{Txctsc as TxCtsConfig, Txctssrc as TxCtsSource}; use crate::pac::lpuart0::stat::Msbf as MsbFirst; -use crate::{interrupt, pac}; +use crate::{interrupt, pac, AnyPin}; pub mod buffered; @@ -20,55 +21,6 @@ pub mod buffered; // Stub implementation for LIB (Peripherals), GPIO, DMA and CLOCK until stable API // Pin and Clock initialization is currently done at the examples level. -// --- START GPIO --- - -mod gpio { - use embassy_hal_internal::PeripheralType; - trait SealedPin {} - - #[allow(private_bounds)] - pub trait GpioPin: SealedPin + Sized + PeripheralType + Into + 'static { - /// Type-erase the pin. - fn degrade(self) -> AnyPin { - todo!() - } - } - - // Add this macro to implement GpioPin for all pins - macro_rules! impl_gpio_pin { - ($($pin:ident),*) => { - $( - impl SealedPin for crate::peripherals::$pin {} - - impl GpioPin for crate::peripherals::$pin {} - - impl From for AnyPin { - // TODO: AJM: any reason we aren't using $pin? - fn from(_val: crate::peripherals::$pin) -> Self { - AnyPin - } - } - )* - }; - } - - // Implement GpioPin for all pins from lib.rs - impl_gpio_pin!(P2_2, P2_3); - - #[derive(Debug, Clone, Copy)] - pub struct AnyPin; - - impl PeripheralType for AnyPin {} - - pub enum Alt { - ALT3, - } -} - -use gpio::{AnyPin, GpioPin as Pin}; - -// --- END GPIO --- - // --- START DMA --- mod dma { pub struct Channel<'d> { @@ -144,8 +96,7 @@ macro_rules! impl_instance { }; } -// impl_instance!(0, 1, 2, 3, 4); -impl_instance!(2); +impl_instance!(0, 1, 2, 3, 4, 5); // ============================================================================ // INSTANCE HELPER FUNCTIONS @@ -391,54 +342,184 @@ pub fn has_data(regs: Regs) -> bool { // PIN TRAITS FOR LPUART FUNCTIONALITY // ============================================================================ -impl sealed::Sealed for T {} +impl sealed::Sealed for T {} /// io configuration trait for Lpuart Tx configuration -pub trait TxPin: Pin + sealed::Sealed + PeripheralType { +pub trait TxPin: Into + sealed::Sealed + PeripheralType { /// convert the pin to appropriate function for Lpuart Tx usage fn as_tx(&self); } /// io configuration trait for Lpuart Rx configuration -pub trait RxPin: Pin + sealed::Sealed + PeripheralType { +pub trait RxPin: Into + sealed::Sealed + PeripheralType { /// convert the pin to appropriate function for Lpuart Rx usage fn as_rx(&self); } /// io configuration trait for Lpuart Cts -pub trait CtsPin: Pin + sealed::Sealed + PeripheralType { +pub trait CtsPin: Into + sealed::Sealed + PeripheralType { /// convert the pin to appropriate function for Lpuart Cts usage fn as_cts(&self); } /// io configuration trait for Lpuart Rts -pub trait RtsPin: Pin + sealed::Sealed + PeripheralType { +pub trait RtsPin: Into + sealed::Sealed + PeripheralType { /// convert the pin to appropriate function for Lpuart Rts usage fn as_rts(&self); } -macro_rules! impl_pin_trait { - ($fcn:ident, $mode:ident, $($pin:ident, $alt:ident),*) => { - paste! { - $( - impl [<$mode:camel Pin>] for crate::peripherals::$pin { - fn [](&self) { - let _alt = gpio::Alt::$alt; - // todo!("Configure pin for LPUART function") - } - } - )* +macro_rules! impl_tx_pin { + ($inst:ident, $pin:ident, $alt:ident) => { + impl TxPin for crate::peripherals::$pin { + fn as_tx(&self) { + // TODO: Check these are right + self.set_pull(crate::gpio::Pull::Up); + self.set_slew_rate(crate::gpio::SlewRate::Fast.into()); + self.set_drive_strength(crate::gpio::DriveStrength::Double.into()); + self.set_function(crate::pac::port0::pcr0::Mux::$alt); + self.set_enable_input_buffer(); + } + } + }; +} + +macro_rules! impl_rx_pin { + ($inst:ident, $pin:ident, $alt:ident) => { + impl RxPin for crate::peripherals::$pin { + fn as_rx(&self) { + // TODO: Check these are right + self.set_pull(crate::gpio::Pull::Up); + self.set_slew_rate(crate::gpio::SlewRate::Fast.into()); + self.set_drive_strength(crate::gpio::DriveStrength::Double.into()); + self.set_function(crate::pac::port0::pcr0::Mux::$alt); + self.set_enable_input_buffer(); + } + } + }; +} + +// TODO: Macro and impls for CTS/RTS pins +macro_rules! impl_cts_pin { + ($inst:ident, $pin:ident, $alt:ident) => { + impl CtsPin for crate::peripherals::$pin { + fn as_cts(&self) { + todo!() + } + } + }; +} + +macro_rules! impl_rts_pin { + ($inst:ident, $pin:ident, $alt:ident) => { + impl RtsPin for crate::peripherals::$pin { + fn as_rts(&self) { + todo!() + } } }; } -// Document identifier: MCXA343/344 Rev. 1DraftB ReleaseCandidate, 2025-07-10 - 6.1 MCX A173, A174 Signal Multiplexing and Pin Assignments -// impl_pin_trait!(LPUART0, rx, P2_0, ALT2, P0_2, ALT2, P0_20, ALT3); -// impl_pin_trait!(LPUART0, tx, P2_1, ALT2, P0_3, ALT2, P0_21, ALT3); -// impl_pin_trait!(LPUART0, rts, P2_2, ALT2, P0_0, ALT2, P0_22, ALT3); -// impl_pin_trait!(LPUART0, cts, P2_3, ALT2, P0_1, ALT2, P0_23, ALT3); -impl_pin_trait!(LPUART2, rx, P2_3, ALT3); -impl_pin_trait!(LPUART2, tx, P2_2, ALT3); +// LPUART 0 +impl_tx_pin!(LPUART0, P0_3, Mux2); +impl_tx_pin!(LPUART0, P0_21, Mux3); +impl_tx_pin!(LPUART0, P2_1, Mux2); + +impl_rx_pin!(LPUART0, P0_2, Mux2); +impl_rx_pin!(LPUART0, P0_20, Mux3); +impl_rx_pin!(LPUART0, P2_0, Mux2); + +impl_cts_pin!(LPUART0, P0_1, Mux2); +impl_cts_pin!(LPUART0, P0_23, Mux3); +impl_cts_pin!(LPUART0, P2_3, Mux2); + +impl_rts_pin!(LPUART0, P0_0, Mux2); +impl_rts_pin!(LPUART0, P0_22, Mux3); +impl_rts_pin!(LPUART0, P2_2, Mux2); + +// LPUART 1 +impl_tx_pin!(LPUART1, P1_9, Mux2); +impl_tx_pin!(LPUART1, P2_13, Mux3); +impl_tx_pin!(LPUART1, P3_9, Mux3); +impl_tx_pin!(LPUART1, P3_21, Mux3); + +impl_rx_pin!(LPUART1, P1_8, Mux2); +impl_rx_pin!(LPUART1, P2_12, Mux3); +impl_rx_pin!(LPUART1, P3_8, Mux3); +impl_rx_pin!(LPUART1, P3_20, Mux3); + +impl_cts_pin!(LPUART1, P1_11, Mux2); +impl_cts_pin!(LPUART1, P2_17, Mux3); +impl_cts_pin!(LPUART1, P3_11, Mux3); +impl_cts_pin!(LPUART1, P3_23, Mux3); + +impl_rts_pin!(LPUART1, P1_10, Mux2); +impl_rts_pin!(LPUART1, P2_15, Mux3); +impl_rts_pin!(LPUART1, P2_16, Mux3); +impl_rts_pin!(LPUART1, P3_10, Mux3); + +// LPUART 2 +impl_tx_pin!(LPUART2, P1_5, Mux3); +impl_tx_pin!(LPUART2, P1_13, Mux3); +impl_tx_pin!(LPUART2, P2_2, Mux3); +impl_tx_pin!(LPUART2, P2_10, Mux3); +impl_tx_pin!(LPUART2, P3_15, Mux2); + +impl_rx_pin!(LPUART2, P1_4, Mux3); +impl_rx_pin!(LPUART2, P1_12, Mux3); +impl_rx_pin!(LPUART2, P2_3, Mux3); +impl_rx_pin!(LPUART2, P2_11, Mux3); +impl_rx_pin!(LPUART2, P3_14, Mux2); + +impl_cts_pin!(LPUART2, P1_7, Mux3); +impl_cts_pin!(LPUART2, P1_15, Mux3); +impl_cts_pin!(LPUART2, P2_4, Mux3); +impl_cts_pin!(LPUART2, P3_13, Mux2); + +impl_rts_pin!(LPUART2, P1_6, Mux3); +impl_rts_pin!(LPUART2, P1_14, Mux3); +impl_rts_pin!(LPUART2, P2_5, Mux3); +impl_rts_pin!(LPUART2, P3_12, Mux2); + +// LPUART 3 +impl_tx_pin!(LPUART3, P3_1, Mux3); +impl_tx_pin!(LPUART3, P3_12, Mux3); +impl_tx_pin!(LPUART3, P4_5, Mux3); + +impl_rx_pin!(LPUART3, P3_0, Mux3); +impl_rx_pin!(LPUART3, P3_13, Mux3); +impl_rx_pin!(LPUART3, P4_2, Mux3); + +impl_cts_pin!(LPUART3, P3_7, Mux3); +impl_cts_pin!(LPUART3, P3_14, Mux3); +impl_cts_pin!(LPUART3, P4_6, Mux3); + +impl_rts_pin!(LPUART3, P3_6, Mux3); +impl_rts_pin!(LPUART3, P3_15, Mux3); +impl_rts_pin!(LPUART3, P4_7, Mux3); + +// LPUART 4 +impl_tx_pin!(LPUART4, P2_7, Mux3); +impl_tx_pin!(LPUART4, P3_19, Mux2); +impl_tx_pin!(LPUART4, P3_27, Mux3); +impl_tx_pin!(LPUART4, P4_3, Mux3); + +impl_rx_pin!(LPUART4, P2_6, Mux3); +impl_rx_pin!(LPUART4, P3_18, Mux2); +impl_rx_pin!(LPUART4, P3_28, Mux3); +impl_rx_pin!(LPUART4, P4_4, Mux3); + +impl_cts_pin!(LPUART4, P2_0, Mux3); +impl_cts_pin!(LPUART4, P3_17, Mux2); +impl_cts_pin!(LPUART4, P3_31, Mux3); + +impl_rts_pin!(LPUART4, P2_1, Mux3); +impl_rts_pin!(LPUART4, P3_16, Mux2); +impl_rts_pin!(LPUART4, P3_30, Mux3); + +// LPUART 5 +// +// TODO: The datasheet doesn't list tx/rx/cts/rts pins for LPUART5 +// See https://github.com/OpenDevicePartnership/embassy-mcxa/issues/48 // ============================================================================ // ERROR TYPES AND RESULTS diff --git a/src/pins.rs b/src/pins.rs index 0a83a41f0..fdf1b0a86 100644 --- a/src/pins.rs +++ b/src/pins.rs @@ -1,40 +1,6 @@ //! Pin configuration helpers (separate from peripheral drivers). use crate::pac; -pub unsafe fn configure_uart2_pins_port2() { - // P2_2 = LPUART2_TX ALT3, P2_3 = LPUART2_RX ALT3 with pull-up, input enable, high drive, slow slew. - let port2 = &*pac::Port2::ptr(); - port2.pcr2().write(|w| { - w.ps() - .ps1() - .pe() - .pe1() - .sre() - .sre1() - .dse() - .dse1() - .mux() - .mux3() - .ibe() - .ibe1() - }); - port2.pcr3().write(|w| { - w.ps() - .ps1() - .pe() - .pe1() - .sre() - .sre1() - .dse() - .dse1() - .mux() - .mux3() - .ibe() - .ibe1() - }); - core::arch::asm!("dsb sy; isb sy"); -} - pub unsafe fn configure_adc_pins() { // P1_10 = ADC1_A8 let port1 = &*pac::Port1::ptr(); -- cgit