aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJames Munns <[email protected]>2025-11-25 18:08:13 +0100
committerGitHub <[email protected]>2025-11-25 18:08:13 +0100
commit05bf2d0438fe8c41d0fe26b85106ff73a6e273e9 (patch)
tree8a2969ac89735154f8090d629d9c37814a25190a /src
parent7ee5cb570f0c0daeb2e6a9d5120fd96ee885025f (diff)
Wire up Lpuart pins (#43)
Allow the HAL lpuart driver to correctly configure pins as requested on init.
Diffstat (limited to 'src')
-rw-r--r--src/clocks/config.rs5
-rw-r--r--src/clocks/mod.rs5
-rw-r--r--src/interrupt.rs2
-rw-r--r--src/lib.rs1
-rw-r--r--src/lpuart/buffered.rs20
-rw-r--r--src/lpuart/mod.rs231
-rw-r--r--src/pins.rs34
7 files changed, 176 insertions, 122 deletions
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 {
21 Self(n) 21 Self(n)
22 } 22 }
23 23
24 /// Divide by one, or no division
25 pub const fn no_div() -> Self {
26 Self(0)
27 }
28
24 /// Store a specific divisor value that will divide the source 29 /// Store a specific divisor value that will divide the source
25 /// by `n`. e.g. `Div8::from_divisor(1)` will divide the source 30 /// by `n`. e.g. `Div8::from_divisor(1)` will divide the source
26 /// by 1, and `Div8::from_divisor(256)` will divide the source 31 /// 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 {
928 #[cfg(not(feature = "time"))] 928 #[cfg(not(feature = "time"))]
929 impl_cc_gate!(OSTIMER0, mrcc_glb_cc1, mrcc_glb_rst1, ostimer0, OsTimerConfig); 929 impl_cc_gate!(OSTIMER0, mrcc_glb_cc1, mrcc_glb_rst1, ostimer0, OsTimerConfig);
930 930
931 impl_cc_gate!(LPUART0, mrcc_glb_cc0, mrcc_glb_rst0, lpuart0, LpuartConfig);
932 impl_cc_gate!(LPUART1, mrcc_glb_cc0, mrcc_glb_rst0, lpuart1, LpuartConfig);
931 impl_cc_gate!(LPUART2, mrcc_glb_cc0, mrcc_glb_rst0, lpuart2, LpuartConfig); 933 impl_cc_gate!(LPUART2, mrcc_glb_cc0, mrcc_glb_rst0, lpuart2, LpuartConfig);
934 impl_cc_gate!(LPUART3, mrcc_glb_cc0, mrcc_glb_rst0, lpuart3, LpuartConfig);
935 impl_cc_gate!(LPUART4, mrcc_glb_cc0, mrcc_glb_rst0, lpuart4, LpuartConfig);
936 impl_cc_gate!(LPUART5, mrcc_glb_cc1, mrcc_glb_rst1, lpuart5, LpuartConfig);
932 impl_cc_gate!(ADC1, mrcc_glb_cc1, mrcc_glb_rst1, adc1, AdcConfig); 937 impl_cc_gate!(ADC1, mrcc_glb_cc1, mrcc_glb_rst1, adc1, AdcConfig);
933} 938}
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 @@
7#![allow(clippy::missing_safety_doc)] 7#![allow(clippy::missing_safety_doc)]
8 8
9mod generated { 9mod generated {
10 embassy_hal_internal::interrupt_mod!(OS_EVENT, LPUART2, RTC, ADC1); 10 embassy_hal_internal::interrupt_mod!(OS_EVENT, LPUART0, LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, RTC, ADC1,);
11} 11}
12 12
13use core::sync::atomic::{AtomicU16, AtomicU32, Ordering}; 13use 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!(
88 LPUART2, 88 LPUART2,
89 LPUART3, 89 LPUART3,
90 LPUART4, 90 LPUART4,
91 LPUART5,
91 92
92 MAU0, 93 MAU0,
93 MBC0, 94 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> {
123 config: Config, 123 config: Config,
124 ) -> Result<Self> { 124 ) -> Result<Self> {
125 // Configure pins if provided 125 // Configure pins if provided
126 let tx_pin = tx_pin.map(|pin| { 126 let tx_pin: Option<Peri<'a, AnyPin>> = tx_pin.map(|pin| {
127 pin.as_tx(); 127 pin.as_tx();
128 let converted: Peri<'a, AnyPin> = pin.into(); 128 pin.into()
129 converted
130 }); 129 });
131 130
132 let rx_pin = rx_pin.map(|pin| { 131 let rx_pin: Option<Peri<'a, AnyPin>> = rx_pin.map(|pin| {
133 pin.as_rx(); 132 pin.as_rx();
134 let converted: Peri<'a, AnyPin> = pin.into(); 133 pin.into()
135 converted
136 }); 134 });
137 135
138 let rts_pin = rts_pin.map(|pin| { 136 let rts_pin: Option<Peri<'a, AnyPin>> = rts_pin.map(|pin| {
139 pin.as_rts(); 137 pin.as_rts();
140 let converted: Peri<'a, AnyPin> = pin.into(); 138 pin.into()
141 converted
142 }); 139 });
143 140
144 let cts_pin = cts_pin.map(|pin| { 141 let cts_pin: Option<Peri<'a, AnyPin>> = cts_pin.map(|pin| {
145 pin.as_cts(); 142 pin.as_cts();
146 let converted: Peri<'a, AnyPin> = pin.into(); 143 pin.into()
147 converted
148 }); 144 });
149 145
150 let state = T::buffered_state(); 146 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;
5 5
6use crate::clocks::periph_helpers::{Div4, LpuartClockSel, LpuartConfig}; 6use crate::clocks::periph_helpers::{Div4, LpuartClockSel, LpuartConfig};
7use crate::clocks::{enable_and_reset, ClockError, Gate, PoweredClock}; 7use crate::clocks::{enable_and_reset, ClockError, Gate, PoweredClock};
8use crate::gpio::SealedPin;
8use crate::pac::lpuart0::baud::Sbns as StopBits; 9use crate::pac::lpuart0::baud::Sbns as StopBits;
9use crate::pac::lpuart0::ctrl::{Idlecfg as IdleConfig, Ilt as IdleType, Pt as Parity, M as DataBits}; 10use crate::pac::lpuart0::ctrl::{Idlecfg as IdleConfig, Ilt as IdleType, Pt as Parity, M as DataBits};
10use crate::pac::lpuart0::modir::{Txctsc as TxCtsConfig, Txctssrc as TxCtsSource}; 11use crate::pac::lpuart0::modir::{Txctsc as TxCtsConfig, Txctssrc as TxCtsSource};
11use crate::pac::lpuart0::stat::Msbf as MsbFirst; 12use crate::pac::lpuart0::stat::Msbf as MsbFirst;
12use crate::{interrupt, pac}; 13use crate::{interrupt, pac, AnyPin};
13 14
14pub mod buffered; 15pub mod buffered;
15 16
@@ -20,55 +21,6 @@ pub mod buffered;
20// Stub implementation for LIB (Peripherals), GPIO, DMA and CLOCK until stable API 21// Stub implementation for LIB (Peripherals), GPIO, DMA and CLOCK until stable API
21// Pin and Clock initialization is currently done at the examples level. 22// Pin and Clock initialization is currently done at the examples level.
22 23
23// --- START GPIO ---
24
25mod gpio {
26 use embassy_hal_internal::PeripheralType;
27 trait SealedPin {}
28
29 #[allow(private_bounds)]
30 pub trait GpioPin: SealedPin + Sized + PeripheralType + Into<AnyPin> + 'static {
31 /// Type-erase the pin.
32 fn degrade(self) -> AnyPin {
33 todo!()
34 }
35 }
36
37 // Add this macro to implement GpioPin for all pins
38 macro_rules! impl_gpio_pin {
39 ($($pin:ident),*) => {
40 $(
41 impl SealedPin for crate::peripherals::$pin {}
42
43 impl GpioPin for crate::peripherals::$pin {}
44
45 impl From<crate::peripherals::$pin> for AnyPin {
46 // TODO: AJM: any reason we aren't using $pin?
47 fn from(_val: crate::peripherals::$pin) -> Self {
48 AnyPin
49 }
50 }
51 )*
52 };
53 }
54
55 // Implement GpioPin for all pins from lib.rs
56 impl_gpio_pin!(P2_2, P2_3);
57
58 #[derive(Debug, Clone, Copy)]
59 pub struct AnyPin;
60
61 impl PeripheralType for AnyPin {}
62
63 pub enum Alt {
64 ALT3,
65 }
66}
67
68use gpio::{AnyPin, GpioPin as Pin};
69
70// --- END GPIO ---
71
72// --- START DMA --- 24// --- START DMA ---
73mod dma { 25mod dma {
74 pub struct Channel<'d> { 26 pub struct Channel<'d> {
@@ -144,8 +96,7 @@ macro_rules! impl_instance {
144 }; 96 };
145} 97}
146 98
147// impl_instance!(0, 1, 2, 3, 4); 99impl_instance!(0, 1, 2, 3, 4, 5);
148impl_instance!(2);
149 100
150// ============================================================================ 101// ============================================================================
151// INSTANCE HELPER FUNCTIONS 102// INSTANCE HELPER FUNCTIONS
@@ -391,54 +342,184 @@ pub fn has_data(regs: Regs) -> bool {
391// PIN TRAITS FOR LPUART FUNCTIONALITY 342// PIN TRAITS FOR LPUART FUNCTIONALITY
392// ============================================================================ 343// ============================================================================
393 344
394impl<T: Pin> sealed::Sealed for T {} 345impl<T: SealedPin> sealed::Sealed for T {}
395 346
396/// io configuration trait for Lpuart Tx configuration 347/// io configuration trait for Lpuart Tx configuration
397pub trait TxPin<T: Instance>: Pin + sealed::Sealed + PeripheralType { 348pub trait TxPin<T: Instance>: Into<AnyPin> + sealed::Sealed + PeripheralType {
398 /// convert the pin to appropriate function for Lpuart Tx usage 349 /// convert the pin to appropriate function for Lpuart Tx usage
399 fn as_tx(&self); 350 fn as_tx(&self);
400} 351}
401 352
402/// io configuration trait for Lpuart Rx configuration 353/// io configuration trait for Lpuart Rx configuration
403pub trait RxPin<T: Instance>: Pin + sealed::Sealed + PeripheralType { 354pub trait RxPin<T: Instance>: Into<AnyPin> + sealed::Sealed + PeripheralType {
404 /// convert the pin to appropriate function for Lpuart Rx usage 355 /// convert the pin to appropriate function for Lpuart Rx usage
405 fn as_rx(&self); 356 fn as_rx(&self);
406} 357}
407 358
408/// io configuration trait for Lpuart Cts 359/// io configuration trait for Lpuart Cts
409pub trait CtsPin<T: Instance>: Pin + sealed::Sealed + PeripheralType { 360pub trait CtsPin<T: Instance>: Into<AnyPin> + sealed::Sealed + PeripheralType {
410 /// convert the pin to appropriate function for Lpuart Cts usage 361 /// convert the pin to appropriate function for Lpuart Cts usage
411 fn as_cts(&self); 362 fn as_cts(&self);
412} 363}
413 364
414/// io configuration trait for Lpuart Rts 365/// io configuration trait for Lpuart Rts
415pub trait RtsPin<T: Instance>: Pin + sealed::Sealed + PeripheralType { 366pub trait RtsPin<T: Instance>: Into<AnyPin> + sealed::Sealed + PeripheralType {
416 /// convert the pin to appropriate function for Lpuart Rts usage 367 /// convert the pin to appropriate function for Lpuart Rts usage
417 fn as_rts(&self); 368 fn as_rts(&self);
418} 369}
419 370
420macro_rules! impl_pin_trait { 371macro_rules! impl_tx_pin {
421 ($fcn:ident, $mode:ident, $($pin:ident, $alt:ident),*) => { 372 ($inst:ident, $pin:ident, $alt:ident) => {
422 paste! { 373 impl TxPin<crate::peripherals::$inst> for crate::peripherals::$pin {
423 $( 374 fn as_tx(&self) {
424 impl [<$mode:camel Pin>]<crate::peripherals::$fcn> for crate::peripherals::$pin { 375 // TODO: Check these are right
425 fn [<as_ $mode>](&self) { 376 self.set_pull(crate::gpio::Pull::Up);
426 let _alt = gpio::Alt::$alt; 377 self.set_slew_rate(crate::gpio::SlewRate::Fast.into());
427 // todo!("Configure pin for LPUART function") 378 self.set_drive_strength(crate::gpio::DriveStrength::Double.into());
428 } 379 self.set_function(crate::pac::port0::pcr0::Mux::$alt);
429 } 380 self.set_enable_input_buffer();
430 )* 381 }
382 }
383 };
384}
385
386macro_rules! impl_rx_pin {
387 ($inst:ident, $pin:ident, $alt:ident) => {
388 impl RxPin<crate::peripherals::$inst> for crate::peripherals::$pin {
389 fn as_rx(&self) {
390 // TODO: Check these are right
391 self.set_pull(crate::gpio::Pull::Up);
392 self.set_slew_rate(crate::gpio::SlewRate::Fast.into());
393 self.set_drive_strength(crate::gpio::DriveStrength::Double.into());
394 self.set_function(crate::pac::port0::pcr0::Mux::$alt);
395 self.set_enable_input_buffer();
396 }
397 }
398 };
399}
400
401// TODO: Macro and impls for CTS/RTS pins
402macro_rules! impl_cts_pin {
403 ($inst:ident, $pin:ident, $alt:ident) => {
404 impl CtsPin<crate::peripherals::$inst> for crate::peripherals::$pin {
405 fn as_cts(&self) {
406 todo!()
407 }
408 }
409 };
410}
411
412macro_rules! impl_rts_pin {
413 ($inst:ident, $pin:ident, $alt:ident) => {
414 impl RtsPin<crate::peripherals::$inst> for crate::peripherals::$pin {
415 fn as_rts(&self) {
416 todo!()
417 }
431 } 418 }
432 }; 419 };
433} 420}
434 421
435// Document identifier: MCXA343/344 Rev. 1DraftB ReleaseCandidate, 2025-07-10 - 6.1 MCX A173, A174 Signal Multiplexing and Pin Assignments 422// LPUART 0
436// impl_pin_trait!(LPUART0, rx, P2_0, ALT2, P0_2, ALT2, P0_20, ALT3); 423impl_tx_pin!(LPUART0, P0_3, Mux2);
437// impl_pin_trait!(LPUART0, tx, P2_1, ALT2, P0_3, ALT2, P0_21, ALT3); 424impl_tx_pin!(LPUART0, P0_21, Mux3);
438// impl_pin_trait!(LPUART0, rts, P2_2, ALT2, P0_0, ALT2, P0_22, ALT3); 425impl_tx_pin!(LPUART0, P2_1, Mux2);
439// impl_pin_trait!(LPUART0, cts, P2_3, ALT2, P0_1, ALT2, P0_23, ALT3); 426
440impl_pin_trait!(LPUART2, rx, P2_3, ALT3); 427impl_rx_pin!(LPUART0, P0_2, Mux2);
441impl_pin_trait!(LPUART2, tx, P2_2, ALT3); 428impl_rx_pin!(LPUART0, P0_20, Mux3);
429impl_rx_pin!(LPUART0, P2_0, Mux2);
430
431impl_cts_pin!(LPUART0, P0_1, Mux2);
432impl_cts_pin!(LPUART0, P0_23, Mux3);
433impl_cts_pin!(LPUART0, P2_3, Mux2);
434
435impl_rts_pin!(LPUART0, P0_0, Mux2);
436impl_rts_pin!(LPUART0, P0_22, Mux3);
437impl_rts_pin!(LPUART0, P2_2, Mux2);
438
439// LPUART 1
440impl_tx_pin!(LPUART1, P1_9, Mux2);
441impl_tx_pin!(LPUART1, P2_13, Mux3);
442impl_tx_pin!(LPUART1, P3_9, Mux3);
443impl_tx_pin!(LPUART1, P3_21, Mux3);
444
445impl_rx_pin!(LPUART1, P1_8, Mux2);
446impl_rx_pin!(LPUART1, P2_12, Mux3);
447impl_rx_pin!(LPUART1, P3_8, Mux3);
448impl_rx_pin!(LPUART1, P3_20, Mux3);
449
450impl_cts_pin!(LPUART1, P1_11, Mux2);
451impl_cts_pin!(LPUART1, P2_17, Mux3);
452impl_cts_pin!(LPUART1, P3_11, Mux3);
453impl_cts_pin!(LPUART1, P3_23, Mux3);
454
455impl_rts_pin!(LPUART1, P1_10, Mux2);
456impl_rts_pin!(LPUART1, P2_15, Mux3);
457impl_rts_pin!(LPUART1, P2_16, Mux3);
458impl_rts_pin!(LPUART1, P3_10, Mux3);
459
460// LPUART 2
461impl_tx_pin!(LPUART2, P1_5, Mux3);
462impl_tx_pin!(LPUART2, P1_13, Mux3);
463impl_tx_pin!(LPUART2, P2_2, Mux3);
464impl_tx_pin!(LPUART2, P2_10, Mux3);
465impl_tx_pin!(LPUART2, P3_15, Mux2);
466
467impl_rx_pin!(LPUART2, P1_4, Mux3);
468impl_rx_pin!(LPUART2, P1_12, Mux3);
469impl_rx_pin!(LPUART2, P2_3, Mux3);
470impl_rx_pin!(LPUART2, P2_11, Mux3);
471impl_rx_pin!(LPUART2, P3_14, Mux2);
472
473impl_cts_pin!(LPUART2, P1_7, Mux3);
474impl_cts_pin!(LPUART2, P1_15, Mux3);
475impl_cts_pin!(LPUART2, P2_4, Mux3);
476impl_cts_pin!(LPUART2, P3_13, Mux2);
477
478impl_rts_pin!(LPUART2, P1_6, Mux3);
479impl_rts_pin!(LPUART2, P1_14, Mux3);
480impl_rts_pin!(LPUART2, P2_5, Mux3);
481impl_rts_pin!(LPUART2, P3_12, Mux2);
482
483// LPUART 3
484impl_tx_pin!(LPUART3, P3_1, Mux3);
485impl_tx_pin!(LPUART3, P3_12, Mux3);
486impl_tx_pin!(LPUART3, P4_5, Mux3);
487
488impl_rx_pin!(LPUART3, P3_0, Mux3);
489impl_rx_pin!(LPUART3, P3_13, Mux3);
490impl_rx_pin!(LPUART3, P4_2, Mux3);
491
492impl_cts_pin!(LPUART3, P3_7, Mux3);
493impl_cts_pin!(LPUART3, P3_14, Mux3);
494impl_cts_pin!(LPUART3, P4_6, Mux3);
495
496impl_rts_pin!(LPUART3, P3_6, Mux3);
497impl_rts_pin!(LPUART3, P3_15, Mux3);
498impl_rts_pin!(LPUART3, P4_7, Mux3);
499
500// LPUART 4
501impl_tx_pin!(LPUART4, P2_7, Mux3);
502impl_tx_pin!(LPUART4, P3_19, Mux2);
503impl_tx_pin!(LPUART4, P3_27, Mux3);
504impl_tx_pin!(LPUART4, P4_3, Mux3);
505
506impl_rx_pin!(LPUART4, P2_6, Mux3);
507impl_rx_pin!(LPUART4, P3_18, Mux2);
508impl_rx_pin!(LPUART4, P3_28, Mux3);
509impl_rx_pin!(LPUART4, P4_4, Mux3);
510
511impl_cts_pin!(LPUART4, P2_0, Mux3);
512impl_cts_pin!(LPUART4, P3_17, Mux2);
513impl_cts_pin!(LPUART4, P3_31, Mux3);
514
515impl_rts_pin!(LPUART4, P2_1, Mux3);
516impl_rts_pin!(LPUART4, P3_16, Mux2);
517impl_rts_pin!(LPUART4, P3_30, Mux3);
518
519// LPUART 5
520//
521// TODO: The datasheet doesn't list tx/rx/cts/rts pins for LPUART5
522// See https://github.com/OpenDevicePartnership/embassy-mcxa/issues/48
442 523
443// ============================================================================ 524// ============================================================================
444// ERROR TYPES AND RESULTS 525// 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 @@
1//! Pin configuration helpers (separate from peripheral drivers). 1//! Pin configuration helpers (separate from peripheral drivers).
2use crate::pac; 2use crate::pac;
3 3
4pub unsafe fn configure_uart2_pins_port2() {
5 // P2_2 = LPUART2_TX ALT3, P2_3 = LPUART2_RX ALT3 with pull-up, input enable, high drive, slow slew.
6 let port2 = &*pac::Port2::ptr();
7 port2.pcr2().write(|w| {
8 w.ps()
9 .ps1()
10 .pe()
11 .pe1()
12 .sre()
13 .sre1()
14 .dse()
15 .dse1()
16 .mux()
17 .mux3()
18 .ibe()
19 .ibe1()
20 });
21 port2.pcr3().write(|w| {
22 w.ps()
23 .ps1()
24 .pe()
25 .pe1()
26 .sre()
27 .sre1()
28 .dse()
29 .dse1()
30 .mux()
31 .mux3()
32 .ibe()
33 .ibe1()
34 });
35 core::arch::asm!("dsb sy; isb sy");
36}
37
38pub unsafe fn configure_adc_pins() { 4pub unsafe fn configure_adc_pins() {
39 // P1_10 = ADC1_A8 5 // P1_10 = ADC1_A8
40 let port1 = &*pac::Port1::ptr(); 6 let port1 = &*pac::Port1::ptr();