use core::fmt;
use core::marker::PhantomData;
use core::ops::DerefMut;
use core::ptr;
use core::sync::atomic::{self, Ordering};
use embedded_dma::StaticWriteBuffer;
use stable_deref_trait::StableDeref;
use crate::hal::serial::{self, Write};
use crate::dma::{
dma1, CircBuffer, DMAFrame, FrameReader, FrameSender, Receive, RxDma, TransferPayload,
Transmit, TxDma,
};
use crate::dmamux::{DmaInput, DmaMux};
use crate::gpio::{self, Alternate, OpenDrain, PushPull};
use crate::pac;
use crate::rcc::{Clocks, Enable, RccBus, Reset};
use crate::time::{Bps, U32Ext};
#[cfg(any(
//feature = "stm32l451", // missing PAC support
// feature = "stm32l452", // missing PAC support
// feature = "stm32l462", // missing PAC support
// feature = "stm32l471", // missing PAC support
feature = "stm32l475",
feature = "stm32l476",
feature = "stm32l485",
feature = "stm32l486",
feature = "stm32l496",
feature = "stm32l4a6",
// feature = "stm32l4p5",
// feature = "stm32l4q5",
// feature = "stm32l4r5",
// feature = "stm32l4s5",
// feature = "stm32l4r7",
// feature = "stm32l4s7",
feature = "stm32l4r9",
feature = "stm32l4s9",
))]
use crate::dma::dma2;
pub enum Event {
Rxne,
Txe,
Idle,
CharacterMatch,
ReceiverTimeout,
}
#[non_exhaustive]
#[derive(Debug)]
pub enum Error {
Framing,
Noise,
Overrun,
Parity,
}
pub enum Parity {
ParityNone,
ParityEven,
ParityOdd,
}
pub enum StopBits {
STOP1,
STOP0P5,
STOP2,
STOP1P5,
}
pub enum Oversampling {
Over8,
Over16,
}
pub struct Config {
baudrate: Bps,
parity: Parity,
stopbits: StopBits,
oversampling: Oversampling,
character_match: Option<u8>,
receiver_timeout: Option<u32>,
disable_overrun: bool,
onebit_sampling: bool,
}
impl Config {
pub fn baudrate(mut self, baudrate: Bps) -> Self {
self.baudrate = baudrate;
self
}
pub fn parity_none(mut self) -> Self {
self.parity = Parity::ParityNone;
self
}
pub fn parity_even(mut self) -> Self {
self.parity = Parity::ParityEven;
self
}
pub fn parity_odd(mut self) -> Self {
self.parity = Parity::ParityOdd;
self
}
pub fn stopbits(mut self, stopbits: StopBits) -> Self {
self.stopbits = stopbits;
self
}
pub fn oversampling(mut self, oversampling: Oversampling) -> Self {
self.oversampling = oversampling;
self
}
pub fn character_match(mut self, character_match: u8) -> Self {
self.character_match = Some(character_match);
self
}
pub fn receiver_timeout(mut self, receiver_timeout: u32) -> Self {
assert!(receiver_timeout < 1 << 24);
self.receiver_timeout = Some(receiver_timeout);
self
}
pub fn with_overrun_disabled(mut self) -> Self {
self.disable_overrun = true;
self
}
pub fn with_onebit_sampling(mut self) -> Self {
self.onebit_sampling = true;
self
}
}
impl Default for Config {
fn default() -> Config {
let baudrate = 115_200_u32.bps();
Config {
baudrate,
parity: Parity::ParityNone,
stopbits: StopBits::STOP1,
oversampling: Oversampling::Over16,
character_match: None,
receiver_timeout: None,
disable_overrun: false,
onebit_sampling: false,
}
}
}
impl From<Bps> for Config {
fn from(baudrate: Bps) -> Config {
Config {
baudrate,
..Default::default()
}
}
}
pub struct Serial<USART, PINS> {
usart: USART,
pins: PINS,
}
pub struct Rx<USART> {
_usart: PhantomData<USART>,
}
pub struct Tx<USART> {
_usart: PhantomData<USART>,
}
macro_rules! hal {
($(
$(#[$meta:meta])*
$USARTX:ident: (
$usartX:ident,
$pclkX:ident,
tx: ($txdma:ident, $dmatxch:path, $dmatxsel:path),
rx: ($rxdma:ident, $dmarxch:path, $dmarxsel:path)
),
)+) => {
$(
impl<PINS> Serial<pac::$USARTX, PINS> {
/// Configures the serial interface and creates the interface
/// struct.
///
/// `Config` is a config struct that configures baud rate, stop bits and parity.
///
/// `Clocks` passes information about the current frequencies of
/// the clocks. The existence of the struct ensures that the
/// clock settings are fixed.
///
/// The `serial` struct takes ownership over the `USARTX` device
/// registers and the specified `PINS`
///
/// `MAPR` and `APBX` are register handles which are passed for
/// configuration. (`MAPR` is used to map the USART to the
/// corresponding pins. `APBX` is used to reset the USART.)
pub fn $usartX(
usart: pac::$USARTX,
pins: PINS,
config: impl Into<Config>,
clocks: Clocks,
apb: &mut <pac::$USARTX as RccBus>::Bus,
) -> Self
where
PINS: Pins<pac::$USARTX>,
{
let config = config.into();
<pac::$USARTX>::enable(apb);
<pac::$USARTX>::reset(apb);
usart.cr1.reset();
usart.cr2.reset();
usart.cr3.reset();
match config.oversampling {
Oversampling::Over8 => {
let uartdiv = 2 * clocks.$pclkX().raw() / config.baudrate.0;
assert!(uartdiv >= 16, "impossible baud rate");
let lower = (uartdiv & 0xf) >> 1;
let brr = (uartdiv & !0xf) | lower;
usart.cr1.modify(|_, w| w.over8().set_bit());
usart.brr.write(|w| unsafe { w.bits(brr) });
}
Oversampling::Over16 => {
let brr = clocks.$pclkX().raw() / config.baudrate.0;
assert!(brr >= 16, "impossible baud rate");
usart.brr.write(|w| unsafe { w.bits(brr) });
}
}
if let Some(val) = config.receiver_timeout {
usart.rtor.modify(|_, w| w.rto().bits(val));
}
usart.cr3.modify(|_, w| w.dmat().set_bit().dmar().set_bit());
if PINS::FLOWCTL {
usart.cr3.modify(|_, w| w.rtse().set_bit().ctse().set_bit());
} else if PINS::DEM {
usart.cr3.modify(|_, w| w.dem().set_bit());
usart.cr1.modify(|_, w| w.deat().bits(0b1111).dedt().bits(0b1111));
} else {
usart.cr3.modify(|_, w| w.rtse().clear_bit().ctse().clear_bit());
}
usart.cr3.modify(|_, w| {
if config.onebit_sampling {
w.onebit().set_bit();
}
if config.disable_overrun {
w.ovrdis().set_bit();
}
if PINS::HALF_DUPLEX {
w.hdsel().set_bit();
}
w
});
let (word_length, parity_control_enable, parity) = match config.parity {
Parity::ParityNone => (false, false, false),
Parity::ParityEven => (true, true, false),
Parity::ParityOdd => (true, true, true),
};
usart.cr1.modify(|_r, w| {
w
.m0().bit(word_length)
.ps().bit(parity)
.pce().bit(parity_control_enable)
});
let stop_bits = match config.stopbits {
StopBits::STOP1 => 0b00,
StopBits::STOP0P5 => 0b01,
StopBits::STOP2 => 0b10,
StopBits::STOP1P5 => 0b11,
};
usart.cr2.modify(|_r, w| {
w.stop().bits(stop_bits);
if let Some(c) = config.character_match {
w.add().bits(c);
}
if config.receiver_timeout.is_some() {
w.rtoen().set_bit();
}
w
});
usart
.cr1
.modify(|_, w| w.ue().set_bit().re().set_bit().te().set_bit());
Serial { usart, pins }
}
pub fn listen(&mut self, event: Event) {
match event {
Event::Rxne => {
self.usart.cr1.modify(|_, w| w.rxneie().set_bit())
},
Event::Txe => {
self.usart.cr1.modify(|_, w| w.txeie().set_bit())
},
Event::Idle => {
self.usart.cr1.modify(|_, w| w.idleie().set_bit())
},
Event::CharacterMatch => {
self.usart.cr1.modify(|_, w| w.cmie().set_bit())
},
Event::ReceiverTimeout => {
self.usart.cr1.modify(|_, w| w.rtoie().set_bit())
},
}
}
pub fn check_for_error() -> Result<(), Error> {
let mut rx: Rx<pac::$USARTX> = Rx {
_usart: PhantomData,
};
rx.check_for_error()
}
pub fn unlisten(&mut self, event: Event) {
match event {
Event::Rxne => {
self.usart.cr1.modify(|_, w| w.rxneie().clear_bit())
},
Event::Txe => {
self.usart.cr1.modify(|_, w| w.txeie().clear_bit())
},
Event::Idle => {
self.usart.cr1.modify(|_, w| w.idleie().clear_bit())
},
Event::CharacterMatch => {
self.usart.cr1.modify(|_, w| w.cmie().clear_bit())
},
Event::ReceiverTimeout => {
self.usart.cr1.modify(|_, w| w.rtoie().clear_bit())
},
}
}
pub fn split(self) -> (Tx<pac::$USARTX>, Rx<pac::$USARTX>) {
(
Tx {
_usart: PhantomData,
},
Rx {
_usart: PhantomData,
},
)
}
pub fn release(self) -> (pac::$USARTX, PINS) {
(self.usart, self.pins)
}
}
impl<PINS> serial::Read<u8> for Serial<pac::$USARTX, PINS> {
type Error = Error;
fn read(&mut self) -> nb::Result<u8, Error> {
let mut rx: Rx<pac::$USARTX> = Rx {
_usart: PhantomData,
};
rx.read()
}
}
impl serial::Read<u8> for Rx<pac::$USARTX> {
type Error = Error;
fn read(&mut self) -> nb::Result<u8, Error> {
self.check_for_error()?;
let isr = unsafe { (*pac::$USARTX::ptr()).isr.read() };
if isr.rxne().bit_is_set() {
return Ok(unsafe {
ptr::read_volatile(&(*pac::$USARTX::ptr()).rdr as *const _ as *const _)
});
}
Err(nb::Error::WouldBlock)
}
}
impl<PINS> serial::Write<u8> for Serial<pac::$USARTX, PINS> {
type Error = Error;
fn flush(&mut self) -> nb::Result<(), Error> {
let mut tx: Tx<pac::$USARTX> = Tx {
_usart: PhantomData,
};
tx.flush()
}
fn write(&mut self, byte: u8) -> nb::Result<(), Error> {
let mut tx: Tx<pac::$USARTX> = Tx {
_usart: PhantomData,
};
tx.write(byte)
}
}
impl serial::Write<u8> for Tx<pac::$USARTX> {
type Error = Error;
fn flush(&mut self) -> nb::Result<(), Error> {
let isr = unsafe { (*pac::$USARTX::ptr()).isr.read() };
if isr.tc().bit_is_set() {
Ok(())
} else {
Err(nb::Error::WouldBlock)
}
}
fn write(&mut self, byte: u8) -> nb::Result<(), Error> {
let isr = unsafe { (*pac::$USARTX::ptr()).isr.read() };
if isr.txe().bit_is_set() {
unsafe {
ptr::write_volatile(&(*pac::$USARTX::ptr()).tdr as *const _ as *mut _, byte)
}
Ok(())
} else {
Err(nb::Error::WouldBlock)
}
}
}
impl embedded_hal::blocking::serial::write::Default<u8>
for Tx<pac::$USARTX> {}
pub type $rxdma = RxDma<Rx<pac::$USARTX>, $dmarxch>;
pub type $txdma = TxDma<Tx<pac::$USARTX>, $dmatxch>;
impl Receive for $rxdma {
type RxChannel = $dmarxch;
type TransmittedWord = u8;
}
impl Transmit for $txdma {
type TxChannel = $dmatxch;
type ReceivedWord = u8;
}
impl TransferPayload for $rxdma {
fn start(&mut self) {
self.channel.start();
}
fn stop(&mut self) {
self.channel.stop();
}
}
impl TransferPayload for $txdma {
fn start(&mut self) {
self.channel.start();
}
fn stop(&mut self) {
self.channel.stop();
}
}
impl Rx<pac::$USARTX> {
pub fn with_dma(self, channel: $dmarxch) -> $rxdma {
RxDma {
payload: self,
channel,
}
}
pub fn check_for_error(&mut self) -> Result<(), Error> {
let isr = unsafe { (*pac::$USARTX::ptr()).isr.read() };
let icr = unsafe { &(*pac::$USARTX::ptr()).icr };
if isr.pe().bit_is_set() {
icr.write(|w| w.pecf().clear());
return Err(Error::Parity);
}
if isr.fe().bit_is_set() {
icr.write(|w| w.fecf().clear());
return Err(Error::Framing);
}
if isr.nf().bit_is_set() {
icr.write(|w| w.ncf().clear());
return Err(Error::Noise);
}
if isr.ore().bit_is_set() {
icr.write(|w| w.orecf().clear());
return Err(Error::Overrun);
}
Ok(())
}
pub fn is_idle(&mut self, clear: bool) -> bool {
let isr = unsafe { &(*pac::$USARTX::ptr()).isr.read() };
let icr = unsafe { &(*pac::$USARTX::ptr()).icr };
if isr.idle().bit_is_set() {
if clear {
icr.write(|w| w.idlecf().set_bit() );
}
true
} else {
false
}
}
pub fn is_receiver_timeout(&mut self, clear: bool) -> bool {
let isr = unsafe { &(*pac::$USARTX::ptr()).isr.read() };
let icr = unsafe { &(*pac::$USARTX::ptr()).icr };
if isr.rtof().bit_is_set() {
if clear {
icr.write(|w| w.rtocf().set_bit() );
}
true
} else {
false
}
}
pub fn check_character_match(&mut self, clear: bool) -> bool {
let isr = unsafe { &(*pac::$USARTX::ptr()).isr.read() };
let icr = unsafe { &(*pac::$USARTX::ptr()).icr };
if isr.cmf().bit_is_set() {
if clear {
icr.write(|w| w.cmcf().set_bit() );
}
true
} else {
false
}
}
}
impl crate::dma::CharacterMatch for Rx<pac::$USARTX> {
fn check_character_match(&mut self, clear: bool) -> bool {
self.check_character_match(clear)
}
}
impl crate::dma::ReceiverTimeout for Rx<pac::$USARTX> {
fn check_receiver_timeout(&mut self, clear: bool) -> bool {
self.is_receiver_timeout(clear)
}
}
impl crate::dma::OperationError<(), Error> for Rx<pac::$USARTX>{
fn check_operation_error(&mut self) -> Result<(), Error> {
self.check_for_error()
}
}
impl Tx<pac::$USARTX> {
pub fn with_dma(self, channel: $dmatxch) -> $txdma {
TxDma {
payload: self,
channel,
}
}
}
impl $rxdma {
pub fn split(mut self) -> (Rx<pac::$USARTX>, $dmarxch) {
self.stop();
let RxDma {payload, channel} = self;
(
payload,
channel
)
}
}
impl $txdma {
pub fn split(mut self) -> (Tx<pac::$USARTX>, $dmatxch) {
self.stop();
let TxDma {payload, channel} = self;
(
payload,
channel,
)
}
}
impl<B> crate::dma::CircReadDma<B, u8> for $rxdma
where
&'static mut B: StaticWriteBuffer<Word = u8>,
B: 'static,
Self: core::marker::Sized,
{
fn circ_read(mut self, mut buffer: &'static mut B,
) -> CircBuffer<B, Self>
{
let (ptr, len) = unsafe { buffer.static_write_buffer() };
self.channel.set_peripheral_address(
unsafe { &(*pac::$USARTX::ptr()).rdr as *const _ as u32 },
false,
);
self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len as u16);
self.channel.set_request_line($dmarxsel).unwrap();
self.channel.ccr().modify(|_, w| {
w
.mem2mem()
.clear_bit()
.pl()
.medium()
.msize()
.bits8()
.psize()
.bits8()
.circ()
.set_bit()
.dir()
.clear_bit()
});
atomic::compiler_fence(Ordering::Release);
self.start();
CircBuffer::new(buffer, self)
}
}
impl $rxdma {
pub fn frame_reader<BUFFER, const N: usize>(
mut self,
buffer: BUFFER,
) -> FrameReader<BUFFER, Self, N>
where
BUFFER: Sized + StableDeref<Target = DMAFrame<N>> + DerefMut + 'static,
{
let usart = unsafe{ &(*pac::$USARTX::ptr()) };
let buf = &*buffer;
self.channel.set_peripheral_address(&usart.rdr as *const _ as u32, false);
self.channel.set_memory_address(unsafe { buf.buffer_address_for_dma() } as u32, true);
self.channel.set_transfer_length(buf.max_len() as u16);
self.channel.set_request_line($dmarxsel).unwrap();
self.channel.ccr().modify(|_, w| {
w
.mem2mem()
.clear_bit()
.pl()
.medium()
.msize()
.bits8()
.psize()
.bits8()
.dir()
.clear_bit()
});
atomic::compiler_fence(Ordering::Release);
self.channel.start();
FrameReader::new(buffer, self, usart.cr2.read().add().bits())
}
}
impl $txdma {
pub fn frame_sender<BUFFER, const N: usize>(
mut self,
) -> FrameSender<BUFFER, Self, N>
where
BUFFER: Sized + StableDeref<Target = DMAFrame<N>> + DerefMut + 'static,
{
let usart = unsafe{ &(*pac::$USARTX::ptr()) };
self.channel.set_peripheral_address(&usart.tdr as *const _ as u32, false);
self.channel.set_request_line($dmatxsel).unwrap();
self.channel.ccr().modify(|_, w| unsafe {
w.mem2mem()
.clear_bit()
.pl()
.bits(0b01)
.msize()
.bits(0b00)
.psize()
.bits(0b00)
.dir()
.set_bit()
});
FrameSender::new(self)
}
}
)+
}
}
hal! {
USART1: (usart1, pclk2, tx: (TxDma1, dma1::C4, DmaInput::Usart1Tx), rx: (RxDma1, dma1::C5, DmaInput::Usart1Rx)),
USART2: (usart2, pclk1, tx: (TxDma2, dma1::C7, DmaInput::Usart2Tx), rx: (RxDma2, dma1::C6, DmaInput::Usart2Rx)),
}
#[cfg(not(any(feature = "stm32l432", feature = "stm32l442")))]
hal! {
USART3: (usart3, pclk1, tx: (TxDma3, dma1::C2, DmaInput::Usart3Tx), rx: (RxDma3, dma1::C3, DmaInput::Usart3Rx)),
}
#[cfg(any(
// feature = "stm32l451", // missing PAC support
// feature = "stm32l452", // missing PAC support
// feature = "stm32l462", // missing PAC support
// feature = "stm32l471", // missing PAC support
feature = "stm32l475",
feature = "stm32l476",
feature = "stm32l485",
feature = "stm32l486",
feature = "stm32l496",
feature = "stm32l4a6",
// feature = "stm32l4p5",
// feature = "stm32l4q5",
// feature = "stm32l4r5",
// feature = "stm32l4s5",
// feature = "stm32l4r7",
// feature = "stm32l4s7",
feature = "stm32l4r9",
feature = "stm32l4s9",
))]
hal! {
UART4: (uart4, pclk1, tx: (TxDma4, dma2::C3, DmaInput::Uart4Tx), rx: (RxDma4, dma2::C5, DmaInput::Uart4Rx)),
}
#[cfg(any(
// feature = "stm32l471", // missing PAC support
feature = "stm32l475",
feature = "stm32l476",
feature = "stm32l485",
feature = "stm32l486",
feature = "stm32l496",
feature = "stm32l4a6",
// feature = "stm32l4p5",
// feature = "stm32l4q5",
// feature = "stm32l4r5",
// feature = "stm32l4s5",
// feature = "stm32l4r7",
// feature = "stm32l4s7",
feature = "stm32l4r9",
feature = "stm32l4s9",
))]
hal! {
UART5: (uart5, pclk1, tx: (TxDma5, dma2::C1, DmaInput::Uart5Tx), rx: (RxDma5, dma2::C2, DmaInput::Uart5Rx)),
}
impl<USART, PINS> fmt::Write for Serial<USART, PINS>
where
Serial<USART, PINS>: crate::hal::serial::Write<u8>,
{
fn write_str(&mut self, s: &str) -> fmt::Result {
let _ = s
.as_bytes()
.iter()
.map(|c| nb::block!(self.write(*c)))
.last();
Ok(())
}
}
impl<USART> fmt::Write for Tx<USART>
where
Tx<USART>: crate::hal::serial::Write<u8>,
{
fn write_str(&mut self, s: &str) -> fmt::Result {
let _ = s
.as_bytes()
.iter()
.map(|c| nb::block!(self.write(*c)))
.last();
Ok(())
}
}
pub trait TxPin<Instance>: private::SealedTx {}
pub trait TxHalfDuplexPin<Instance>: private::SealedTxHalfDuplex {}
pub trait RxPin<Instance>: private::SealedRx {}
pub trait RtsDePin<Instance>: private::SealedRtsDe {}
pub trait CtsPin<Instance>: private::SealedCts {}
macro_rules! impl_pin_traits {
(
$(
$instance:ident: {
$(
$af:literal: {
TX: $($tx:ident),*;
RX: $($rx:ident),*;
RTS_DE: $($rts_de:ident),*;
CTS: $($cts:ident),*;
}
)*
}
)*
) => {
$(
$(
$(
impl private::SealedTx for
gpio::$tx<Alternate<PushPull, $af>> {}
impl TxPin<pac::$instance> for
gpio::$tx<Alternate<PushPull, $af>> {}
)*
$(
impl private::SealedTxHalfDuplex for
gpio::$tx<Alternate<OpenDrain, $af>> {}
impl TxHalfDuplexPin<pac::$instance> for
gpio::$tx<Alternate<OpenDrain, $af>> {}
)*
$(
impl private::SealedRx for
gpio::$rx<Alternate<PushPull, $af>> {}
impl RxPin<pac::$instance> for
gpio::$rx<Alternate<PushPull, $af>> {}
)*
$(
impl private::SealedRtsDe for
gpio::$rts_de<Alternate<PushPull, $af>> {}
impl RtsDePin<pac::$instance> for
gpio::$rts_de<Alternate<PushPull, $af>> {}
)*
$(
impl private::SealedCts for
gpio::$cts<Alternate<PushPull, $af>> {}
impl CtsPin<pac::$instance> for
gpio::$cts<Alternate<PushPull, $af>> {}
)*
)*
)*
};
}
impl_pin_traits! {
USART1: {
7: {
TX: PA9, PB6;
RX: PA10, PB7;
RTS_DE: PA12, PB3;
CTS: PA11, PB4;
}
}
USART2: {
7: {
TX: PA2, PD5;
RX: PA3, PD6;
RTS_DE: PA1, PD4;
CTS: PA0, PD3;
}
3: {
TX: ;
RX: PA15;
RTS_DE: ;
CTS: ;
}
}
USART3: {
7: {
TX: PB10, PC4, PC10, PD8;
RX: PB11, PC5, PC11, PD9;
RTS_DE: PB1, PB14, PD2, PD12;
CTS: PA6, PB13, PD11;
}
}
}
#[cfg(any(
// feature = "stm32l451",
// feature = "stm32l452",
// feature = "stm32l462",
// feature = "stm32l471",
feature = "stm32l475",
feature = "stm32l476",
feature = "stm32l485",
feature = "stm32l486",
feature = "stm32l496",
feature = "stm32l4a6",
// feature = "stm32l4p5",
// feature = "stm32l4q5",
// feature = "stm32l4r5",
// feature = "stm32l4s5",
// feature = "stm32l4r7",
// feature = "stm32l4s7",
feature = "stm32l4r9",
feature = "stm32l4s9",
))]
impl_pin_traits! {
UART4: {
8: {
TX: PA0, PC10;
RX: PA1, PC11;
RTS_DE: PA15;
CTS: PB7;
}
}
}
#[cfg(any(
// feature = "stm32l471", ,, missing PAC support
feature = "stm32l475",
feature = "stm32l476",
feature = "stm32l485",
feature = "stm32l486",
feature = "stm32l496",
feature = "stm32l4a6",
// feature = "stm32l4p5",
// feature = "stm32l4q5",
// feature = "stm32l4r5",
// feature = "stm32l4s5",
// feature = "stm32l4r7",
// feature = "stm32l4s7",
feature = "stm32l4r9",
feature = "stm32l4s9",
))]
impl_pin_traits! {
UART5: {
8: {
TX: PC12;
RX: PD2;
RTS_DE: PB4;
CTS: PB5;
}
}
}
pub trait Pins<USART> {
const FLOWCTL: bool;
const DEM: bool;
const HALF_DUPLEX: bool;
}
impl<Instance, Tx, Rx> Pins<Instance> for (Tx, Rx)
where
Tx: TxPin<Instance>,
Rx: RxPin<Instance>,
{
const FLOWCTL: bool = false;
const DEM: bool = false;
const HALF_DUPLEX: bool = false;
}
impl<Instance, Tx> Pins<Instance> for (Tx,)
where
Tx: TxHalfDuplexPin<Instance>,
{
const FLOWCTL: bool = false;
const DEM: bool = false;
const HALF_DUPLEX: bool = true;
}
impl<Instance, Tx, Rx, Rts, Cts> Pins<Instance> for (Tx, Rx, Rts, Cts)
where
Tx: TxPin<Instance>,
Rx: RxPin<Instance>,
Rts: RtsDePin<Instance>,
Cts: CtsPin<Instance>,
{
const FLOWCTL: bool = true;
const DEM: bool = false;
const HALF_DUPLEX: bool = false;
}
impl<Instance, Tx, Rx, De> Pins<Instance> for (Tx, Rx, De)
where
Tx: TxPin<Instance>,
Rx: RxPin<Instance>,
De: RtsDePin<Instance>,
{
const FLOWCTL: bool = false;
const DEM: bool = true;
const HALF_DUPLEX: bool = false;
}
mod private {
pub trait SealedTx {}
pub trait SealedTxHalfDuplex {}
pub trait SealedRx {}
pub trait SealedRtsDe {}
pub trait SealedCts {}
}