stm32f1_hal/uart/
uart4.rs

1use crate::pac::uart4::cr1;
2type UartX = pac::UART4;
3
4// sync begin
5
6use super::*;
7use crate::{
8    Mcu, pac,
9    rcc::{BusClock, Enable, Reset},
10};
11
12// Initialization -------------------------------------------------------------
13
14impl UartInit<UartX> for UartX {
15    fn constrain(self) -> Uart<UartX> {
16        Uart { uart: self }
17    }
18}
19
20impl UartPeriphExt for UartX {
21    fn config(&mut self, config: Config, mcu: &mut Mcu) {
22        UartX::enable(&mut mcu.rcc);
23        UartX::reset(&mut mcu.rcc);
24
25        // Configure baud rate
26        let brr = UartX::clock(&mcu.rcc.clocks).raw() / config.baudrate;
27        assert!(brr >= 16, "impossible baud rate");
28        self.brr().write(|w| unsafe { w.bits(brr as u16) });
29
30        // Configure word
31        self.cr1().modify(|_, w| {
32            w.m().bit(match config.word_length {
33                WordLength::Bits8 => false,
34                WordLength::Bits9 => true,
35            });
36            w.ps().variant(match config.parity {
37                Parity::ParityOdd => cr1::PS::Odd,
38                _ => cr1::PS::Even,
39            });
40            w.pce().bit(!matches!(config.parity, Parity::ParityNone));
41            w
42        });
43
44        // Configure stop bits
45        self.set_stop_bits(config.stop_bits);
46    }
47
48    fn enable_comm(&mut self, tx: bool, rx: bool) {
49        // UE: enable USART
50        // TE: enable transceiver
51        // RE: enable receiver
52        self.cr1().modify(|_, w| {
53            w.ue().set_bit();
54            w.te().bit(tx);
55            w.re().bit(rx);
56            w
57        });
58    }
59
60    fn set_stop_bits(&mut self, bits: StopBits) {
61        // sync stop_bits_u4
62        use pac::uart4::cr2::STOP;
63
64        // StopBits::STOP0P5 and StopBits::STOP1P5 aren't supported when using UART
65        // STOP_A::STOP1 and STOP_A::STOP2 will be used, respectively
66        self.cr2().write(|w| {
67            w.stop().variant(match bits {
68                StopBits::STOP0P5 | StopBits::STOP1 => STOP::Stop1,
69                StopBits::STOP1P5 | StopBits::STOP2 => STOP::Stop2,
70            })
71        });
72        // sync stop_bits_u4_end
73    }
74}
75
76// Implement Peripheral -------------------------------------------------------
77
78impl UartPeriph for UartX {
79    #[inline]
80    fn set_dma_tx(&mut self, enable: bool) {
81        self.cr3().modify(|_, w| w.dmat().bit(enable));
82    }
83
84    #[inline]
85    fn set_dma_rx(&mut self, enable: bool) {
86        self.cr3().modify(|_, w| w.dmar().bit(enable));
87    }
88
89    #[inline]
90    fn is_tx_empty(&self) -> bool {
91        self.sr().read().txe().bit_is_set()
92    }
93
94    #[inline]
95    fn is_tx_complete(&self) -> bool {
96        self.sr().read().tc().bit_is_set()
97    }
98
99    fn write(&mut self, word: u16) -> nb::Result<(), Error> {
100        if self.is_tx_empty() {
101            self.dr().write(|w| unsafe { w.dr().bits(word.into()) });
102            Ok(())
103        } else {
104            Err(nb::Error::WouldBlock)
105        }
106    }
107
108    fn read(&mut self) -> nb::Result<u16, Error> {
109        let sr = self.sr().read();
110
111        // Check if a byte is available
112        if sr.rxne().bit_is_set() {
113            // Read the received byte
114            return Ok(self.dr().read().dr().bits());
115        }
116
117        // Check for any errors
118        let err = if sr.pe().bit_is_set() {
119            Some(Error::Parity)
120        } else if sr.fe().bit_is_set() {
121            Some(Error::FrameFormat)
122        } else if sr.ne().bit_is_set() {
123            Some(Error::Noise)
124        } else if sr.ore().bit_is_set() {
125            Some(Error::Overrun)
126        } else {
127            None
128        };
129
130        if let Some(err) = err {
131            self.clear_err_flag();
132            Err(nb::Error::Other(err))
133        } else {
134            Err(nb::Error::WouldBlock)
135        }
136    }
137
138    #[inline]
139    fn get_tx_data_reg_addr(&self) -> u32 {
140        &self.dr() as *const _ as u32
141    }
142
143    #[inline]
144    fn get_rx_data_reg_addr(&self) -> u32 {
145        &self.dr() as *const _ as u32
146    }
147
148    #[inline]
149    fn set_interrupt(&mut self, event: UartEvent, enable: bool) {
150        match event {
151            UartEvent::Idle => {
152                self.cr1().modify(|_, w| w.idleie().bit(enable));
153            }
154            UartEvent::RxNotEmpty => {
155                self.cr1().modify(|_, w| w.rxneie().bit(enable));
156            }
157            UartEvent::TxEmpty => {
158                self.cr1().modify(|_, w| w.txeie().bit(enable));
159            }
160        }
161    }
162
163    #[inline]
164    fn is_interrupt_enable(&mut self, event: UartEvent) -> bool {
165        let cr1 = self.cr1().read();
166        match event {
167            UartEvent::Idle => cr1.idleie().bit_is_set(),
168            UartEvent::RxNotEmpty => cr1.rxneie().bit_is_set(),
169            UartEvent::TxEmpty => cr1.txeie().bit_is_set(),
170        }
171    }
172
173    #[inline]
174    fn is_interrupted(&mut self, event: UartEvent) -> bool {
175        let sr = self.sr().read();
176        match event {
177            UartEvent::Idle => {
178                if sr.idle().bit_is_set() && self.cr1().read().idleie().bit_is_set() {
179                    self.clear_err_flag();
180                    return true;
181                }
182            }
183            UartEvent::RxNotEmpty => {
184                if (sr.rxne().bit_is_set() || sr.ore().bit_is_set())
185                    && self.cr1().read().rxneie().bit_is_set()
186                {
187                    return true;
188                }
189            }
190            UartEvent::TxEmpty => {
191                if sr.txe().bit_is_set() && self.cr1().read().txeie().bit_is_set() {
192                    return true;
193                }
194            }
195        }
196        false
197    }
198
199    /// In order to clear that error flag, you have to do a read from the sr register
200    /// followed by a read from the dr register.
201    #[inline]
202    fn clear_err_flag(&self) {
203        let _ = self.sr().read();
204        let _ = self.dr().read();
205    }
206
207    #[inline]
208    fn is_rx_not_empty(&self) -> bool {
209        self.sr().read().rxne().bit_is_set()
210    }
211}
212
213// sync end