From 5d23ebc177c4b34ea5bee14a6e61ebc2b185efa6 Mon Sep 17 00:00:00 2001 From: Marwan SMOUNI Date: Fri, 11 Feb 2022 16:12:26 +0100 Subject: [PATCH] allow to configure: +UsartInversion +WordLength +ParityControl --- examples/serial_delay.rs | 3 ++ examples/serial_dma.rs | 3 ++ examples/serial_echo.rs | 3 ++ src/serial.rs | 82 ++++++++++++++++++++++++++++++++++++++-- 4 files changed, 87 insertions(+), 4 deletions(-) diff --git a/examples/serial_delay.rs b/examples/serial_delay.rs index 0c1ff94..a74ee06 100644 --- a/examples/serial_delay.rs +++ b/examples/serial_delay.rs @@ -43,6 +43,9 @@ fn main() -> ! { baud_rate: 115_200.Bps(), oversampling: serial::Oversampling::By16, character_match: None, + active_level_inversion: serial::UsartInversion::Standard, + word_length: serial::WordLength::DataBits8, + parity_control: None, }, ); let (mut tx, _) = serial.split(); diff --git a/examples/serial_dma.rs b/examples/serial_dma.rs index cc8b025..6dbdb9d 100644 --- a/examples/serial_dma.rs +++ b/examples/serial_dma.rs @@ -50,6 +50,9 @@ fn main() -> ! { baud_rate: 115_200.Bps(), oversampling: serial::Oversampling::By16, character_match: None, + active_level_inversion: serial::UsartInversion::Standard, + word_length: serial::WordLength::DataBits8, + parity_control: None, }, ); let (mut tx, mut rx) = serial.split(); diff --git a/examples/serial_echo.rs b/examples/serial_echo.rs index ddae8fa..b13ee69 100644 --- a/examples/serial_echo.rs +++ b/examples/serial_echo.rs @@ -39,6 +39,9 @@ fn main() -> ! { baud_rate: 115_200.Bps(), oversampling: serial::Oversampling::By16, character_match: None, + active_level_inversion: serial::UsartInversion::Standard, + word_length: serial::WordLength::DataBits8, + parity_control: None, }, ); diff --git a/src/serial.rs b/src/serial.rs index c86013f..73536d6 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -184,10 +184,62 @@ where let ch = config.character_match.unwrap_or(0); usart.cr2.write(|w| w.add().bits(ch)); - // Enable transmission and receiving - usart - .cr1 - .modify(|_, w| w.te().enabled().re().enabled().ue().enabled()); + // TXINV | RXINV: TX/RX pin active level inversion + match config.active_level_inversion { + UsartInversion::Standard => { + usart + .cr2 + .modify(|_r, w| w.rxinv().clear_bit().txinv().clear_bit()); + } + UsartInversion::Inverted => { + usart + .cr2 + .modify(|_r, w| w.rxinv().set_bit().txinv().set_bit()); + } + } + + usart.cr1.modify(|_r, w| { + match config.word_length { + // M[1:0] + WordLength::DataBits7 => { + // 10: 1 Start bit, 7 data bits + w.m0().clear_bit().m1().set_bit(); + } + WordLength::DataBits8 => { + // 00: 1 Start bit, 9 data bits + w.m0().clear_bit().m1().clear_bit(); + } + WordLength::DataBits9 => { + // 01: 1 Start bit, 9 data bits + w.m0().set_bit().m1().clear_bit(); + } + } + + if let Some(parity) = config.parity_control { + // Parity control enable + w.pce().set_bit(); + match parity { + ParityControl::Even => { + // Parity selection: Even + w.ps().clear_bit(); + } + ParityControl::Odd => { + // Parity selection: Odd + w.ps().set_bit(); + } + } + } + + // USART enable + w.ue() + .set_bit() + // Enable receiving + .re() + .set_bit() + // Enable transmission + .te() + .set_bit() + }); // Enable DMA usart.cr3.write(|w| w.dmat().enabled().dmar().enabled()); @@ -434,9 +486,28 @@ where pub struct Config { pub baud_rate: BytesPerSecond, pub oversampling: Oversampling, + pub active_level_inversion: UsartInversion, + pub word_length: WordLength, + pub parity_control: Option, pub character_match: Option, } +pub enum UsartInversion { + Standard, + Inverted, +} + +pub enum WordLength { + DataBits7, + DataBits8, + DataBits9, +} + +pub enum ParityControl { + Even, + Odd, +} + pub enum Oversampling { By8, By16, @@ -447,6 +518,9 @@ impl Default for Config { Self { baud_rate: 115_200.Bps(), oversampling: Oversampling::By16, + active_level_inversion: UsartInversion::Standard, + word_length: WordLength::DataBits8, + parity_control: None, character_match: None, } }