imxrt_iomuxc/lpuart.rs
1//! UART pad configuration
2
3/// Type tag for the transfer pin
4pub enum Tx {}
5/// Type tag for the receive pin
6pub enum Rx {}
7
8/// A pin direction, either transfer or receive
9pub trait Direction: private::Sealed {}
10
11impl Direction for Tx {}
12impl Direction for Rx {}
13
14mod private {
15 pub trait Sealed {}
16 impl Sealed for super::Tx {}
17 impl Sealed for super::Rx {}
18}
19
20/// A UART pin
21pub trait Pin: super::Iomuxc {
22 /// The alternate value for the UART pin
23 const ALT: u32;
24 /// The daisy register which will select the pad
25 const DAISY: Option<super::Daisy>;
26 /// Pin direction
27 type Direction: Direction;
28 /// UART module; `U3` for `UART3`
29 type Module: super::consts::Unsigned;
30}
31
32/// Prepare a UART pin
33///
34/// If you do not call `prepare()` on your UART pin, it might not work as a UART
35/// pin.
36///
37/// # Safety
38///
39/// `prepare()` inherits all the unsafety that comes from the `IOMUX` supertrait.
40/// In particular, we cannot be sure that the implementation's pointers are correct.
41/// It may also write a daisy configuration that's incorrect.
42pub fn prepare<P: Pin>(pin: &mut P) {
43 super::alternate(pin, P::ALT);
44 super::clear_sion(pin);
45 if let Some(daisy) = P::DAISY {
46 unsafe { daisy.write() };
47 }
48}
49
50#[allow(unused)] // Used in chip-specific modules...
51macro_rules! uart {
52 (module: $module:ty, alt: $alt:expr, pad: $pad:ty, direction: $direction:ty, daisy: $daisy:expr) => {
53 impl Pin for $pad {
54 const ALT: u32 = $alt;
55 const DAISY: Option<Daisy> = $daisy;
56 type Direction = $direction;
57 type Module = $module;
58 }
59 };
60}