stm32f1_hal/uart/
usart3.rs

1use crate::pac::usart1::cr1;
2type UartX = pac::USART3;
3
4// $sync begin
5
6use super::*;
7use crate::{Mcu, pac};
8
9// Initialization -------------------------------------------------------------
10
11impl UartInit<UartX> for UartX {
12    fn init<OS: OsInterface>(self, mcu: &mut Mcu) -> Uart<OS, UartX> {
13        mcu.rcc.enable(&self);
14        mcu.rcc.reset(&self);
15        Uart {
16            uart: self,
17            _os: PhantomData,
18        }
19    }
20}
21
22impl UartPeriphConfig for UartX {
23    fn config(&mut self, config: Config) {
24        // Configure baud rate
25        let brr = self.get_clock().raw() / config.baudrate;
26        assert!(brr >= 16, "impossible baud rate");
27        self.brr().write(|w| unsafe { w.bits(brr as u16) });
28
29        // Configure word
30        self.cr1().modify(|_, w| {
31            w.m().bit(match config.word_length {
32                WordLength::Bits8 => false,
33                WordLength::Bits9 => true,
34            });
35            w.ps().variant(match config.parity {
36                Parity::ParityOdd => cr1::PS::Odd,
37                _ => cr1::PS::Even,
38            });
39            w.pce().bit(!matches!(config.parity, Parity::ParityNone));
40            w
41        });
42
43        // Configure stop bits
44        self.set_stop_bits(config.stop_bits);
45    }
46
47    fn enable_comm(&mut self, tx: bool, rx: bool) {
48        // UE: enable USART
49        // TE: enable transceiver
50        // RE: enable receiver
51        self.cr1().modify(|_, w| {
52            w.ue().set_bit();
53            w.te().bit(tx);
54            w.re().bit(rx);
55            w
56        });
57    }
58
59    fn set_stop_bits(&mut self, bits: StopBits) {
60        // $sync stop_bits_u1
61        use pac::usart1::cr2::STOP;
62
63        self.cr2().write(|w| {
64            w.stop().variant(match bits {
65                StopBits::STOP0P5 => STOP::Stop0p5,
66                StopBits::STOP1 => STOP::Stop1,
67                StopBits::STOP1P5 => STOP::Stop1p5,
68                StopBits::STOP2 => STOP::Stop2,
69            })
70        });
71        // $sync stop_bits_end
72    }
73
74    #[inline]
75    fn is_tx_empty(&self) -> bool {
76        self.sr().read().txe().bit_is_set()
77    }
78
79    #[inline]
80    fn is_rx_not_empty(&self) -> bool {
81        self.sr().read().rxne().bit_is_set()
82    }
83}
84
85// Implement Peripheral -------------------------------------------------------
86
87impl UartPeriph for UartX {
88    #[inline]
89    fn is_tx_complete(&self) -> bool {
90        let sr = self.sr().read();
91        sr.txe().bit_is_set() && sr.tc().bit_is_set()
92    }
93
94    #[inline]
95    fn write(&mut self, word: u16) -> nb::Result<(), Error> {
96        if self.is_tx_empty() {
97            self.dr().write(|w| unsafe { w.dr().bits(word) });
98            Ok(())
99        } else {
100            Err(nb::Error::WouldBlock)
101        }
102    }
103
104    #[inline]
105    fn write_with(&mut self, f: impl FnOnce() -> Option<u16>) -> Option<bool> {
106        if self.is_tx_empty() {
107            if let Some(data) = f() {
108                self.dr().write(|w| unsafe { w.dr().bits(data) });
109                Some(true)
110            } else {
111                Some(false)
112            }
113        } else {
114            None
115        }
116    }
117
118    fn read(&mut self) -> nb::Result<u16, Error> {
119        let sr = self.sr().read();
120
121        // Check if a byte is available
122        if sr.rxne().bit_is_set() {
123            // Read the received byte
124            return Ok(self.dr().read().dr().bits());
125        }
126
127        // Check for any errors
128        let err = if sr.pe().bit_is_set() {
129            Some(Error::Parity)
130        } else if sr.fe().bit_is_set() {
131            Some(Error::FrameFormat)
132        } else if sr.ne().bit_is_set() {
133            Some(Error::Noise)
134        } else if sr.ore().bit_is_set() {
135            Some(Error::Overrun)
136        } else {
137            None
138        };
139
140        if let Some(err) = err {
141            self.clear_err_flag();
142            Err(nb::Error::Other(err))
143        } else {
144            Err(nb::Error::WouldBlock)
145        }
146    }
147
148    #[inline]
149    fn set_interrupt(&mut self, event: Event, enable: bool) {
150        match event {
151            Event::Idle => {
152                self.cr1().modify(|_, w| w.idleie().bit(enable));
153            }
154            Event::RxNotEmpty => {
155                self.cr1().modify(|_, w| w.rxneie().bit(enable));
156            }
157            Event::TxEmpty => {
158                self.cr1().modify(|_, w| w.txeie().bit(enable));
159            }
160        }
161    }
162
163    #[inline]
164    fn is_interrupt_enable(&mut self, event: Event) -> bool {
165        let cr1 = self.cr1().read();
166        match event {
167            Event::Idle => cr1.idleie().bit_is_set(),
168            Event::RxNotEmpty => cr1.rxneie().bit_is_set(),
169            Event::TxEmpty => cr1.txeie().bit_is_set(),
170        }
171    }
172
173    #[inline]
174    fn is_interrupted(&mut self, event: Event) -> bool {
175        let sr = self.sr().read();
176        match event {
177            Event::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            Event::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            Event::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
208impl UartPeriphWithDma for UartX {
209    #[inline]
210    fn get_tx_data_reg_addr(&self) -> usize {
211        self.dr().as_ptr() as usize
212    }
213
214    #[inline]
215    fn get_rx_data_reg_addr(&self) -> usize {
216        self.dr().as_ptr() as usize
217    }
218
219    #[inline]
220    fn enable_dma_tx(&mut self, enable: bool) {
221        self.cr3().modify(|_, w| w.dmat().bit(enable));
222    }
223
224    #[inline]
225    fn enable_dma_rx(&mut self, enable: bool) {
226        self.cr3().modify(|_, w| w.dmar().bit(enable));
227    }
228}
229
230// $sync end