Skip to content

Commit 632955f

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 814059b commit 632955f

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::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;
@@ -144,44 +134,69 @@ impl Default for Config {
144134
}
145135
}
146136

147-
pub trait Pins<USART> {
137+
/// Trait to mark serial pins with transmit capability.
138+
pub trait TxPin<USART> {
139+
fn setup(&self);
140+
}
141+
142+
/// Trait to mark serial pins with receive capability.
143+
pub trait RxPin<USART> {
148144
fn setup(&self);
149145
}
150146

147+
/// Macro to implement `TxPin` / `RxPin` for a certain pin, using a certain
148+
/// alternative function and for a certain serial peripheral.
151149
macro_rules! impl_pins {
152-
($($instance:ty, $tx:ident, $rx:ident, $alt:ident;)*) => {
150+
($($pin:ident, $alt:ident, $instance:ty, $trait:ident;)*) => {
153151
$(
154-
impl<Tx, Rx> Pins<$instance> for ($tx<Tx>, $rx<Rx>) {
152+
impl<MODE> $trait<$instance> for $pin<MODE> {
155153
fn setup(&self) {
156-
self.0.set_alt_mode(AltMode::$alt);
157-
self.1.set_alt_mode(AltMode::$alt);
154+
self.set_alt_mode(AltMode::$alt);
158155
}
159156
}
160157
)*
161158
}
162159
}
163160

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

187202
/// Serial abstraction
@@ -206,30 +221,34 @@ macro_rules! usart {
206221
$USARTX:ident: ($usartX:ident, $apbXenr:ident, $usartXen:ident, $pclkX:ident, $SerialExt:ident),
207222
)+) => {
208223
$(
209-
pub trait $SerialExt<PINS> {
210-
fn usart(self, pins: PINS, config: Config, rcc: &mut Rcc) -> Result<Serial<$USARTX>, InvalidConfig>;
224+
pub trait $SerialExt<TX, RX> {
225+
fn usart(self, tx: TX, rx: RX, config: Config, rcc: &mut Rcc) -> Result<Serial<$USARTX>, InvalidConfig>;
211226
}
212227

213-
impl<PINS> $SerialExt<PINS> for $USARTX
228+
impl<TX, RX> $SerialExt<TX, RX> for $USARTX
214229
where
215-
PINS: Pins<$USARTX>,
230+
TX: TxPin<$USARTX>,
231+
RX: RxPin<$USARTX>,
216232
{
217-
fn usart(self, pins: PINS, config: Config, rcc: &mut Rcc) -> Result<Serial<$USARTX>, InvalidConfig> {
218-
Serial::$usartX(self, pins, config, rcc)
233+
fn usart(self, tx: TX, rx: RX, config: Config, rcc: &mut Rcc) -> Result<Serial<$USARTX>, InvalidConfig> {
234+
Serial::$usartX(self, tx, rx, config, rcc)
219235
}
220236
}
221237

222238
impl Serial<$USARTX> {
223-
pub fn $usartX<PINS>(
239+
pub fn $usartX<TX, RX>(
224240
usart: $USARTX,
225-
pins: PINS,
241+
tx: TX,
242+
rx: RX,
226243
config: Config,
227244
rcc: &mut Rcc,
228245
) -> Result<Self, InvalidConfig>
229246
where
230-
PINS: Pins<$USARTX>,
247+
TX: TxPin<$USARTX>,
248+
RX: RxPin<$USARTX>,
231249
{
232-
pins.setup();
250+
tx.setup();
251+
rx.setup();
233252

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

0 commit comments

Comments
 (0)