use core::marker::PhantomData; use embassy::util::Unborrow; use embassy_extras::unborrow; use crate::gpio::{NoPin, Pin}; use crate::pac::usart_v1::{regs, vals, Usart}; use crate::peripherals; #[non_exhaustive] pub struct Config { pub baudrate: u32, pub data_bits: u8, pub stop_bits: u8, } impl Default for Config { fn default() -> Self { Self { baudrate: 115200, data_bits: 8, stop_bits: 1, } } } pub struct Uart<'d, T: Instance> { inner: T, phantom: PhantomData<&'d mut T>, } impl<'d, T: Instance> Uart<'d, T> { pub fn new( inner: impl Unborrow, rx: impl Unborrow>, tx: impl Unborrow>, cts: impl Unborrow>, rts: impl Unborrow>, config: Config, ) -> Self { unborrow!(inner, rx, tx, cts, rts); Self { inner, phantom: PhantomData, } } } pub(crate) mod sealed { use crate::gpio::{OptionalPin, Pin}; use super::*; pub trait Instance { fn regs(&self) -> Usart; } pub trait RxPin: OptionalPin { const AF_NUM: u8; } pub trait TxPin: OptionalPin { const AF_NUM: u8; } pub trait CtsPin: OptionalPin { const AF_NUM: u8; } pub trait RtsPin: OptionalPin { const AF_NUM: u8; } pub trait CkPin: OptionalPin { const AF_NUM: u8; } } pub trait Instance: sealed::Instance {} pub trait RxPin: sealed::RxPin {} pub trait TxPin: sealed::TxPin {} pub trait CtsPin: sealed::CtsPin {} pub trait RtsPin: sealed::RtsPin {} pub trait CkPin: sealed::CkPin {} impl sealed::RxPin for NoPin { const AF_NUM: u8 = 0; } impl RxPin for NoPin {} impl sealed::TxPin for NoPin { const AF_NUM: u8 = 0; } impl TxPin for NoPin {} impl sealed::CtsPin for NoPin { const AF_NUM: u8 = 0; } impl CtsPin for NoPin {} impl sealed::RtsPin for NoPin { const AF_NUM: u8 = 0; } impl RtsPin for NoPin {} impl sealed::CkPin for NoPin { const AF_NUM: u8 = 0; } impl CkPin for NoPin {} macro_rules! impl_usart { ($inst:ident, $addr:expr) => { impl crate::usart::sealed::Instance for peripherals::$inst { fn regs(&self) -> crate::pac::usart_v1::Usart { crate::pac::usart_v1::Usart($addr as _) } } impl crate::usart::Instance for peripherals::$inst {} }; } macro_rules! impl_usart_pin { ($inst:ident, $func:ident, $pin:ident, $num:expr) => { impl crate::usart::sealed::$func for peripherals::$pin { const AF_NUM: u8 = $num; } impl crate::usart::$func for peripherals::$pin {} }; }