1use core::fmt;
4use core::marker::PhantomData;
5
6use embedded_hal_nb::nb::{Error as NbError, Result as NbResult};
7use embedded_hal_nb::serial::{ErrorKind, ErrorType, Read, Write};
8use mik32_pac::usart_0::RegisterBlock;
9use mik32_pac::{Peripherals, Usart0, Usart1};
10
11use crate::constants::{DIV_AHB, DIV_APB_P};
12use crate::gpio::{Func2Mode, Pin};
13use crate::rcc::system_clock;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum WordLength {
17 DataBits7,
18 DataBits8,
19 DataBits9,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub enum DuplexMode {
24 Half,
25 Full,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum SyncMode {
30 Async,
31 Sync,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub enum Parity {
36 None,
37 Even,
38 Odd,
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub enum StopBits {
43 Stop1,
44 Stop2,
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48pub enum DmaConfig {
49 None,
50 Tx,
51 Rx,
52 TxRx,
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub struct Config {
57 pub baudrate: u32,
58 pub word_length: WordLength,
59 pub parity: Parity,
60 pub stop_bits: StopBits,
61 pub duplex_mode: DuplexMode,
62 pub sync_mode: SyncMode,
63 pub dma: DmaConfig,
64}
65
66impl Config {
67 pub const fn default() -> Self {
68 Self {
69 baudrate: 115_200,
70 word_length: WordLength::DataBits8,
71 parity: Parity::None,
72 stop_bits: StopBits::Stop1,
73 duplex_mode: DuplexMode::Full,
74 sync_mode: SyncMode::Async,
75 dma: DmaConfig::None,
76 }
77 }
78
79 pub const fn baudrate(mut self, baudrate: u32) -> Self {
80 self.baudrate = baudrate;
81 self
82 }
83
84 pub const fn word_length(mut self, word_length: WordLength) -> Self {
85 self.word_length = word_length;
86 self
87 }
88
89 pub const fn parity(mut self, parity: Parity) -> Self {
90 self.parity = parity;
91 self
92 }
93
94 pub const fn stop_bits(mut self, stop_bits: StopBits) -> Self {
95 self.stop_bits = stop_bits;
96 self
97 }
98
99 pub const fn duplex_mode(mut self, duplex_mode: DuplexMode) -> Self {
100 self.duplex_mode = duplex_mode;
101 self
102 }
103
104 pub const fn sync_mode(mut self, sync_mode: SyncMode) -> Self {
105 self.sync_mode = sync_mode;
106 self
107 }
108
109 pub const fn dma(mut self, dma: DmaConfig) -> Self {
110 self.dma = dma;
111 self
112 }
113}
114
115pub trait TxPin<UART> {}
116pub trait RxPin<UART> {}
117
118impl TxPin<Usart0> for Pin<0, 6, Func2Mode> {}
119impl RxPin<Usart0> for Pin<0, 5, Func2Mode> {}
120
121impl TxPin<Usart1> for Pin<1, 9, Func2Mode> {}
122impl RxPin<Usart1> for Pin<1, 8, Func2Mode> {}
123
124pub trait Instance {
125 fn ptr() -> *const RegisterBlock;
126 fn enable_clock();
127}
128
129impl Instance for Usart0 {
130 #[inline(always)]
131 fn ptr() -> *const RegisterBlock {
132 Usart0::ptr() as *const RegisterBlock
133 }
134
135 #[inline(always)]
136 fn enable_clock() {
137 let p = unsafe { Peripherals::steal() };
138 p.pm.clk_apb_p_set().modify(|_, w| w.uart_0().enable());
139 }
140}
141
142impl Instance for Usart1 {
143 #[inline(always)]
144 fn ptr() -> *const RegisterBlock {
145 Usart1::ptr() as *const RegisterBlock
146 }
147
148 #[inline(always)]
149 fn enable_clock() {
150 let p = unsafe { Peripherals::steal() };
151 p.pm.clk_apb_p_set().modify(|_, w| w.uart_1().enable());
152 }
153}
154
155pub struct Serial<UART, TXPIN, RXPIN>
156where
157 UART: Instance,
158 TXPIN: TxPin<UART>,
159 RXPIN: RxPin<UART>,
160{
161 uart: UART,
162 pins: (TXPIN, RXPIN),
163}
164
165pub struct Tx<UART: Instance> {
166 _uart: PhantomData<UART>,
167}
168
169pub struct Rx<UART: Instance> {
170 _uart: PhantomData<UART>,
171}
172
173impl<UART, TXPIN, RXPIN> Serial<UART, TXPIN, RXPIN>
174where
175 UART: Instance,
176 TXPIN: TxPin<UART>,
177 RXPIN: RxPin<UART>,
178{
179 pub fn new(uart: UART, pins: (TXPIN, RXPIN), config: Config) -> Self {
180 UART::enable_clock();
181
182 let serial = Self { uart, pins };
183 serial.configure(config);
184 serial
185 }
186
187 pub fn split(self) -> (Tx<UART>, Rx<UART>) {
188 let _ = self.uart;
189 let _ = self.pins;
190
191 (Tx { _uart: PhantomData }, Rx { _uart: PhantomData })
192 }
193
194 #[inline(always)]
195 fn regs(&self) -> &RegisterBlock {
196 unsafe { &*UART::ptr() }
197 }
198
199 fn configure(&self, config: Config) {
200 let regs = self.regs();
201 let baudrate_divisor = calc_baudrate_divisor(config.baudrate);
202
203 regs.control1().modify(|_, w| w.ue().disable());
204
205 regs.divider()
206 .write(|w| unsafe { w.brr().bits(baudrate_divisor) });
207
208 regs.control1().write(|w| {
209 w.idleie()
210 .disable()
211 .peie()
212 .disable()
213 .rxneie()
214 .disable()
215 .tcie()
216 .disable()
217 .txeie()
218 .disable()
219 });
220
221 regs.control2().write(|w| {
222 w.lbdie()
223 .disable()
224 .lbm()
225 .normal()
226 .swap()
227 .normal()
228 .rxinv()
229 .direct()
230 .txinv()
231 .direct()
232 .datainv()
233 .direct()
234 .msbfirst()
235 .lsb()
236 });
237
238 regs.control3().write(|w| {
239 w.eie()
240 .disable()
241 .ctsie()
242 .disable()
243 .ctse()
244 .ignored()
245 .rtse()
246 ._0()
247 });
248
249 match config.word_length {
250 WordLength::DataBits7 => regs.control1().modify(|_, w| w.m()._7bits()),
251 WordLength::DataBits8 => regs.control1().modify(|_, w| w.m()._8bits()),
252 WordLength::DataBits9 => regs.control1().modify(|_, w| w.m()._9bits()),
253 };
254
255 match config.parity {
256 Parity::None => regs.control1().modify(|_, w| w.pce().disable()),
257 Parity::Even => regs
258 .control1()
259 .modify(|_, w| w.pce().enable().ps().parity()),
260 Parity::Odd => regs.control1().modify(|_, w| w.pce().enable().ps().odd()),
261 };
262
263 match config.stop_bits {
264 StopBits::Stop1 => regs.control2().modify(|_, w| w.stop_1()._1bit()),
265 StopBits::Stop2 => regs.control2().modify(|_, w| w.stop_1()._2bits()),
266 };
267
268 match config.duplex_mode {
269 DuplexMode::Full => regs.control3().modify(|_, w| w.hdsel().duplex()),
270 DuplexMode::Half => regs.control3().modify(|_, w| w.hdsel().half_duplex()),
271 };
272
273 match config.sync_mode {
274 SyncMode::Async => regs.control2().modify(|_, w| w.clken().asynchronous()),
275 SyncMode::Sync => regs.control2().modify(|_, w| w.clken().synchronous()),
276 };
277
278 match config.dma {
279 DmaConfig::None => regs
280 .control3()
281 .modify(|_, w| w.dmat().disable().dmar().disable()),
282 DmaConfig::Tx => regs
283 .control3()
284 .modify(|_, w| w.dmat().enable().dmar().disable()),
285 DmaConfig::Rx => regs
286 .control3()
287 .modify(|_, w| w.dmat().disable().dmar().enable()),
288 DmaConfig::TxRx => regs
289 .control3()
290 .modify(|_, w| w.dmat().enable().dmar().enable()),
291 };
292
293 regs.flags().write(|w| unsafe { w.bits(0x03ff) });
294
295 regs.control1()
296 .modify(|_, w| w.te().enable().re().enable().ue().enable());
297
298 while {
299 let flags = regs.flags().read();
300 flags.teack().bit_is_clear() || flags.reack().bit_is_clear()
301 } {
302 core::hint::spin_loop();
303 }
304 }
305}
306
307impl<UART, TXPIN, RXPIN> ErrorType for Serial<UART, TXPIN, RXPIN>
308where
309 UART: Instance,
310 TXPIN: TxPin<UART>,
311 RXPIN: RxPin<UART>,
312{
313 type Error = ErrorKind;
314}
315
316impl<UART: Instance> ErrorType for Tx<UART> {
317 type Error = ErrorKind;
318}
319
320impl<UART: Instance> ErrorType for Rx<UART> {
321 type Error = ErrorKind;
322}
323
324impl<UART: Instance> Write for Tx<UART> {
325 fn write(&mut self, byte: u8) -> NbResult<(), Self::Error> {
326 let regs = regs::<UART>();
327
328 if regs.flags().read().txe().bit_is_clear() {
329 return Err(NbError::WouldBlock);
330 }
331
332 regs.txdata()
333 .write(|w| unsafe { w.tdr().bits(byte as u16) });
334
335 Ok(())
336 }
337
338 fn flush(&mut self) -> NbResult<(), Self::Error> {
339 if regs::<UART>().flags().read().tc().bit_is_clear() {
340 return Err(NbError::WouldBlock);
341 }
342
343 Ok(())
344 }
345}
346
347impl<UART: Instance> fmt::Write for Tx<UART> {
348 fn write_str(&mut self, s: &str) -> fmt::Result {
349 for byte in s.bytes() {
350 nb_block(|| self.write(byte)).map_err(|_| fmt::Error)?;
351 }
352
353 nb_block(|| self.flush()).map_err(|_| fmt::Error)
354 }
355}
356
357impl<UART: Instance> Read for Rx<UART> {
358 fn read(&mut self) -> NbResult<u8, Self::Error> {
359 let regs = regs::<UART>();
360 let flags = regs.flags().read();
361
362 if flags.pe().bit_is_set() {
363 regs.flags().write(|w| w.pe().clear_bit_by_one());
364 return Err(NbError::Other(ErrorKind::Parity));
365 }
366
367 if flags.fe().bit_is_set() {
368 regs.flags().write(|w| w.fe().clear_bit_by_one());
369 return Err(NbError::Other(ErrorKind::FrameFormat));
370 }
371
372 if flags.nf().bit_is_set() {
373 regs.flags().write(|w| w.nf().clear_bit_by_one());
374 return Err(NbError::Other(ErrorKind::Noise));
375 }
376
377 if flags.ore().bit_is_set() {
378 regs.flags().write(|w| w.ore().clear_bit_by_one());
379 return Err(NbError::Other(ErrorKind::Overrun));
380 }
381
382 if flags.rxne().bit_is_clear() {
383 return Err(NbError::WouldBlock);
384 }
385
386 Ok(regs.rxdata().read().rdr().bits() as u8)
387 }
388}
389
390#[inline(always)]
391fn regs<UART: Instance>() -> &'static RegisterBlock {
392 unsafe { &*UART::ptr() }
393}
394
395#[inline(always)]
396fn calc_baudrate_divisor(baudrate: u32) -> u16 {
397 let sys_clock: u32 = system_clock().into();
398 let clock = sys_clock / (DIV_AHB + 1) / (DIV_APB_P + 1);
399 let divisor = clock / baudrate;
400
401 divisor.clamp(16, u16::MAX as u32) as u16
402}
403
404fn nb_block<T, E>(mut f: impl FnMut() -> NbResult<T, E>) -> Result<T, E> {
405 loop {
406 match f() {
407 Ok(value) => return Ok(value),
408 Err(NbError::WouldBlock) => core::hint::spin_loop(),
409 Err(NbError::Other(error)) => return Err(error),
410 }
411 }
412}