#![macro_use] #[cfg_attr(usart_v1, path = "v1.rs")] #[cfg_attr(usart_v2, path = "v2.rs")] mod _version; use crate::{dma, peripherals}; pub use _version::*; use crate::gpio::Pin; use crate::rcc::RccPeripheral; #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum DataBits { DataBits8, DataBits9, } #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum Parity { ParityNone, ParityEven, ParityOdd, } #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum StopBits { #[doc = "1 stop bit"] STOP1, #[doc = "0.5 stop bits"] STOP0P5, #[doc = "2 stop bits"] STOP2, #[doc = "1.5 stop bits"] STOP1P5, } #[non_exhaustive] #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct Config { pub baudrate: u32, pub data_bits: DataBits, pub stop_bits: StopBits, pub parity: Parity, } impl Default for Config { fn default() -> Self { Self { baudrate: 115200, data_bits: DataBits::DataBits8, stop_bits: StopBits::STOP1, parity: Parity::ParityNone, } } } /// Serial error #[derive(Debug, Eq, PartialEq, Copy, Clone)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[non_exhaustive] pub enum Error { /// Framing error Framing, /// Noise error Noise, /// RX buffer overrun Overrun, /// Parity check error Parity, } pub(crate) mod sealed { use super::*; pub trait Instance { fn regs(&self) -> crate::pac::usart::Usart; } pub trait RxPin: Pin { fn af_num(&self) -> u8; } pub trait TxPin: Pin { fn af_num(&self) -> u8; } pub trait CtsPin: Pin { fn af_num(&self) -> u8; } pub trait RtsPin: Pin { fn af_num(&self) -> u8; } pub trait CkPin: Pin { fn af_num(&self) -> u8; } pub trait RxDma { fn request(&self) -> dma::Request; } pub trait TxDma { fn request(&self) -> dma::Request; } } pub trait Instance: sealed::Instance + RccPeripheral {} 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 {} pub trait RxDma: sealed::RxDma + dma::Channel {} pub trait TxDma: sealed::TxDma + dma::Channel {} crate::pac::peripherals!( (usart, $inst:ident) => { impl sealed::Instance for peripherals::$inst { fn regs(&self) -> crate::pac::usart::Usart { crate::pac::$inst } } impl Instance for peripherals::$inst {} }; ); macro_rules! impl_pin { ($inst:ident, $pin:ident, $signal:ident, $af:expr) => { impl sealed::$signal for peripherals::$pin { fn af_num(&self) -> u8 { $af } } impl $signal for peripherals::$pin {} }; } crate::pac::peripheral_pins!( // USART ($inst:ident, usart, USART, $pin:ident, TX, $af:expr) => { impl_pin!($inst, $pin, TxPin, $af); }; ($inst:ident, usart, USART, $pin:ident, RX, $af:expr) => { impl_pin!($inst, $pin, RxPin, $af); }; ($inst:ident, usart, USART, $pin:ident, CTS, $af:expr) => { impl_pin!($inst, $pin, CtsPin, $af); }; ($inst:ident, usart, USART, $pin:ident, RTS, $af:expr) => { impl_pin!($inst, $pin, RtsPin, $af); }; ($inst:ident, usart, USART, $pin:ident, CK, $af:expr) => { impl_pin!($inst, $pin, CkPin, $af); }; // UART ($inst:ident, uart, UART, $pin:ident, TX, $af:expr) => { impl_pin!($inst, $pin, TxPin, $af); }; ($inst:ident, uart, UART, $pin:ident, RX, $af:expr) => { impl_pin!($inst, $pin, RxPin, $af); }; ($inst:ident, uart, UART, $pin:ident, CTS, $af:expr) => { impl_pin!($inst, $pin, CtsPin, $af); }; ($inst:ident, uart, UART, $pin:ident, RTS, $af:expr) => { impl_pin!($inst, $pin, RtsPin, $af); }; ($inst:ident, uart, UART, $pin:ident, CK, $af:expr) => { impl_pin!($inst, $pin, CkPin, $af); }; ); macro_rules! impl_dma { ($inst:ident, ALL, $signal:ident, $request:expr) => { impl sealed::$signal for T { fn request(&self) -> dma::Request { $request } } impl $signal for T {} }; ($inst:ident, $channel:ident, $signal:ident, $request:expr) => { impl sealed::$signal for peripherals::$channel { fn request(&self) -> dma::Request { $request } } impl $signal for peripherals::$channel {} }; } crate::pac::peripheral_dma_channels! { ($peri:ident, usart, $kind:ident, RX, $channel:ident, $dma_peri:ident, $channel_num:expr, $request:expr) => { impl_dma!($peri, $channel, RxDma, $request); }; ($peri:ident, usart, $kind:ident, TX, $channel:ident, $dma_peri:ident, $channel_num:expr, $request:expr) => { impl_dma!($peri, $channel, TxDma, $request); }; ($peri:ident, uart, $kind:ident, RX, $channel:ident, $dma_peri:ident, $channel_num:expr, $request:expr) => { impl_dma!($peri, $channel, RxDma, $request); }; ($peri:ident, uart, $kind:ident, TX, $channel:ident, $dma_peri:ident, $channel_num:expr, $request:expr) => { impl_dma!($peri, $channel, TxDma, $request); }; } crate::pac::dma_requests! { (usart, $peri:ident, RX, $request:expr) => { impl_dma!($peri, ALL, RxDma, $request); }; (usart, $peri:ident, TX, $request:expr) => { impl_dma!($peri, ALL, TxDma, $request); }; (uart, $peri:ident, RX, $request:expr) => { impl_dma!($peri, ALL, RxDma, $request); }; (uart, $peri:ident, TX, $request:expr) => { impl_dma!($peri, ALL, TxDma, $request); }; }