Skip to content

Instantly share code, notes, and snippets.

@VictorKoenders
Last active November 25, 2021 08:14
Show Gist options
  • Save VictorKoenders/f57319393531dd2e9173c0dad054d282 to your computer and use it in GitHub Desktop.
Save VictorKoenders/f57319393531dd2e9173c0dad054d282 to your computer and use it in GitHub Desktop.
rp-hal uart proposal
// Usage:
let pins = ( // TX, RX
pins.gpio0.into_mode(),
pins.gpio1.into_mode(),
);
let pins = ( // TX, RX, CTS, RTS
pins.gpio0.into_mode(),
pins.gpio1.into_mode(),
pins.gpio2.into_mode(),
pins.gpio3.into_mode(),
);
// or
let pins = Pins::new() // TX, RX, CTS (RTS = ())
.tx(pins.gpio0.into_mode())
.rx(pins.gpio1.into_mode())
.cts(pins.gpio2.into_mode());
// or
let pins = Pins {// TX, RX (CTS = (), RTS = ())
tx: pins.gpio.into_mode(),
rx: pins.gpio1.into_mode(),
cts: (),
rts: ()
};
// Uart pin definition:
pub trait ValidUartPins<UART> {}
impl<UART, TX, RX, CTS, RTS> ValidUartPins<UART> for Pins<TX, RX, CTS, RTS>
where
TX: Tx<UART>,
RX: Rx<UART>,
CTS: Cts<UART>,
RTS: Rts<UART>,
{
}
impl<UART, TX, RX> ValidUartPins<UART> for (TX, RX)
where
TX: Tx<UART>,
RX: Rx<UART>,
{
}
impl<UART, TX, RX, CTS, RTS> ValidUartPins<UART> for (TX, RX, CTS, RTS)
where
TX: Tx<UART>,
RX: Rx<UART>,
CTS: Cts<UART>,
RTS: Rts<UART>,
{
}
pub struct Pins<TX, RX, CTS, RTS> {
pub tx: TX,
pub rx: RX,
pub rts: RTS,
pub cts: CTS,
}
impl Pins<(), (), (), ()> {
pub fn new() -> 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> {
const IS_SET: bool;
}
pub trait Rx<UART> {
const IS_SET: bool;
}
pub trait Cts<UART> {
const IS_SET: bool;
}
pub trait Rts<UART> {
const IS_SET: bool;
}
impl<UART> Tx<UART> for () {
const IS_SET: bool = false;
}
impl<UART> Rx<UART> for () {
const IS_SET: bool = false;
}
impl<UART> Cts<UART> for () {
const IS_SET: bool = false;
}
impl<UART> Rts<UART> for () {
const IS_SET: bool = false;
}
macro_rules! impl_valid_uart {
($($uart:ident: {
tx: [$($tx:ident),*],
rx: [$($rx:ident),*],
cts: [$($cts:ident),*],
rts: [$($rts:ident),*],
}),*) => {
$(
$(
impl Tx<$uart> for crate::gpio::Pin<crate::gpio::bank0::$tx, crate::gpio::FunctionUart> {
const IS_SET: bool = true;
}
)*
$(
impl Rx<$uart> for crate::gpio::Pin<crate::gpio::bank0::$rx, crate::gpio::FunctionUart> {
const IS_SET: bool = true;
}
)*
$(
impl Cts<$uart> for crate::gpio::Pin<crate::gpio::bank0::$cts, crate::gpio::FunctionUart> {
const IS_SET: bool = true;
}
)*
$(
impl Rts<$uart> for crate::gpio::Pin<crate::gpio::bank0::$rts, crate::gpio::FunctionUart> {
const IS_SET: 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],
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment