Skip to content

Commit b3409e7

Browse files
committed
Improve UART modules
1 parent b644729 commit b3409e7

File tree

8 files changed

+778
-211
lines changed

8 files changed

+778
-211
lines changed

scripts/sync_code.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@
44
from base import blue, green, red
55

66
TABLE = {
7-
"src/uart/uart.rs": "src/uart/usart.rs",
8-
"src/timer/timer8.rs": "src/timer/timer1.rs",
7+
"src/uart/usart2.rs": "src/uart/usart1.rs",
8+
"src/uart/usart3.rs": "src/uart/usart1.rs",
9+
"src/uart/uart4.rs": "src/uart/usart1.rs",
10+
"src/uart/uart5.rs": "src/uart/uart4.rs",
911
"src/timer/timer2.rs": "src/timer/timer1.rs",
1012
"src/timer/timer3.rs": "src/timer/timer2.rs",
1113
"src/timer/timer4.rs": "src/timer/timer2.rs",
1214
"src/timer/timer5.rs": "src/timer/timer2.rs",
1315
"src/timer/timer6.rs": "src/timer/timer1.rs",
1416
"src/timer/timer7.rs": "src/timer/timer6.rs",
17+
"src/timer/timer8.rs": "src/timer/timer1.rs",
1518
"src/timer/timer15.rs": "src/timer/timer2.rs",
1619
"src/timer/timer16.rs": "src/timer/timer2.rs",
1720
"src/timer/timer17.rs": "src/timer/timer16.rs",

src/prelude.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ pub use crate::ringbuf::ReadChunkExt;
2121
pub use crate::ringbuf::WriteChunkExt;
2222
// pub use crate::timer::timer_1_8::TimerInit as _;
2323
#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
24-
pub use crate::uart::uart::UartInit as _;
25-
pub use crate::uart::usart::UartInit as _;
24+
pub use crate::uart::UartInit as _;
2625
pub use cortex_m;
2726
pub use cortex_m_rt;
2827
pub use fugit::ExtU32 as _fugit_ExtU32;

src/uart/mod.rs

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,57 @@
11
#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
2-
pub(crate) mod uart;
3-
pub(crate) mod usart;
4-
2+
pub mod uart4;
3+
#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
4+
pub mod uart5;
5+
pub mod usart1;
6+
pub mod usart2;
7+
pub mod usart3;
58
pub use crate::common::uart::*;
9+
10+
use crate::{
11+
Steal,
12+
afio::{RemapMode, uart_remap::*},
13+
rcc::{BusClock, Enable, Reset},
14+
};
15+
16+
use crate::Mcu;
17+
18+
pub trait UartInit<U> {
19+
fn constrain(self) -> Uart<U>;
20+
}
21+
22+
pub trait UartPeriphExt: UartPeriph + BusClock + Enable + Reset {
23+
fn config(&mut self, config: Config, mcu: &mut Mcu);
24+
fn enable_comm(&mut self, tx: bool, rx: bool);
25+
fn set_stop_bits(&mut self, bits: StopBits);
26+
}
27+
28+
// wrapper
29+
pub struct Uart<U> {
30+
uart: U,
31+
}
32+
33+
#[allow(private_bounds)]
34+
impl<U: UartPeriphExt + Steal> Uart<U> {
35+
pub fn into_tx_rx<REMAP: RemapMode<U>>(
36+
mut self,
37+
pins: (Option<impl UartTxPin<REMAP>>, Option<impl UartRxPin<REMAP>>),
38+
config: Config,
39+
mcu: &mut Mcu,
40+
) -> (Option<Tx<U>>, Option<Rx<U>>) {
41+
REMAP::remap(&mut mcu.afio);
42+
self.uart.config(config, mcu);
43+
self.uart.enable_comm(pins.0.is_some(), pins.1.is_some());
44+
unsafe {
45+
(
46+
pins.0
47+
.map(|_| Tx::new([self.uart.steal(), self.uart.steal()])),
48+
pins.1
49+
.map(|_| Rx::new([self.uart.steal(), self.uart.steal()])),
50+
)
51+
}
52+
}
53+
54+
pub fn get_idle_interrupt_handler(&self) -> UartIdleInterrupt<U> {
55+
UartIdleInterrupt::new(unsafe { self.uart.steal() })
56+
}
57+
}
Lines changed: 39 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,34 @@
1-
#![allow(dead_code)]
2-
#![allow(private_bounds)]
1+
use crate::pac::uart4::cr1;
2+
type UartX = pac::UART4;
33

4-
use crate::pac::uart4::{self, cr1};
5-
6-
// Do NOT manually modify the code between begin and end!
7-
// It's synced by scripts/sync_code.py.
84
// sync begin
95

6+
use super::*;
107
use crate::{
11-
Mcu, Steal,
12-
afio::{RemapMode, uart_remap::*},
13-
common::{uart::*, wrap_trait::*},
14-
pac,
8+
Mcu, pac,
159
rcc::{BusClock, Enable, Reset},
1610
};
1711

18-
// Initialization interface ------------------------------------------------------
19-
20-
macro_rules! impl_uart_init {
21-
($($reg:ty),+) => {$(
22-
impl UartInit<$reg> for $reg {
23-
fn constrain(self) -> Uart<$reg> {
24-
Uart { reg: self }
25-
}
26-
}
27-
)+};
28-
}
29-
pub(crate) use impl_uart_init;
30-
31-
pub trait UartInit<REG: RegisterBlock> {
32-
fn constrain(self) -> Uart<REG>;
33-
}
34-
3512
// Initialization -------------------------------------------------------------
3613

37-
// Use a wrapper to avoid conflicting implementations of trait
38-
pub struct Uart<REG: RegisterBlock> {
39-
reg: REG,
40-
}
41-
42-
#[allow(unused_variables)]
43-
impl<REG: RegisterBlock + Steal> Uart<REG> {
44-
fn steal(&self) -> Self {
45-
Self {
46-
reg: unsafe { self.reg.steal() },
47-
}
48-
}
49-
50-
pub fn into_tx_rx<REMAP: RemapMode<REG>>(
51-
mut self,
52-
pins: (Option<impl UartTxPin<REMAP>>, Option<impl UartRxPin<REMAP>>),
53-
config: Config,
54-
mcu: &mut Mcu,
55-
) -> (Option<Tx<Self>>, Option<Rx<Self>>) {
56-
REMAP::remap(&mut mcu.afio);
57-
self.config(config, mcu);
58-
self.enable_comm(pins.0.is_some(), pins.1.is_some());
59-
(
60-
pins.0.map(|_| Tx::new([self.steal(), self.steal()])),
61-
pins.1.map(|_| Rx::new([self.steal(), self.steal()])),
62-
)
63-
}
64-
65-
pub fn get_idle_interrupt_handler(&self) -> UartIdleInterrupt<Self> {
66-
UartIdleInterrupt::new(self.steal())
14+
impl UartInit<UartX> for UartX {
15+
fn constrain(self) -> Uart<UartX> {
16+
Uart { uart: self }
6717
}
18+
}
6819

20+
impl UartPeriphExt for UartX {
6921
fn config(&mut self, config: Config, mcu: &mut Mcu) {
70-
REG::enable(&mut mcu.rcc);
71-
REG::reset(&mut mcu.rcc);
22+
UartX::enable(&mut mcu.rcc);
23+
UartX::reset(&mut mcu.rcc);
7224

7325
// Configure baud rate
74-
let brr = REG::clock(&mcu.rcc.clocks).raw() / config.baudrate;
26+
let brr = UartX::clock(&mcu.rcc.clocks).raw() / config.baudrate;
7527
assert!(brr >= 16, "impossible baud rate");
76-
self.reg.brr().write(|w| unsafe { w.bits(brr as u16) });
28+
self.brr().write(|w| unsafe { w.bits(brr as u16) });
7729

7830
// Configure word
79-
self.reg.cr1().modify(|_, w| {
31+
self.cr1().modify(|_, w| {
8032
w.m().bit(match config.word_length {
8133
WordLength::Bits8 => false,
8234
WordLength::Bits9 => true,
@@ -97,71 +49,69 @@ impl<REG: RegisterBlock + Steal> Uart<REG> {
9749
// UE: enable USART
9850
// TE: enable transceiver
9951
// RE: enable receiver
100-
self.reg.cr1().modify(|_, w| {
52+
self.cr1().modify(|_, w| {
10153
w.ue().set_bit();
10254
w.te().bit(tx);
10355
w.re().bit(rx);
10456
w
10557
});
10658
}
10759

108-
// sync stop_bits_uart4
109-
11060
fn set_stop_bits(&mut self, bits: StopBits) {
61+
// sync stop_bits_u4
11162
use pac::uart4::cr2::STOP;
11263

11364
// StopBits::STOP0P5 and StopBits::STOP1P5 aren't supported when using UART
11465
// STOP_A::STOP1 and STOP_A::STOP2 will be used, respectively
115-
self.reg.cr2().write(|w| {
66+
self.cr2().write(|w| {
11667
w.stop().variant(match bits {
11768
StopBits::STOP0P5 | StopBits::STOP1 => STOP::Stop1,
11869
StopBits::STOP1P5 | StopBits::STOP2 => STOP::Stop2,
11970
})
12071
});
72+
// sync stop_bits_u4_end
12173
}
12274
}
12375

124-
// sync periph
125-
12676
// Implement Peripheral -------------------------------------------------------
12777

128-
impl<REG: RegisterBlock> UartPeriph for Uart<REG> {
78+
impl UartPeriph for UartX {
12979
#[inline]
13080
fn set_dma_tx(&mut self, enable: bool) {
131-
self.reg.cr3().modify(|_, w| w.dmat().bit(enable));
81+
self.cr3().modify(|_, w| w.dmat().bit(enable));
13282
}
13383

13484
#[inline]
13585
fn set_dma_rx(&mut self, enable: bool) {
136-
self.reg.cr3().modify(|_, w| w.dmar().bit(enable));
86+
self.cr3().modify(|_, w| w.dmar().bit(enable));
13787
}
13888

13989
#[inline]
14090
fn is_tx_empty(&self) -> bool {
141-
self.reg.sr().read().txe().bit_is_set()
91+
self.sr().read().txe().bit_is_set()
14292
}
14393

14494
#[inline]
14595
fn is_tx_complete(&self) -> bool {
146-
self.reg.sr().read().tc().bit_is_set()
96+
self.sr().read().tc().bit_is_set()
14797
}
14898

14999
fn write(&mut self, word: u16) -> nb::Result<(), Error> {
150100
if self.is_tx_empty() {
151-
self.reg.dr().write(|w| unsafe { w.dr().bits(word.into()) });
101+
self.dr().write(|w| unsafe { w.dr().bits(word.into()) });
152102
Ok(())
153103
} else {
154104
Err(nb::Error::WouldBlock)
155105
}
156106
}
157107

158108
fn read(&mut self) -> nb::Result<u16, Error> {
159-
let sr = self.reg.sr().read();
109+
let sr = self.sr().read();
160110

161111
// Check if a byte is available
162112
if sr.rxne().bit_is_set() {
163113
// Read the received byte
164-
return Ok(self.reg.dr().read().dr().bits());
114+
return Ok(self.dr().read().dr().bits());
165115
}
166116

167117
// Check for any errors
@@ -187,32 +137,32 @@ impl<REG: RegisterBlock> UartPeriph for Uart<REG> {
187137

188138
#[inline]
189139
fn get_tx_data_reg_addr(&self) -> u32 {
190-
&self.reg.dr() as *const _ as u32
140+
&self.dr() as *const _ as u32
191141
}
192142

193143
#[inline]
194144
fn get_rx_data_reg_addr(&self) -> u32 {
195-
&self.reg.dr() as *const _ as u32
145+
&self.dr() as *const _ as u32
196146
}
197147

198148
#[inline]
199149
fn set_interrupt(&mut self, event: UartEvent, enable: bool) {
200150
match event {
201151
UartEvent::Idle => {
202-
self.reg.cr1().modify(|_, w| w.idleie().bit(enable));
152+
self.cr1().modify(|_, w| w.idleie().bit(enable));
203153
}
204154
UartEvent::RxNotEmpty => {
205-
self.reg.cr1().modify(|_, w| w.rxneie().bit(enable));
155+
self.cr1().modify(|_, w| w.rxneie().bit(enable));
206156
}
207157
UartEvent::TxEmpty => {
208-
self.reg.cr1().modify(|_, w| w.txeie().bit(enable));
158+
self.cr1().modify(|_, w| w.txeie().bit(enable));
209159
}
210160
}
211161
}
212162

213163
#[inline]
214164
fn is_interrupt_enable(&mut self, event: UartEvent) -> bool {
215-
let cr1 = self.reg.cr1().read();
165+
let cr1 = self.cr1().read();
216166
match event {
217167
UartEvent::Idle => cr1.idleie().bit_is_set(),
218168
UartEvent::RxNotEmpty => cr1.rxneie().bit_is_set(),
@@ -222,23 +172,23 @@ impl<REG: RegisterBlock> UartPeriph for Uart<REG> {
222172

223173
#[inline]
224174
fn is_interrupted(&mut self, event: UartEvent) -> bool {
225-
let sr = self.reg.sr().read();
175+
let sr = self.sr().read();
226176
match event {
227177
UartEvent::Idle => {
228-
if sr.idle().bit_is_set() && self.reg.cr1().read().idleie().bit_is_set() {
178+
if sr.idle().bit_is_set() && self.cr1().read().idleie().bit_is_set() {
229179
self.clear_err_flag();
230180
return true;
231181
}
232182
}
233183
UartEvent::RxNotEmpty => {
234184
if (sr.rxne().bit_is_set() || sr.ore().bit_is_set())
235-
&& self.reg.cr1().read().rxneie().bit_is_set()
185+
&& self.cr1().read().rxneie().bit_is_set()
236186
{
237187
return true;
238188
}
239189
}
240190
UartEvent::TxEmpty => {
241-
if sr.txe().bit_is_set() && self.reg.cr1().read().txeie().bit_is_set() {
191+
if sr.txe().bit_is_set() && self.cr1().read().txeie().bit_is_set() {
242192
return true;
243193
}
244194
}
@@ -250,28 +200,14 @@ impl<REG: RegisterBlock> UartPeriph for Uart<REG> {
250200
/// followed by a read from the dr register.
251201
#[inline]
252202
fn clear_err_flag(&self) {
253-
let _ = self.reg.sr().read();
254-
let _ = self.reg.dr().read();
203+
let _ = self.sr().read();
204+
let _ = self.dr().read();
255205
}
256206

257207
#[inline]
258208
fn is_rx_not_empty(&self) -> bool {
259-
self.reg.sr().read().rxne().bit_is_set()
209+
self.sr().read().rxne().bit_is_set()
260210
}
261211
}
262212

263213
// sync end
264-
265-
impl_uart_init!(pac::UART4, pac::UART5);
266-
wrap_trait_deref!(
267-
(pac::UART4, pac::UART5,),
268-
pub(super) trait RegisterBlock: BusClock + Enable + Reset {
269-
fn cr1(&self) -> &uart4::CR1;
270-
fn dr(&self) -> &uart4::DR;
271-
fn brr(&self) -> &uart4::BRR;
272-
fn sr(&self) -> &uart4::SR;
273-
fn cr2(&self) -> &uart4::CR2;
274-
fn cr3(&self) -> &uart4::CR3;
275-
fn gtpr(&self) -> &uart4::GTPR;
276-
}
277-
);

0 commit comments

Comments
 (0)