stm32f1_hal/common/uart/
mod.rs1mod 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
13pub 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
41pub trait UartPeriph {
44 fn write(&mut self, word: u16) -> nb::Result<(), Error>;
45 fn write_with(&mut self, f: impl FnOnce() -> Option<u16>) -> Option<bool>;
50 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 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 TxEmpty,
74 RxNotEmpty,
76 Idle,
78}
79
80#[derive(Debug)]
82#[non_exhaustive]
83pub enum Error {
84 Overrun,
86 FrameFormat,
89 Parity,
91 Noise,
93 Busy,
95 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 Bits8,
146 Bits9,
149}
150
151pub enum Parity {
152 ParityNone,
153 ParityEven,
154 ParityOdd,
155}
156
157pub enum StopBits {
158 STOP1,
160 STOP0P5,
162 STOP2,
164 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}