stm32f4xx_hal/serial/
uart_impls.rs

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
24// Implemented by all USART/UART instances
25pub 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        // Delegate to u16 version, then truncate to 8 bits
58        self.read_u16().map(|word16| word16 as u8)
59    }
60
61    fn write_u8(&self, word: u8) -> nb::Result<(), Error> {
62        // Delegate to u16 version
63        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    // ISR
101    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    // Listen
119    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    // PeriAddress
147    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            // NOTE(unsafe) atomic read with no side effects
158            let sr = self.sr().read();
159
160            // Any error requires the dr to be read to clear
161            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                // NOTE(unsafe) atomic read from stateless register
179                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            // NOTE(unsafe) atomic read with no side effects
187            let sr = self.sr().read();
188
189            if sr.txe().bit_is_set() {
190                // NOTE(unsafe) atomic write to stateless register
191                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            // NOTE(unsafe) atomic read with no side effects
200            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            // The frequency to calculate USARTDIV is this:
279            //
280            // (Taken from STM32F411xC/E Reference Manual,
281            // Section 19.3.4, Equation 1)
282            //
283            // 16 bit oversample: OVER8 = 0
284            // 8 bit oversample:  OVER8 = 1
285            //
286            // USARTDIV =          (pclk)
287            //            ------------------------
288            //            8 x (2 - OVER8) x (baud)
289            //
290            // BUT, the USARTDIV has 4 "fractional" bits, which effectively
291            // means that we need to "correct" the equation as follows:
292            //
293            // USARTDIV =      (pclk) * 16
294            //            ------------------------
295            //            8 x (2 - OVER8) x (baud)
296            //
297            // When OVER8 is enabled, we can only use the lowest three
298            // fractional bits, so we'll need to shift those last four bits
299            // right one bit
300
301            // Calculate correct baudrate divisor on the fly
302            if (pclk_freq / 16) >= baud {
303                // We have the ability to oversample to 16 bits, take
304                // advantage of it.
305                //
306                // We also add `baud / 2` to the `pclk_freq` to ensure
307                // rounding of values to the closest scale, rather than the
308                // floored behavior of normal integer division.
309                let div = (pclk_freq + (baud / 2)) / baud;
310                Ok((false, div))
311            } else if (pclk_freq / 8) >= baud {
312                // We are close enough to pclk where we can only
313                // oversample 8.
314                //
315                // See note above regarding `baud` and rounding.
316                let div = ((pclk_freq * 2) + (baud / 2)) / baud;
317
318                // Ensure the the fractional bits (only 3) are
319                // right-aligned.
320                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            // Enable clock.
343            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        // Reset other registers to disable advanced USART features
360        uart.cr2().reset();
361        uart.cr3().reset(); // IrDA configuration - see STM32F411xC/E (RM0383) sections:
362                            // 19.3.12 "IrDA SIR ENDEC block"
363                            // 19.6.7 "Guard time and prescaler register (USART_GTPR)"
364        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                // FIXME
378                uart.gtpr()
379                    .write(|w| w.psc().bits((1843200u32 / pclk_freq) as u8))
380            },
381            IrdaMode::None => {}
382        }
383
384        // Enable transmission and receiving
385        // and configure frame
386
387        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            // Enable clock.
424            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        // Reset other registers to disable advanced USART features
436        uart.cr2().reset();
437        uart.cr3().reset();
438
439        // Enable transmission and receiving
440        // and configure frame
441
442        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    /// This clears `Idle`, `Overrun`, `Noise`, `FrameError` and `ParityError` flags
478    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    /// This clears `Idle`, `Overrun`, `Noise`, `FrameError` and `ParityError` flags
493    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}