use crate::gpio::{bank0, FunctionUart, Pin};
use crate::pac::{UART0, UART1};
use crate::typelevel::Sealed;
use super::UartDevice;
pub trait ValidUartPinout<UART: UartDevice> {
const TX_ENABLED: bool;
const RX_ENABLED: bool;
const CTS_ENABLED: bool;
const RTS_ENABLED: bool;
}
impl<UART, TX, RX, CTS, RTS> ValidUartPinout<UART> for Pins<TX, RX, CTS, RTS>
where
UART: UartDevice,
TX: Tx<UART>,
RX: Rx<UART>,
CTS: Cts<UART>,
RTS: Rts<UART>,
{
const TX_ENABLED: bool = TX::ENABLED;
const RX_ENABLED: bool = RX::ENABLED;
const CTS_ENABLED: bool = CTS::ENABLED;
const RTS_ENABLED: bool = RTS::ENABLED;
}
impl<UART, TX, RX> ValidUartPinout<UART> for (TX, RX)
where
UART: UartDevice,
TX: Tx<UART>,
RX: Rx<UART>,
{
const TX_ENABLED: bool = TX::ENABLED;
const RX_ENABLED: bool = RX::ENABLED;
const CTS_ENABLED: bool = false;
const RTS_ENABLED: bool = false;
}
impl<UART, TX, RX, CTS, RTS> ValidUartPinout<UART> for (TX, RX, CTS, RTS)
where
UART: UartDevice,
TX: Tx<UART>,
RX: Rx<UART>,
CTS: Cts<UART>,
RTS: Rts<UART>,
{
const TX_ENABLED: bool = TX::ENABLED;
const RX_ENABLED: bool = RX::ENABLED;
const CTS_ENABLED: bool = CTS::ENABLED;
const RTS_ENABLED: bool = RTS::ENABLED;
}
#[allow(missing_docs)]
pub struct Pins<TX, RX, CTS, RTS> {
pub tx: TX,
pub rx: RX,
pub rts: RTS,
pub cts: CTS,
}
impl Default for Pins<(), (), (), ()> {
fn default() -> Self {
Self {
tx: (),
rx: (),
rts: (),
cts: (),
}
}
}
impl<TX, RX, CTS, RTS> Pins<TX, RX, CTS, RTS> {
pub fn tx<NTX>(self, tx: NTX) -> Pins<NTX, RX, CTS, RTS> {
Pins {
tx,
rx: self.rx,
rts: self.rts,
cts: self.cts,
}
}
pub fn rx<NRX>(self, rx: NRX) -> Pins<TX, NRX, CTS, RTS> {
Pins {
tx: self.tx,
rx,
rts: self.rts,
cts: self.cts,
}
}
pub fn cts<NCTS>(self, cts: NCTS) -> Pins<TX, RX, NCTS, RTS> {
Pins {
tx: self.tx,
rx: self.rx,
rts: self.rts,
cts,
}
}
pub fn rts<NRTS>(self, rts: NRTS) -> Pins<TX, RX, CTS, NRTS> {
Pins {
tx: self.tx,
rx: self.rx,
rts,
cts: self.cts,
}
}
}
pub trait Tx<UART: UartDevice>: Sealed {
#[allow(missing_docs)]
const ENABLED: bool;
}
pub trait Rx<UART: UartDevice>: Sealed {
#[allow(missing_docs)]
const ENABLED: bool;
}
pub trait Cts<UART: UartDevice>: Sealed {
#[allow(missing_docs)]
const ENABLED: bool;
}
pub trait Rts<UART: UartDevice>: Sealed {
#[allow(missing_docs)]
const ENABLED: bool;
}
impl<UART: UartDevice> Tx<UART> for () {
const ENABLED: bool = false;
}
impl<UART: UartDevice> Rx<UART> for () {
const ENABLED: bool = false;
}
impl<UART: UartDevice> Cts<UART> for () {
const ENABLED: bool = false;
}
impl<UART: UartDevice> Rts<UART> for () {
const ENABLED: bool = false;
}
impl Sealed for () {}
macro_rules! impl_valid_uart {
($($uart:ident: {
tx: [$($tx:ident),*],
rx: [$($rx:ident),*],
cts: [$($cts:ident),*],
rts: [$($rts:ident),*],
}),*) => {
$(
$(
impl Tx<$uart> for Pin<bank0::$tx, FunctionUart> {
const ENABLED: bool = true;
}
)*
$(
impl Rx<$uart> for Pin<bank0::$rx, FunctionUart> {
const ENABLED: bool = true;
}
)*
$(
impl Cts<$uart> for Pin<bank0::$cts, FunctionUart> {
const ENABLED: bool = true;
}
)*
$(
impl Rts<$uart> for Pin<bank0::$rts, FunctionUart> {
const ENABLED: bool = true;
}
)*
)*
};
}
impl_valid_uart!(
UART0: {
tx: [Gpio0, Gpio12, Gpio16, Gpio28],
rx: [Gpio1, Gpio13, Gpio17, Gpio29],
cts: [Gpio2, Gpio14, Gpio18],
rts: [Gpio3, Gpio15, Gpio19],
},
UART1: {
tx: [Gpio4, Gpio8, Gpio20, Gpio24],
rx: [Gpio5, Gpio9, Gpio21, Gpio25],
cts: [Gpio6, Gpio10, Gpio22, Gpio26],
rts: [Gpio7, Gpio11, Gpio23, Gpio27],
}
);