embassy/embassy-stm32/src/usart/mod.rs

260 lines
6.9 KiB
Rust
Raw Normal View History

#![macro_use]
2021-07-01 17:37:01 +02:00
#[cfg_attr(usart_v1, path = "v1.rs")]
#[cfg_attr(usart_v2, path = "v2.rs")]
mod _version;
2021-07-15 05:42:06 +02:00
use crate::{dma, peripherals};
pub use _version::*;
2021-04-14 15:34:58 +02:00
2021-05-15 03:52:58 +02:00
use crate::gpio::Pin;
2021-06-29 16:59:22 +02:00
use crate::rcc::RccPeripheral;
use embassy::interrupt::Interrupt;
2021-04-14 15:34:58 +02:00
2021-06-30 20:37:35 +02:00
#[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,
}
}
}
2021-05-15 03:52:58 +02:00
/// Serial error
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
2021-07-04 23:34:37 +02:00
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2021-04-14 15:34:58 +02:00
#[non_exhaustive]
2021-05-15 03:52:58 +02:00
pub enum Error {
/// Framing error
Framing,
/// Noise error
Noise,
/// RX buffer overrun
Overrun,
/// Parity check error
Parity,
2021-04-14 15:34:58 +02:00
}
2021-04-25 22:35:51 +02:00
pub(crate) mod sealed {
use super::*;
2021-06-29 19:00:52 +02:00
2021-04-25 22:35:51 +02:00
pub trait Instance {
2021-07-04 23:34:37 +02:00
fn regs(&self) -> crate::pac::usart::Usart;
2021-04-25 22:35:51 +02:00
}
pub trait RxPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
2021-04-25 22:35:51 +02:00
}
pub trait TxPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
2021-04-25 22:35:51 +02:00
}
pub trait CtsPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
2021-04-25 22:35:51 +02:00
}
pub trait RtsPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
2021-04-25 22:35:51 +02:00
}
pub trait CkPin<T: Instance>: Pin {
fn af_num(&self) -> u8;
2021-04-25 22:35:51 +02:00
}
2021-06-25 20:00:11 +02:00
2021-07-15 05:42:06 +02:00
pub trait RxDma<T: Instance> {
fn request(&self) -> dma::Request;
}
2021-06-25 20:00:11 +02:00
2021-07-15 05:42:06 +02:00
pub trait TxDma<T: Instance> {
fn request(&self) -> dma::Request;
}
2021-04-25 22:35:51 +02:00
}
2021-06-25 20:00:11 +02:00
pub trait Instance: sealed::Instance + RccPeripheral {
type Interrupt: Interrupt;
}
2021-04-25 22:35:51 +02:00
pub trait RxPin<T: Instance>: sealed::RxPin<T> {}
pub trait TxPin<T: Instance>: sealed::TxPin<T> {}
pub trait CtsPin<T: Instance>: sealed::CtsPin<T> {}
pub trait RtsPin<T: Instance>: sealed::RtsPin<T> {}
pub trait CkPin<T: Instance>: sealed::CkPin<T> {}
2021-07-15 05:42:06 +02:00
pub trait RxDma<T: Instance>: sealed::RxDma<T> + dma::Channel {}
pub trait TxDma<T: Instance>: sealed::TxDma<T> + dma::Channel {}
2021-06-25 20:00:11 +02:00
crate::pac::interrupts!(
($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => {
2021-06-03 17:27:17 +02:00
impl sealed::Instance for peripherals::$inst {
fn regs(&self) -> crate::pac::usart::Usart {
crate::pac::$inst
2021-04-14 15:34:58 +02:00
}
}
2021-06-03 17:27:17 +02:00
impl Instance for peripherals::$inst {
type Interrupt = crate::interrupt::$irq;
}
2021-04-14 15:34:58 +02:00
};
2021-06-03 17:27:17 +02:00
);
2021-04-14 15:34:58 +02:00
2021-06-03 17:27:17 +02:00
macro_rules! impl_pin {
($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
fn af_num(&self) -> u8 {
$af
}
2021-04-25 22:35:51 +02:00
}
2021-06-03 17:27:17 +02:00
impl $signal<peripherals::$inst> for peripherals::$pin {}
2021-04-25 22:35:51 +02:00
};
}
2021-06-03 17:27:17 +02:00
#[cfg(not(rcc_f1))]
2021-06-03 17:27:17 +02:00
crate::pac::peripheral_pins!(
// USART
2021-06-03 17:27:17 +02:00
($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);
};
2021-06-03 17:27:17 +02:00
);
2021-07-15 05:42:06 +02:00
#[cfg(rcc_f1)]
crate::pac::peripheral_pins!(
// USART
($inst:ident, usart, USART, $pin:ident, TX) => {
impl_pin!($inst, $pin, TxPin, 0);
};
($inst:ident, usart, USART, $pin:ident, RX) => {
impl_pin!($inst, $pin, RxPin, 0);
};
($inst:ident, usart, USART, $pin:ident, CTS) => {
impl_pin!($inst, $pin, CtsPin, 0);
};
($inst:ident, usart, USART, $pin:ident, RTS) => {
impl_pin!($inst, $pin, RtsPin, 0);
};
($inst:ident, usart, USART, $pin:ident, CK) => {
impl_pin!($inst, $pin, CkPin, 0);
};
// UART
($inst:ident, uart, UART, $pin:ident, TX) => {
impl_pin!($inst, $pin, TxPin, 0);
};
($inst:ident, uart, UART, $pin:ident, RX) => {
impl_pin!($inst, $pin, RxPin, 0);
};
($inst:ident, uart, UART, $pin:ident, CTS) => {
impl_pin!($inst, $pin, CtsPin, 0);
};
($inst:ident, uart, UART, $pin:ident, RTS) => {
impl_pin!($inst, $pin, RtsPin, 0);
};
($inst:ident, uart, UART, $pin:ident, CK) => {
impl_pin!($inst, $pin, CkPin, 0);
};
);
2021-11-02 20:28:14 +01:00
#[allow(unused)]
2021-07-15 05:42:06 +02:00
macro_rules! impl_dma {
($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
impl<T> sealed::$signal<peripherals::$inst> for T
where
T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
{
2021-07-15 05:42:06 +02:00
fn request(&self) -> dma::Request {
$request
}
}
impl<T> $signal<peripherals::$inst> for T where
T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>
{
}
2021-07-15 05:42:06 +02:00
};
($inst:ident, {channel: $channel:ident}, $signal:ident, $request:expr) => {
2021-07-15 05:42:06 +02:00
impl sealed::$signal<peripherals::$inst> for peripherals::$channel {
fn request(&self) -> dma::Request {
$request
}
}
impl $signal<peripherals::$inst> for peripherals::$channel {}
};
}
crate::pac::peripheral_dma_channels! {
($peri:ident, usart, $kind:ident, RX, $channel:tt, $request:expr) => {
2021-07-15 05:42:06 +02:00
impl_dma!($peri, $channel, RxDma, $request);
};
($peri:ident, usart, $kind:ident, TX, $channel:tt, $request:expr) => {
2021-07-15 05:42:06 +02:00
impl_dma!($peri, $channel, TxDma, $request);
};
($peri:ident, uart, $kind:ident, RX, $channel:tt, $request:expr) => {
2021-07-15 05:42:06 +02:00
impl_dma!($peri, $channel, RxDma, $request);
};
($peri:ident, uart, $kind:ident, TX, $channel:tt, $request:expr) => {
2021-07-15 05:42:06 +02:00
impl_dma!($peri, $channel, TxDma, $request);
};
}