Skip to content

Commit d408ae7

Browse files
committed
Serial: Replace Pins trait with TxPin / RxPin
The previous approach with the `Pins` trait assumed that an USART peripheral can only be used with specific pin pairs. However, pins can be mixed, so you could use USART1 with PA9 and PB7. So instead of the `Pins` trait, there are now separate `TxPin` and `RxPin` traits. They are implemented for all pins of all U(S)ART peripherals of the stm32l0xx family. Pin mappings verified against datasheets of stm32l071kb, stm32l072vz and stm32l083vz.
1 parent 6700dbc commit d408ae7

File tree

5 files changed

+84
-68
lines changed

5 files changed

+84
-68
lines changed

examples/rtc.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ fn main() -> ! {
4545

4646
let serial = dp.USART2
4747
.usart(
48-
(gpioa.pa2, gpioa.pa3),
48+
gpioa.pa2,
49+
gpioa.pa3,
4950
serial::Config::default()
5051
.baudrate(115_200.bps()),
5152
&mut rcc,

examples/serial.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,14 @@ fn main() -> ! {
2222
// the RCC register.
2323
let gpioa = dp.GPIOA.split(&mut rcc);
2424

25-
#[cfg(feature = "stm32l0x1")]
26-
let tx_pin = gpioa.pa9;
27-
#[cfg(feature = "stm32l0x1")]
28-
let rx_pin = gpioa.pa10;
29-
30-
#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))]
31-
let tx_pin = gpioa.pa14;
32-
#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))]
33-
let rx_pin = gpioa.pa15;
25+
// Choose TX / RX pins
26+
let tx_pin = gpioa.pa2;
27+
let rx_pin = gpioa.pa3;
3428

3529
// Configure the serial peripheral.
3630
let serial = dp
3731
.USART2
38-
.usart((tx_pin, rx_pin), serial::Config::default(), &mut rcc)
32+
.usart(tx_pin, rx_pin, serial::Config::default(), &mut rcc)
3933
.unwrap();
4034

4135
let (mut tx, mut rx) = serial.split();

examples/serial_dma.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ fn main() -> ! {
4242
let (mut tx, mut rx) = dp
4343
.USART2
4444
.usart(
45-
(gpioa.pa2, gpioa.pa3),
45+
gpioa.pa2,
46+
gpioa.pa3,
4647
serial::Config::default().baudrate(115_200.bps()),
4748
&mut rcc,
4849
)

examples/serial_dma_async.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@ fn main() -> ! {
4646
let gpioa = dp.GPIOA.split(&mut rcc);
4747

4848
let (tx, rx) = dp
49-
.USART2
50-
.usart(
51-
(gpioa.pa2, gpioa.pa3),
52-
serial::Config::default().baudrate(115_200.bps()),
53-
&mut rcc,
54-
)
55-
.unwrap()
56-
.split();
49+
.USART2
50+
.usart(
51+
gpioa.pa2,
52+
gpioa.pa3,
53+
serial::Config::default().baudrate(115_200.bps()),
54+
&mut rcc,
55+
)
56+
.unwrap()
57+
.split();
5758

5859
// we only have two elements for each queue, so U2 is fine (size is max 2)
5960
let mut rx_buffers: Queue<Pin<DmaBuffer>, U2> = Queue::new();

src/serial.rs

Lines changed: 67 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,14 @@ use core::fmt;
22
use core::marker::PhantomData;
33
use core::ptr;
44

5-
use crate::gpio::gpioa::*;
5+
use crate::gpio::{gpioa::*, gpiob::*, gpioc::*, gpiod::*, gpioe::*};
66
use crate::gpio::{PinMode, AltMode};
77
use crate::hal;
88
use crate::hal::prelude::*;
9-
pub use crate::pac::USART2;
9+
pub use crate::pac::{LPUART1, USART1, USART2, USART4, USART5};
1010
use crate::rcc::Rcc;
1111
use nb::block;
1212

13-
#[cfg(feature = "stm32l0x1")]
14-
pub use crate::pac::LPUART1;
15-
1613
#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))]
1714
use core::{
1815
ops::{Deref, DerefMut},
@@ -23,14 +20,7 @@ use core::{
2320
use as_slice::{AsMutSlice, AsSlice};
2421

2522
#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))]
26-
pub use crate::{
27-
dma,
28-
gpio::gpiob::*,
29-
gpio::gpioc::*,
30-
gpio::gpiod::*,
31-
gpio::gpioe::*,
32-
pac::{LPUART1, USART1, USART4, USART5},
33-
};
23+
pub use crate::dma;
3424

3525
#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))]
3626
use dma::Buffer;
@@ -152,44 +142,69 @@ impl Default for Config {
152142
}
153143
}
154144

155-
pub trait Pins<USART> {
145+
/// Trait to mark serial pins with transmit capability.
146+
pub trait TxPin<USART> {
147+
fn setup(&self);
148+
}
149+
150+
/// Trait to mark serial pins with receive capability.
151+
pub trait RxPin<USART> {
156152
fn setup(&self);
157153
}
158154

155+
/// Macro to implement `TxPin` / `RxPin` for a certain pin, using a certain
156+
/// alternative function and for a certain serial peripheral.
159157
macro_rules! impl_pins {
160-
($($instance:ty, $tx:ident, $rx:ident, $alt:ident;)*) => {
158+
($($pin:ident, $alt:ident, $instance:ty, $trait:ident;)*) => {
161159
$(
162-
impl<Tx: PinMode, Rx: PinMode> Pins<$instance> for ($tx<Tx>, $rx<Rx>) {
160+
impl<MODE: PinMode> $trait<$instance> for $pin<MODE> {
163161
fn setup(&self) {
164-
self.0.set_alt_mode(AltMode::$alt);
165-
self.1.set_alt_mode(AltMode::$alt);
162+
self.set_alt_mode(AltMode::$alt);
166163
}
167164
}
168165
)*
169166
}
170167
}
171168

172-
#[cfg(feature = "stm32l0x1")]
173-
impl_pins!(
174-
LPUART1, PA2, PA3, AF6;
175-
USART2, PA9, PA10, AF4;
176-
);
177-
178-
#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))]
179169
impl_pins!(
180-
LPUART1, PA2, PA3, AF6;
181-
LPUART1, PB10, PB11, AF4;
182-
LPUART1, PB11, PB10, AF7;
183-
USART1, PA9, PA10, AF4;
184-
USART1, PB6, PB7, AF0;
185-
USART2, PA2, PA3, AF4;
186-
USART2, PA14, PA15, AF4;
187-
USART2, PD5, PD6, AF0;
188-
USART4, PA0, PA1, AF6;
189-
USART4, PC10, PC11, AF6;
190-
USART4, PE8, PE9, AF6;
191-
USART5, PB3, PB4, AF6;
192-
USART5, PE10, PE11, AF6;
170+
PA0, AF6, USART4, TxPin;
171+
PA1, AF6, USART4, RxPin;
172+
PA2, AF4, USART2, TxPin;
173+
PA2, AF6, LPUART1, TxPin;
174+
PA3, AF4, USART2, RxPin;
175+
PA3, AF6, LPUART1, RxPin;
176+
PA9, AF4, USART1, TxPin;
177+
PA10, AF4, USART1, RxPin;
178+
PA13, AF6, LPUART1, RxPin;
179+
PA14, AF4, USART2, TxPin;
180+
PA14, AF6, LPUART1, TxPin;
181+
PA15, AF4, USART2, RxPin;
182+
PB3, AF6, USART5, TxPin;
183+
PB4, AF6, USART5, RxPin;
184+
PB6, AF0, USART1, TxPin;
185+
PB7, AF0, USART1, RxPin;
186+
PB10, AF4, LPUART1, TxPin;
187+
PB10, AF7, LPUART1, RxPin;
188+
PB11, AF4, LPUART1, RxPin;
189+
PB11, AF7, LPUART1, TxPin;
190+
PC0, AF6, LPUART1, RxPin;
191+
PC1, AF6, LPUART1, TxPin;
192+
PC4, AF2, LPUART1, TxPin;
193+
PC5, AF2, LPUART1, RxPin;
194+
PC10, AF0, LPUART1, TxPin;
195+
PC10, AF6, USART4, TxPin;
196+
PC11, AF0, LPUART1, RxPin;
197+
PC11, AF6, USART4, RxPin;
198+
PC12, AF2, USART5, TxPin;
199+
PD2, AF6, USART5, RxPin;
200+
PD5, AF0, USART2, TxPin;
201+
PD6, AF0, USART2, RxPin;
202+
PD8, AF0, LPUART1, TxPin;
203+
PD9, AF0, LPUART1, RxPin;
204+
PE8, AF6, USART4, TxPin;
205+
PE9, AF6, USART4, RxPin;
206+
PE10, AF6, USART5, TxPin;
207+
PE11, AF6, USART5, RxPin;
193208
);
194209

195210
/// Serial abstraction
@@ -214,30 +229,34 @@ macro_rules! usart {
214229
$USARTX:ident: ($usartX:ident, $apbXenr:ident, $usartXen:ident, $pclkX:ident, $SerialExt:ident),
215230
)+) => {
216231
$(
217-
pub trait $SerialExt<PINS> {
218-
fn usart(self, pins: PINS, config: Config, rcc: &mut Rcc) -> Result<Serial<$USARTX>, InvalidConfig>;
232+
pub trait $SerialExt<TX, RX> {
233+
fn usart(self, tx: TX, rx: RX, config: Config, rcc: &mut Rcc) -> Result<Serial<$USARTX>, InvalidConfig>;
219234
}
220235

221-
impl<PINS> $SerialExt<PINS> for $USARTX
236+
impl<TX, RX> $SerialExt<TX, RX> for $USARTX
222237
where
223-
PINS: Pins<$USARTX>,
238+
TX: TxPin<$USARTX>,
239+
RX: RxPin<$USARTX>,
224240
{
225-
fn usart(self, pins: PINS, config: Config, rcc: &mut Rcc) -> Result<Serial<$USARTX>, InvalidConfig> {
226-
Serial::$usartX(self, pins, config, rcc)
241+
fn usart(self, tx: TX, rx: RX, config: Config, rcc: &mut Rcc) -> Result<Serial<$USARTX>, InvalidConfig> {
242+
Serial::$usartX(self, tx, rx, config, rcc)
227243
}
228244
}
229245

230246
impl Serial<$USARTX> {
231-
pub fn $usartX<PINS>(
247+
pub fn $usartX<TX, RX>(
232248
usart: $USARTX,
233-
pins: PINS,
249+
tx: TX,
250+
rx: RX,
234251
config: Config,
235252
rcc: &mut Rcc,
236253
) -> Result<Self, InvalidConfig>
237254
where
238-
PINS: Pins<$USARTX>,
255+
TX: TxPin<$USARTX>,
256+
RX: RxPin<$USARTX>,
239257
{
240-
pins.setup();
258+
tx.setup();
259+
rx.setup();
241260

242261
// Enable clock for USART
243262
rcc.rb.$apbXenr.modify(|_, w| w.$usartXen().set_bit());

0 commit comments

Comments
 (0)