stm32f1_hal/common/uart/
mod.rs

1mod uart_dma;
2mod uart_it;
3mod uart_poll;
4
5pub use uart_dma::*;
6pub use uart_it::*;
7pub use uart_poll::*;
8
9use crate::common::{embedded_hal_nb as e_nb, embedded_io as e_io, fugit::MicrosDurationU32};
10use crate::os_trait::prelude::*;
11use core::fmt::Display;
12
13// ------------------------------------------------------------------------------------------------
14
15// UART idle interrupt handler
16pub struct UartIdleInterrupt<U: UartPeriph> {
17    uart: U,
18}
19
20impl<U: UartPeriph> UartIdleInterrupt<U> {
21    pub fn new(uart: U) -> Self {
22        Self { uart }
23    }
24
25    #[inline]
26    pub fn is_interrupted(&mut self) -> bool {
27        self.uart.is_interrupted(Event::Idle)
28    }
29
30    #[inline]
31    pub fn listen(&mut self) {
32        self.uart.set_interrupt(Event::Idle, true);
33    }
34
35    #[inline]
36    pub fn unlisten(&mut self) {
37        self.uart.set_interrupt(Event::Idle, false);
38    }
39}
40
41// Peripheral Trait -----------------------------------------------------------
42
43pub trait UartPeriph {
44    fn write(&mut self, word: u16) -> nb::Result<(), Error>;
45    /// # Returns
46    /// - `None`: need to wait
47    /// - `Some(true)`: Wrote a data
48    /// - `Some(false)`: No new data
49    fn write_with(&mut self, f: impl FnOnce() -> Option<u16>) -> Option<bool>;
50    /// Transfer is empty and completed
51    fn is_tx_complete(&self) -> bool;
52
53    fn read(&mut self) -> nb::Result<u16, Error>;
54
55    fn set_interrupt(&mut self, event: Event, enable: bool);
56    fn is_interrupt_enable(&mut self, event: Event) -> bool;
57    /// Read and clean the flag
58    fn is_interrupted(&mut self, event: Event) -> bool;
59
60    fn clear_err_flag(&self);
61}
62
63pub trait UartPeriphWithDma: UartPeriph {
64    fn get_tx_data_reg_addr(&self) -> usize;
65    fn get_rx_data_reg_addr(&self) -> usize;
66    fn enable_dma_tx(&mut self, enable: bool);
67    fn enable_dma_rx(&mut self, enable: bool);
68}
69
70#[derive(Clone, Copy, Debug, PartialEq, Eq)]
71pub enum Event {
72    /// New data can be sent
73    TxEmpty,
74    /// New data has been received
75    RxNotEmpty,
76    /// Idle line state detected
77    Idle,
78}
79
80/// UART error
81#[derive(Debug)]
82#[non_exhaustive]
83pub enum Error {
84    /// The peripheral receive buffer was overrun.
85    Overrun,
86    /// Received data does not conform to the peripheral configuration.
87    /// Can be caused by a misconfigured device on either end of the serial line.
88    FrameFormat,
89    /// Parity check failed.
90    Parity,
91    /// UART line is too noisy to read valid data.
92    Noise,
93    /// UART is busy and cannot accept new data.
94    Busy,
95    /// A different error occurred. The original error may contain more information.
96    Other,
97}
98
99impl Display for Error {
100    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
101        match self {
102            Self::Overrun => write!(f, "UART overrun error"),
103            Self::FrameFormat => write!(f, "UART frame format error"),
104            Self::Parity => write!(f, "UART parity error"),
105            Self::Noise => write!(f, "UART noise error"),
106            Self::Busy => write!(f, "UART busy"),
107            Self::Other => write!(f, "UART other error"),
108        }
109    }
110}
111
112impl core::error::Error for Error {}
113
114impl embedded_io::Error for Error {
115    #[inline]
116    fn kind(&self) -> e_io::ErrorKind {
117        match self {
118            Self::Overrun => e_io::ErrorKind::InvalidData,
119            Self::FrameFormat => e_io::ErrorKind::InvalidData,
120            Self::Parity => e_io::ErrorKind::InvalidData,
121            Self::Noise => e_io::ErrorKind::InvalidData,
122            Self::Busy => e_io::ErrorKind::WriteZero,
123            Self::Other => e_io::ErrorKind::Other,
124        }
125    }
126}
127
128impl e_nb::serial::Error for Error {
129    #[inline]
130    fn kind(&self) -> e_nb::serial::ErrorKind {
131        match self {
132            Self::Overrun => e_nb::serial::ErrorKind::Overrun,
133            Self::FrameFormat => e_nb::serial::ErrorKind::FrameFormat,
134            Self::Parity => e_nb::serial::ErrorKind::Parity,
135            Self::Noise => e_nb::serial::ErrorKind::Noise,
136            Self::Busy => e_nb::serial::ErrorKind::Other,
137            Self::Other => e_nb::serial::ErrorKind::Other,
138        }
139    }
140}
141
142pub enum WordLength {
143    /// When parity is enabled, a word has 7 data bits + 1 parity bit,
144    /// otherwise 8 data bits.
145    Bits8,
146    /// When parity is enabled, a word has 8 data bits + 1 parity bit,
147    /// otherwise 9 data bits.
148    Bits9,
149}
150
151pub enum Parity {
152    ParityNone,
153    ParityEven,
154    ParityOdd,
155}
156
157pub enum StopBits {
158    /// 1 stop bit
159    STOP1,
160    /// 0.5 stop bits
161    STOP0P5,
162    /// 2 stop bits
163    STOP2,
164    /// 1.5 stop bits
165    STOP1P5,
166}
167
168pub struct Config {
169    pub baudrate: u32,
170    pub word_length: WordLength,
171    pub parity: Parity,
172    pub stop_bits: StopBits,
173}
174
175impl Default for Config {
176    fn default() -> Config {
177        Config {
178            baudrate: 115_200,
179            word_length: WordLength::Bits8,
180            parity: Parity::ParityNone,
181            stop_bits: StopBits::STOP1,
182        }
183    }
184}
185
186impl Config {
187    pub fn baudrate(mut self, baudrate: u32) -> Self {
188        self.baudrate = baudrate;
189        self
190    }
191
192    pub fn word_length(mut self, wordlength: WordLength) -> Self {
193        self.word_length = wordlength;
194        self
195    }
196
197    pub fn word_length_8bits(mut self) -> Self {
198        self.word_length = WordLength::Bits8;
199        self
200    }
201
202    pub fn word_length_9bits(mut self) -> Self {
203        self.word_length = WordLength::Bits9;
204        self
205    }
206
207    pub fn parity(mut self, parity: Parity) -> Self {
208        self.parity = parity;
209        self
210    }
211
212    pub fn parity_none(mut self) -> Self {
213        self.parity = Parity::ParityNone;
214        self
215    }
216
217    pub fn parity_even(mut self) -> Self {
218        self.parity = Parity::ParityEven;
219        self
220    }
221
222    pub fn parity_odd(mut self) -> Self {
223        self.parity = Parity::ParityOdd;
224        self
225    }
226
227    pub fn stop_bits(mut self, stop_bits: StopBits) -> Self {
228        self.stop_bits = stop_bits;
229        self
230    }
231}
232
233#[inline]
234const fn calculate_timeout(baudrate: u32, data_len: usize) -> MicrosDurationU32 {
235    let bytes_per_sec = baudrate / 12;
236    MicrosDurationU32::micros((data_len * 1_000_000) as u32 / bytes_per_sec)
237}