stm32_rust_template/driver/usart/
stm32f407.rs1#[cfg(feature = "stm32f407")]
2extern crate alloc;
3
4use super::{
5 ClockPhase, ClockPolarity, Config, DataBits, Event, FlowControl, Mode, ModemControl,
6 ModemStatus, Parity, Result, Status, Usart,
7};
8use crate::mcu::stm32f407::{self, usart::*};
9use crate::utils;
10use alloc::boxed::Box;
11use core::ops::FnMut;
12use core::ptr;
13
14const PCLK1_HZ: u32 = 16_000_000; const PCLK2_HZ: u32 = 16_000_000; pub struct UsartDriver<'a> {
21 regs: *mut RegisterBlock,
22 _callback: Option<Box<dyn FnMut(Event) + 'a>>,
23 config: Config,
24 tx_count: u32,
25 rx_count: u32,
26}
27
28impl<'a> UsartDriver<'a> {
29 pub fn new(usart_base_addr: u32, config: Config) -> Self {
30 Self {
31 regs: usart_base_addr as *mut RegisterBlock,
32 _callback: None,
33 config,
34 tx_count: 0,
35 rx_count: 0,
36 }
37 }
38
39 pub fn new_usart1(config: Config) -> Self {
41 Self::new(stm32f407::USART1_BASEADDR, config)
42 }
43
44 pub fn new_usart2(config: Config) -> Self {
46 Self::new(stm32f407::USART2_BASEADDR, config)
47 }
48
49 pub fn new_usart3(config: Config) -> Self {
51 Self::new(stm32f407::USART3_BASEADDR, config)
52 }
53
54 fn regs(&self) -> &mut RegisterBlock {
55 unsafe { &mut *self.regs }
56 }
57
58 fn is_on_apb2(&self) -> bool {
59 let base = self.regs as u32;
60 base == stm32f407::USART1_BASEADDR
61 }
62
63 fn compute_brr(&self, baudrate: u32) -> u32 {
64 let pclk = if self.is_on_apb2() {
66 PCLK2_HZ
67 } else {
68 PCLK1_HZ
69 };
70 let usartdiv_times_16 = (pclk + (baudrate / 2)) / baudrate;
72 let mantissa = usartdiv_times_16 / 16;
73 let fraction = usartdiv_times_16 & 0xF;
74 (mantissa << 4) | fraction
75 }
76
77 fn write_cr1(&mut self, f: impl FnOnce(u32) -> u32) {
78 let mut v = unsafe { ptr::read_volatile(&self.regs().cr1) };
79 v = f(v);
80 unsafe { ptr::write_volatile(&mut self.regs().cr1, v) };
81 }
82
83 fn write_cr2(&mut self, f: impl FnOnce(u32) -> u32) {
84 let mut v = unsafe { ptr::read_volatile(&self.regs().cr2) };
85 v = f(v);
86 unsafe { ptr::write_volatile(&mut self.regs().cr2, v) };
87 }
88
89 fn write_cr3(&mut self, f: impl FnOnce(u32) -> u32) {
90 let mut v = unsafe { ptr::read_volatile(&self.regs().cr3) };
91 v = f(v);
92 unsafe { ptr::write_volatile(&mut self.regs().cr3, v) };
93 }
94
95 fn wait_txe(&self) {
96 while unsafe { ptr::read_volatile(&self.regs().sr) } & SR_TXE_MASK == 0 {}
97 }
98
99 fn wait_rxne(&self) {
100 while unsafe { ptr::read_volatile(&self.regs().sr) } & SR_RXNE_MASK == 0 {}
101 }
102
103 fn wait_tc(&self) {
104 while unsafe { ptr::read_volatile(&self.regs().sr) } & SR_TC_MASK == 0 {}
105 }
106}
107
108impl<'a> Usart<'a> for UsartDriver<'a> {
109 fn initialize(&mut self, callback: impl FnMut(Event) + 'a) -> Result<()> {
110 self._callback = Some(Box::new(callback));
111
112 self.write_cr1(|v| utils::set_bit(v, CR1_UE_POS, false));
114
115 let cfg = self.config.clone();
117 self.configure(&cfg)?;
118
119 self.write_cr1(|v| utils::set_bit(v, CR1_UE_POS, true));
121 Ok(())
122 }
123
124 fn uninitialize(&mut self) -> Result<()> {
125 self.write_cr1(|v| utils::set_bit(v, CR1_UE_POS, false));
126 self._callback = None;
127 Ok(())
128 }
129
130 fn configure(&mut self, config: &Config) -> Result<()> {
131 self.config = config.clone();
132
133 self.write_cr1(|v| utils::set_bit(v, CR1_UE_POS, false));
135
136 self.write_cr1(|mut v| {
138 v &= !(CR1_M_MASK
140 | CR1_PCE_MASK
141 | CR1_PS_MASK
142 | CR1_TE_MASK
143 | CR1_RE_MASK
144 | CR1_OVER8_MASK
145 | CR1_RWU_MASK
146 | CR1_SBK_MASK
147 | CR1_IDLEIE_MASK
148 | CR1_RXNEIE_MASK
149 | CR1_TCIE_MASK
150 | CR1_TXEIE_MASK
151 | CR1_PEIE_MASK);
152
153 v = match config.data_bits {
155 DataBits::Bits9 => utils::set_bit(v, CR1_M_POS, true),
156 DataBits::Bits8 => utils::set_bit(v, CR1_M_POS, false),
157 _ => return v, };
159
160 match config.parity {
162 Parity::None => {
163 v = utils::set_bit(v, CR1_PCE_POS, false);
164 }
165 Parity::Even => {
166 v = utils::set_bit(v, CR1_PCE_POS, true);
167 v = utils::set_bit(v, CR1_PS_POS, false);
168 }
169 Parity::Odd => {
170 v = utils::set_bit(v, CR1_PCE_POS, true);
171 v = utils::set_bit(v, CR1_PS_POS, true);
172 }
173 }
174
175 let enable_tx = matches!(
177 config.mode,
178 Mode::Asynchronous
179 | Mode::SynchronousMaster
180 | Mode::SynchronousSlave
181 | Mode::SingleWire
182 | Mode::IrDA
183 | Mode::SmartCard
184 );
185 let enable_rx = matches!(
186 config.mode,
187 Mode::Asynchronous
188 | Mode::SynchronousMaster
189 | Mode::SynchronousSlave
190 | Mode::SingleWire
191 | Mode::IrDA
192 | Mode::SmartCard
193 );
194 v = utils::set_bit(v, CR1_TE_POS, enable_tx);
195 v = utils::set_bit(v, CR1_RE_POS, enable_rx);
196
197 v
198 });
199
200 match config.data_bits {
202 DataBits::Bits8 | DataBits::Bits9 => {}
203 _ => return Err(-1),
204 }
205
206 self.write_cr2(|mut v| {
208 v &= !(CR2_STOP_MASK | CR2_CLKEN_MASK | CR2_CPOL_MASK | CR2_CPHA_MASK | CR2_LBCL_MASK);
210
211 let stop_bits_val = match config.stop_bits {
213 super::StopBits::Bits1 => 0,
214 super::StopBits::Bits0_5 => 1,
215 super::StopBits::Bits2 => 2,
216 super::StopBits::Bits1_5 => 3,
217 } as u32;
218 v = utils::set_bits(v, stop_bits_val, CR2_STOP_POS, CR2_STOP_WIDTH);
219
220 let sync_mode = matches!(
222 config.mode,
223 Mode::SynchronousMaster | Mode::SynchronousSlave
224 );
225 v = utils::set_bit(v, CR2_CLKEN_POS, sync_mode);
226 if sync_mode {
227 v = utils::set_bit(
228 v,
229 CR2_CPOL_POS,
230 matches!(config.clock_polarity, ClockPolarity::CPOL1),
231 );
232 v = utils::set_bit(
233 v,
234 CR2_CPHA_POS,
235 matches!(config.clock_phase, ClockPhase::CPHA1),
236 );
237 }
238
239 v
240 });
241
242 self.write_cr3(|mut v| {
244 v &= !(CR3_RTSE_MASK | CR3_CTSE_MASK | CR3_HDSEL_MASK | CR3_IREN_MASK | CR3_SCEN_MASK);
246
247 match config.flow_control {
249 FlowControl::None => {}
250 FlowControl::RTS => {
251 v |= CR3_RTSE_MASK;
252 }
253 FlowControl::CTS => {
254 v |= CR3_CTSE_MASK;
255 }
256 FlowControl::RTS_CTS => {
257 v |= CR3_RTSE_MASK | CR3_CTSE_MASK;
258 }
259 }
260
261 match config.mode {
263 Mode::SingleWire => {
264 v |= CR3_HDSEL_MASK; }
266 Mode::IrDA => {
267 v |= CR3_IREN_MASK;
268 }
269 Mode::SmartCard => {
270 v |= CR3_SCEN_MASK;
271 }
272 _ => {}
273 }
274
275 v
276 });
277
278 let brr = self.compute_brr(config.baudrate);
280 unsafe { ptr::write_volatile(&mut self.regs().brr, brr) };
281
282 self.write_cr1(|v| utils::set_bit(v, CR1_UE_POS, true));
284 Ok(())
285 }
286
287 fn send(&mut self, data: &[u8]) -> Result<()> {
288 self.tx_count = 0;
289 for &byte in data {
290 self.wait_txe();
291 unsafe { ptr::write_volatile(&mut self.regs().dr, byte as u32) };
292 self.tx_count += 1;
293 }
294 self.wait_tc();
295 if let Some(cb) = &mut self._callback {
296 cb(Event::SEND_COMPLETE | Event::TX_COMPLETE);
297 }
298 Ok(())
299 }
300
301 fn receive(&mut self, data: &mut [u8]) -> Result<()> {
302 self.rx_count = 0;
303 for b in data.iter_mut() {
304 self.wait_rxne();
305 *b = unsafe { ptr::read_volatile(&self.regs().dr) as u8 };
306 self.rx_count += 1;
307 }
308 if let Some(cb) = &mut self._callback {
309 cb(Event::RECEIVE_COMPLETE);
310 }
311 Ok(())
312 }
313
314 fn transfer(&mut self, data_out: &[u8], data_in: &mut [u8]) -> Result<()> {
315 if data_in.len() != data_out.len() {
316 return Err(-1);
317 }
318
319 self.tx_count = 0;
320 self.rx_count = 0;
321
322 for (i, &byte) in data_out.iter().enumerate() {
323 self.wait_txe();
324 unsafe { ptr::write_volatile(&mut self.regs().dr, byte as u32) };
325 self.tx_count += 1;
326
327 self.wait_rxne();
328 data_in[i] = unsafe { ptr::read_volatile(&self.regs().dr) as u8 };
329 self.rx_count += 1;
330 }
331 self.wait_tc();
332 if let Some(cb) = &mut self._callback {
333 cb(Event::TRANSFER_COMPLETE);
334 }
335 Ok(())
336 }
337
338 fn get_tx_count(&self) -> u32 {
339 self.tx_count
340 }
341
342 fn get_rx_count(&self) -> u32 {
343 self.rx_count
344 }
345
346 fn get_status(&self) -> Status {
347 let sr = unsafe { ptr::read_volatile(&self.regs().sr) };
348 Status {
349 tx_busy: (sr & SR_TC_MASK) == 0,
350 rx_busy: (sr & SR_RXNE_MASK) != 0,
351 tx_underflow: false,
352 rx_overflow: (sr & SR_ORE_MASK) != 0,
353 rx_break: (sr & SR_LBD_MASK) != 0,
354 rx_framing_error: (sr & SR_FE_MASK) != 0,
355 rx_parity_error: (sr & SR_PE_MASK) != 0,
356 }
357 }
358
359 fn set_modem_control(&mut self, control: ModemControl) -> Result<()> {
360 match control {
361 ModemControl::RTSClear
364 | ModemControl::RTSSet
365 | ModemControl::DTRClear
366 | ModemControl::DTRSet => Err(-2),
367 }
368 }
369
370 fn get_modem_status(&self) -> ModemStatus {
371 let sr = unsafe { ptr::read_volatile(&self.regs().sr) };
372 ModemStatus {
373 cts: (sr & SR_CTS_MASK) != 0,
374 dsr: false,
375 dcd: false,
376 ri: false,
377 }
378 }
379
380 fn tx_enable(&mut self, enable: bool) -> Result<()> {
381 self.write_cr1(|v| utils::set_bit(v, CR1_TE_POS, enable));
382 Ok(())
383 }
384
385 fn rx_enable(&mut self, enable: bool) -> Result<()> {
386 self.write_cr1(|v| utils::set_bit(v, CR1_RE_POS, enable));
387 Ok(())
388 }
389
390 fn control_break(&mut self, enable: bool) -> Result<()> {
391 if enable {
393 self.write_cr1(|v| utils::set_bit(v, CR1_SBK_POS, true));
394 }
395 Ok(())
396 }
397
398 fn abort_send(&mut self) -> Result<()> {
399 self.write_cr1(|v| utils::set_bit(v, CR1_TE_POS, false));
401 Ok(())
402 }
403
404 fn abort_receive(&mut self) -> Result<()> {
405 self.write_cr1(|v| utils::set_bit(v, CR1_RE_POS, false));
407 Ok(())
408 }
409
410 fn abort_transfer(&mut self) -> Result<()> {
411 self.write_cr1(|mut v| {
412 v = utils::set_bit(v, CR1_TE_POS, false);
413 v = utils::set_bit(v, CR1_RE_POS, false);
414 v
415 });
416 Ok(())
417 }
418}