Skip to content

Commit 2b39577

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 9dfb6c5 commit 2b39577

File tree

1 file changed

+67
-48
lines changed

1 file changed

+67
-48
lines changed

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)