1use core::fmt;
2
3use enumflags2::BitFlags;
4use nb::block;
5
6use super::{
7 config, CFlag, Error, Event, Flag, Rx, RxISR, RxListen, Serial, SerialExt, Tx, TxISR, TxListen,
8};
9use crate::dma::{
10 traits::{DMASet, PeriAddress},
11 MemoryToPeripheral, PeripheralToMemory,
12};
13use crate::gpio::{alt::SerialAsync as CommonPins, NoPin, PushPull};
14use crate::rcc::{self, Clocks};
15
16#[cfg(feature = "uart4")]
17pub(crate) use crate::pac::uart4::RegisterBlock as RegisterBlockUart;
18pub(crate) use crate::pac::usart1::RegisterBlock as RegisterBlockUsart;
19
20#[cfg(feature = "uart4")]
21impl crate::Sealed for RegisterBlockUart {}
22impl crate::Sealed for RegisterBlockUsart {}
23
24pub trait Instance:
26 crate::Sealed
27 + crate::Ptr<RB: RegisterBlockImpl>
28 + crate::Steal
29 + core::ops::Deref<Target = Self::RB>
30 + rcc::Enable
31 + rcc::Reset
32 + rcc::BusClock
33 + CommonPins
34{
35 #[doc(hidden)]
36 fn set_stopbits(&self, bits: config::StopBits);
37 #[doc(hidden)]
38 #[inline(always)]
39 fn peri_address() -> u32 {
40 unsafe { &*Self::ptr() }.peri_address()
41 }
42}
43
44pub trait RegisterBlockImpl: crate::Sealed {
45 #[allow(clippy::new_ret_no_self)]
46 fn new<UART: Instance + crate::Ptr<RB = Self>, WORD>(
47 uart: UART,
48 pins: (impl Into<UART::Tx<PushPull>>, impl Into<UART::Rx<PushPull>>),
49 config: impl Into<config::Config>,
50 clocks: &Clocks,
51 ) -> Result<Serial<UART, WORD>, config::InvalidConfig>;
52
53 fn read_u16(&self) -> nb::Result<u16, Error>;
54 fn write_u16(&self, word: u16) -> nb::Result<(), Error>;
55
56 fn read_u8(&self) -> nb::Result<u8, Error> {
57 self.read_u16().map(|word16| word16 as u8)
59 }
60
61 fn write_u8(&self, word: u8) -> nb::Result<(), Error> {
62 self.write_u16(u16::from(word))
64 }
65
66 fn flush(&self) -> nb::Result<(), Error>;
67
68 fn bread_all_u8(&self, buffer: &mut [u8]) -> Result<(), Error> {
69 for b in buffer.iter_mut() {
70 *b = nb::block!(self.read_u8())?;
71 }
72 Ok(())
73 }
74
75 fn bread_all_u16(&self, buffer: &mut [u16]) -> Result<(), Error> {
76 for b in buffer.iter_mut() {
77 *b = nb::block!(self.read_u16())?;
78 }
79 Ok(())
80 }
81
82 fn bwrite_all_u8(&self, buffer: &[u8]) -> Result<(), Error> {
83 for &b in buffer {
84 nb::block!(self.write_u8(b))?;
85 }
86 Ok(())
87 }
88
89 fn bwrite_all_u16(&self, buffer: &[u16]) -> Result<(), Error> {
90 for &b in buffer {
91 nb::block!(self.write_u16(b))?;
92 }
93 Ok(())
94 }
95
96 fn bflush(&self) -> Result<(), Error> {
97 nb::block!(self.flush())
98 }
99
100 fn flags(&self) -> BitFlags<Flag>;
102
103 fn is_idle(&self) -> bool {
104 self.flags().contains(Flag::Idle)
105 }
106 fn is_rx_not_empty(&self) -> bool {
107 self.flags().contains(Flag::RxNotEmpty)
108 }
109 fn is_tx_empty(&self) -> bool {
110 self.flags().contains(Flag::TxEmpty)
111 }
112 fn clear_flags(&self, flags: BitFlags<CFlag>);
113 fn clear_idle_interrupt(&self);
114 fn check_and_clear_error_flags(&self) -> Result<(), Error>;
115 fn enable_error_interrupt_generation(&self);
116 fn disable_error_interrupt_generation(&self);
117
118 fn listen_event(&self, disable: Option<BitFlags<Event>>, enable: Option<BitFlags<Event>>);
120
121 #[inline(always)]
122 fn listen_rxne(&self) {
123 self.listen_event(None, Some(Event::RxNotEmpty.into()))
124 }
125 #[inline(always)]
126 fn unlisten_rxne(&self) {
127 self.listen_event(Some(Event::RxNotEmpty.into()), None)
128 }
129 #[inline(always)]
130 fn listen_idle(&self) {
131 self.listen_event(None, Some(Event::Idle.into()))
132 }
133 #[inline(always)]
134 fn unlisten_idle(&self) {
135 self.listen_event(Some(Event::Idle.into()), None)
136 }
137 #[inline(always)]
138 fn listen_txe(&self) {
139 self.listen_event(None, Some(Event::TxEmpty.into()))
140 }
141 #[inline(always)]
142 fn unlisten_txe(&self) {
143 self.listen_event(Some(Event::TxEmpty.into()), None)
144 }
145
146 fn peri_address(&self) -> u32;
148
149 fn enable_dma(&self, dc: config::DmaConfig);
150
151 fn calculate_brr(pclk_freq: u32, baud: u32) -> Result<(bool, u32), config::InvalidConfig>;
152}
153
154macro_rules! uartCommon {
155 () => {
156 fn read_u16(&self) -> nb::Result<u16, Error> {
157 let sr = self.sr().read();
159
160 if sr.pe().bit_is_set()
162 || sr.fe().bit_is_set()
163 || sr.nf().bit_is_set()
164 || sr.ore().bit_is_set()
165 {
166 self.dr().read();
167 }
168
169 Err(if sr.pe().bit_is_set() {
170 Error::Parity.into()
171 } else if sr.fe().bit_is_set() {
172 Error::FrameFormat.into()
173 } else if sr.nf().bit_is_set() {
174 Error::Noise.into()
175 } else if sr.ore().bit_is_set() {
176 Error::Overrun.into()
177 } else if sr.rxne().bit_is_set() {
178 return Ok(self.dr().read().dr().bits());
180 } else {
181 nb::Error::WouldBlock
182 })
183 }
184
185 fn write_u16(&self, word: u16) -> nb::Result<(), Error> {
186 let sr = self.sr().read();
188
189 if sr.txe().bit_is_set() {
190 self.dr().write(|w| w.dr().set(word));
192 Ok(())
193 } else {
194 Err(nb::Error::WouldBlock)
195 }
196 }
197
198 fn flush(&self) -> nb::Result<(), Error> {
199 let sr = self.sr().read();
201
202 if sr.tc().bit_is_set() {
203 Ok(())
204 } else {
205 Err(nb::Error::WouldBlock)
206 }
207 }
208
209 fn flags(&self) -> BitFlags<Flag> {
210 BitFlags::from_bits_truncate(self.sr().read().bits())
211 }
212
213 fn clear_flags(&self, flags: BitFlags<CFlag>) {
214 self.sr()
215 .write(|w| unsafe { w.bits(0xffff & !flags.bits()) });
216 }
217
218 fn clear_idle_interrupt(&self) {
219 let _ = self.sr().read();
220 let _ = self.dr().read();
221 }
222
223 fn check_and_clear_error_flags(&self) -> Result<(), Error> {
224 let sr = self.sr().read();
225 let _ = self.dr().read();
226
227 if sr.ore().bit_is_set() {
228 Err(Error::Overrun)
229 } else if sr.nf().bit_is_set() {
230 Err(Error::Noise)
231 } else if sr.fe().bit_is_set() {
232 Err(Error::FrameFormat)
233 } else if sr.pe().bit_is_set() {
234 Err(Error::Parity)
235 } else {
236 Ok(())
237 }
238 }
239
240 fn enable_error_interrupt_generation(&self) {
241 self.cr3().modify(|_, w| w.eie().enabled());
242 }
243
244 fn disable_error_interrupt_generation(&self) {
245 self.cr3().modify(|_, w| w.eie().disabled());
246 }
247
248 fn listen_event(&self, disable: Option<BitFlags<Event>>, enable: Option<BitFlags<Event>>) {
249 self.cr1().modify(|r, w| unsafe {
250 w.bits({
251 let mut bits = r.bits();
252 if let Some(d) = disable {
253 bits &= !(d.bits() as u32);
254 }
255 if let Some(e) = enable {
256 bits |= e.bits() as u32;
257 }
258 bits
259 })
260 });
261 }
262
263 fn peri_address(&self) -> u32 {
264 self.dr().as_ptr() as u32
265 }
266
267 fn enable_dma(&self, dc: config::DmaConfig) {
268 use config::DmaConfig;
269 match dc {
270 DmaConfig::Tx => self.cr3().write(|w| w.dmat().enabled()),
271 DmaConfig::Rx => self.cr3().write(|w| w.dmar().enabled()),
272 DmaConfig::TxRx => self.cr3().write(|w| w.dmar().enabled().dmat().enabled()),
273 DmaConfig::None => {}
274 }
275 }
276
277 fn calculate_brr(pclk_freq: u32, baud: u32) -> Result<(bool, u32), config::InvalidConfig> {
278 if (pclk_freq / 16) >= baud {
303 let div = (pclk_freq + (baud / 2)) / baud;
310 Ok((false, div))
311 } else if (pclk_freq / 8) >= baud {
312 let div = ((pclk_freq * 2) + (baud / 2)) / baud;
317
318 let frac = div & 0xF;
321 let div = (div & !0xF) | (frac >> 1);
322 Ok((true, div))
323 } else {
324 Err(config::InvalidConfig)
325 }
326 }
327 };
328}
329
330impl RegisterBlockImpl for RegisterBlockUsart {
331 fn new<UART: Instance + crate::Ptr<RB = Self>, WORD>(
332 uart: UART,
333 pins: (impl Into<UART::Tx<PushPull>>, impl Into<UART::Rx<PushPull>>),
334 config: impl Into<config::Config>,
335 clocks: &Clocks,
336 ) -> Result<Serial<UART, WORD>, config::InvalidConfig>
337where {
338 use self::config::*;
339
340 let config = config.into();
341 unsafe {
342 UART::enable_unchecked();
344 UART::reset_unchecked();
345 }
346
347 let pclk_freq = UART::clock(clocks).raw();
348 let baud = config.baudrate.0;
349
350 let (over8, div) = if config.irda != IrdaMode::None {
351 let div = (pclk_freq + (baud / 2)) / baud;
352 (false, div)
353 } else {
354 Self::calculate_brr(pclk_freq, baud)?
355 };
356
357 uart.brr().write(|w| unsafe { w.bits(div) });
358
359 uart.cr2().reset();
361 uart.cr3().reset(); if config.irda != IrdaMode::None && config.stopbits != StopBits::STOP1 {
365 return Err(config::InvalidConfig);
366 }
367
368 match config.irda {
369 IrdaMode::Normal => unsafe {
370 uart.gtpr().reset();
371 uart.cr3().write(|w| w.iren().enabled());
372 uart.gtpr().write(|w| w.psc().bits(1u8))
373 },
374 IrdaMode::LowPower => unsafe {
375 uart.gtpr().reset();
376 uart.cr3().write(|w| w.iren().enabled().irlp().low_power());
377 uart.gtpr()
379 .write(|w| w.psc().bits((1843200u32 / pclk_freq) as u8))
380 },
381 IrdaMode::None => {}
382 }
383
384 uart.cr1().write(|w| {
388 w.ue().set_bit();
389 w.over8().bit(over8);
390 w.te().set_bit();
391 w.re().set_bit();
392 w.m().bit(config.wordlength == WordLength::DataBits9);
393 w.pce().bit(config.parity != Parity::ParityNone);
394 w.ps().bit(config.parity == Parity::ParityOdd)
395 });
396
397 uart.enable_dma(config.dma);
398
399 let serial = Serial {
400 tx: Tx::new(uart, pins.0.into()),
401 rx: Rx::new(unsafe { UART::steal() }, pins.1.into()),
402 };
403 serial.tx.usart.set_stopbits(config.stopbits);
404 Ok(serial)
405 }
406
407 uartCommon! {}
408}
409
410#[cfg(feature = "uart4")]
411impl RegisterBlockImpl for RegisterBlockUart {
412 fn new<UART: Instance + crate::Ptr<RB = Self>, WORD>(
413 uart: UART,
414 pins: (impl Into<UART::Tx<PushPull>>, impl Into<UART::Rx<PushPull>>),
415 config: impl Into<config::Config>,
416 clocks: &Clocks,
417 ) -> Result<Serial<UART, WORD>, config::InvalidConfig>
418where {
419 use self::config::*;
420
421 let config = config.into();
422 unsafe {
423 UART::enable_unchecked();
425 UART::reset_unchecked();
426 }
427
428 let pclk_freq = UART::clock(clocks).raw();
429 let baud = config.baudrate.0;
430
431 let (over8, div) = Self::calculate_brr(pclk_freq, baud)?;
432
433 uart.brr().write(|w| unsafe { w.bits(div) });
434
435 uart.cr2().reset();
437 uart.cr3().reset();
438
439 uart.cr1().write(|w| {
443 w.ue().set_bit();
444 w.over8().bit(over8);
445 w.te().set_bit();
446 w.re().set_bit();
447 w.m().bit(config.wordlength == WordLength::DataBits9);
448 w.pce().bit(config.parity != Parity::ParityNone);
449 w.ps().bit(config.parity == Parity::ParityOdd)
450 });
451
452 uart.enable_dma(config.dma);
453
454 let serial = Serial {
455 tx: Tx::new(uart, pins.0.into()),
456 rx: Rx::new(unsafe { UART::steal() }, pins.1.into()),
457 };
458 serial.tx.usart.set_stopbits(config.stopbits);
459 Ok(serial)
460 }
461
462 uartCommon! {}
463}
464
465impl<UART: Instance, WORD> RxISR for Serial<UART, WORD>
466where
467 Rx<UART, WORD>: RxISR,
468{
469 fn is_idle(&self) -> bool {
470 self.rx.is_idle()
471 }
472
473 fn is_rx_not_empty(&self) -> bool {
474 self.rx.is_rx_not_empty()
475 }
476
477 fn clear_idle_interrupt(&self) {
479 self.rx.clear_idle_interrupt();
480 }
481}
482
483impl<UART: Instance, WORD> RxISR for Rx<UART, WORD> {
484 fn is_idle(&self) -> bool {
485 self.usart.is_idle()
486 }
487
488 fn is_rx_not_empty(&self) -> bool {
489 self.usart.is_rx_not_empty()
490 }
491
492 fn clear_idle_interrupt(&self) {
494 self.usart.clear_idle_interrupt();
495 }
496}
497
498impl<UART: Instance, WORD> TxISR for Serial<UART, WORD>
499where
500 Tx<UART, WORD>: TxISR,
501{
502 fn is_tx_empty(&self) -> bool {
503 self.tx.is_tx_empty()
504 }
505}
506
507impl<UART: Instance, WORD> TxISR for Tx<UART, WORD> {
508 fn is_tx_empty(&self) -> bool {
509 self.usart.is_tx_empty()
510 }
511}
512
513impl<UART: Instance, WORD> RxListen for Rx<UART, WORD> {
514 fn listen(&mut self) {
515 self.usart.listen_rxne()
516 }
517
518 fn unlisten(&mut self) {
519 self.usart.unlisten_rxne()
520 }
521
522 fn listen_idle(&mut self) {
523 self.usart.listen_idle()
524 }
525
526 fn unlisten_idle(&mut self) {
527 self.usart.unlisten_idle()
528 }
529}
530
531impl<UART: Instance, WORD> TxListen for Tx<UART, WORD> {
532 fn listen(&mut self) {
533 self.usart.listen_txe()
534 }
535
536 fn unlisten(&mut self) {
537 self.usart.unlisten_txe()
538 }
539}
540
541impl<UART: Instance, WORD> crate::ClearFlags for Serial<UART, WORD> {
542 type Flag = CFlag;
543
544 #[inline(always)]
545 fn clear_flags(&mut self, flags: impl Into<BitFlags<Self::Flag>>) {
546 self.tx.usart.clear_flags(flags.into())
547 }
548}
549
550impl<UART: Instance, WORD> crate::ReadFlags for Serial<UART, WORD> {
551 type Flag = Flag;
552
553 #[inline(always)]
554 fn flags(&self) -> BitFlags<Self::Flag> {
555 self.tx.usart.flags()
556 }
557}
558
559impl<UART: Instance, WORD> crate::Listen for Serial<UART, WORD> {
560 type Event = Event;
561
562 #[inline(always)]
563 fn listen(&mut self, event: impl Into<BitFlags<Event>>) {
564 self.tx.usart.listen_event(None, Some(event.into()));
565 }
566
567 #[inline(always)]
568 fn listen_only(&mut self, event: impl Into<BitFlags<Self::Event>>) {
569 self.tx
570 .usart
571 .listen_event(Some(BitFlags::ALL), Some(event.into()));
572 }
573
574 #[inline(always)]
575 fn unlisten(&mut self, event: impl Into<BitFlags<Event>>) {
576 self.tx.usart.listen_event(Some(event.into()), None);
577 }
578}
579
580impl<UART: Instance> fmt::Write for Serial<UART>
581where
582 Tx<UART>: fmt::Write,
583{
584 fn write_str(&mut self, s: &str) -> fmt::Result {
585 self.tx.write_str(s)
586 }
587}
588
589impl<UART: Instance> fmt::Write for Tx<UART> {
590 fn write_str(&mut self, s: &str) -> fmt::Result {
591 s.bytes()
592 .try_for_each(|c| block!(self.usart.write_u8(c)))
593 .map_err(|_| fmt::Error)
594 }
595}
596
597impl<UART: Instance> SerialExt for UART {
598 fn serial<WORD>(
599 self,
600 pins: (impl Into<Self::Tx<PushPull>>, impl Into<Self::Rx<PushPull>>),
601 config: impl Into<config::Config>,
602 clocks: &Clocks,
603 ) -> Result<Serial<Self, WORD>, config::InvalidConfig> {
604 Serial::new(self, pins, config, clocks)
605 }
606}
607
608impl<UART: Instance, WORD> Serial<UART, WORD> {
609 pub fn tx(
610 usart: UART,
611 tx_pin: impl Into<UART::Tx<PushPull>>,
612 config: impl Into<config::Config>,
613 clocks: &Clocks,
614 ) -> Result<Tx<UART, WORD>, config::InvalidConfig>
615 where
616 NoPin: Into<UART::Rx<PushPull>>,
617 {
618 Self::new(usart, (tx_pin, NoPin::new()), config, clocks).map(|s| s.split().0)
619 }
620}
621
622impl<UART: Instance, WORD> Serial<UART, WORD> {
623 pub fn rx(
624 usart: UART,
625 rx_pin: impl Into<UART::Rx<PushPull>>,
626 config: impl Into<config::Config>,
627 clocks: &Clocks,
628 ) -> Result<Rx<UART, WORD>, config::InvalidConfig>
629 where
630 NoPin: Into<UART::Tx<PushPull>>,
631 {
632 Self::new(usart, (NoPin::new(), rx_pin), config, clocks).map(|s| s.split().1)
633 }
634}
635
636unsafe impl<UART: Instance> PeriAddress for Rx<UART, u8> {
637 #[inline(always)]
638 fn address(&self) -> u32 {
639 self.usart.peri_address()
640 }
641
642 type MemSize = u8;
643}
644
645unsafe impl<UART: CommonPins, STREAM, const CHANNEL: u8> DMASet<STREAM, CHANNEL, PeripheralToMemory>
646 for Rx<UART>
647where
648 UART: DMASet<STREAM, CHANNEL, PeripheralToMemory>,
649{
650}
651
652unsafe impl<UART: Instance> PeriAddress for Tx<UART, u8> {
653 #[inline(always)]
654 fn address(&self) -> u32 {
655 self.usart.peri_address()
656 }
657
658 type MemSize = u8;
659}
660
661unsafe impl<UART: CommonPins, STREAM, const CHANNEL: u8> DMASet<STREAM, CHANNEL, MemoryToPeripheral>
662 for Tx<UART>
663where
664 UART: DMASet<STREAM, CHANNEL, MemoryToPeripheral>,
665{
666}