Skip to content

Commit c207345

Browse files
authored
Merge pull request #509 from stm32-rs/rmp
Serial/SPI/I2C/CAN split pin enums
2 parents a80627a + df14c88 commit c207345

File tree

9 files changed

+339
-189
lines changed

9 files changed

+339
-189
lines changed

CHANGELOG.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
- Relax pin type generics for `Serial`, `I2c`, `Spi`, `Can`. [#462]
1313
Use enums of pin tuples and `Enum::from<(tuple)>` for pin remap before passing to peripheral.
14-
Remove `RemapStruct`s. [#462] [#506]
14+
Remove `RemapStruct`s. [#462] [#506] [#509]
1515
- Use independent `Spi` and `SpiSlave` structures instead of `OP` generic [#462]
1616
- Take `&Clocks` instead of `Clocks` [#498]
1717
- Temporary replace `stm32f1` with `stm32f1-staging` [#503]
@@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2626
- Check "device selected" in `build.rs` [#502]
2727
- Use gpio field enums internally [#506]
2828
- Unmacro `dma.rs` [#505]
29+
- Rework USART remap,
2930

3031
### Added
3132

@@ -37,6 +38,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3738
- Add DAC [#483]
3839
- Add an option to allow overclocking [#494]
3940
- `new` on gpio mode [#506]
41+
- Add `Serial` `rx`/`tx` constructors [#509]
4042

4143
[#416]: https://github.com/stm32-rs/stm32f1xx-hal/pull/416
4244
[#453]: https://github.com/stm32-rs/stm32f1xx-hal/pull/453
@@ -54,6 +56,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
5456
[#503]: https://github.com/stm32-rs/stm32f1xx-hal/pull/503
5557
[#505]: https://github.com/stm32-rs/stm32f1xx-hal/pull/505
5658
[#506]: https://github.com/stm32-rs/stm32f1xx-hal/pull/506
59+
[#509]: https://github.com/stm32-rs/stm32f1xx-hal/pull/509
5760

5861
## [v0.10.0] - 2022-12-12
5962

examples/serial_config.rs

+4-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
//! Serial interface loopback test
2-
//!
3-
//! You have to short the TX and RX pins to make this program work
1+
//! Serial Config test
42
53
#![deny(unsafe_code)]
64
#![allow(clippy::empty_loop)]
@@ -40,27 +38,22 @@ fn main() -> ! {
4038

4139
// USART1
4240
// let tx = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh);
43-
// let rx = gpioa.pa10;
4441

4542
// USART1
4643
// let tx = gpiob.pb6.into_alternate_push_pull(&mut gpiob.crl);
47-
// let rx = gpiob.pb7;
4844

4945
// USART2
5046
// let tx = gpioa.pa2.into_alternate_push_pull(&mut gpioa.crl);
51-
// let rx = gpioa.pa3;
5247

5348
// USART3
5449
// Configure pb10 as a push_pull output, this will be the tx pin
5550
let tx = gpiob.pb10.into_alternate_push_pull(&mut gpiob.crh);
56-
// Take ownership over pb11
57-
let rx = gpiob.pb11;
5851

59-
// Set up the usart device. Take ownership over the USART register and tx/rx pins. The rest of
52+
// Set up the usart device. Take ownership over the USART register and tx pin. The rest of
6053
// the registers are used to enable and configure the device.
61-
let serial = Serial::new(
54+
let mut tx = Serial::tx(
6255
p.USART3,
63-
(tx, rx, &mut afio.mapr),
56+
(tx, &mut afio.mapr),
6457
serial::Config::default()
6558
.baudrate(9600.bps())
6659
.stopbits(serial::StopBits::STOP2)
@@ -69,9 +62,6 @@ fn main() -> ! {
6962
&clocks,
7063
);
7164

72-
// Split the serial struct into a receiving and a transmitting part
73-
let (mut tx, _rx) = serial.split();
74-
7565
let sent = b'U';
7666
block!(tx.write_u8(sent)).unwrap();
7767
block!(tx.write_u8(sent)).unwrap();

examples/spi-slave.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ fn main() -> ! {
3838

3939
let mut afio = dp.AFIO.constrain();
4040
let gpioa = dp.GPIOA.split();
41-
let mut gpiob = dp.GPIOB.split();
41+
let gpiob = dp.GPIOB.split();
4242

4343
// SPI1
4444
// Convert pins during SPI initialization
@@ -53,7 +53,7 @@ fn main() -> ! {
5353
// SPI2
5454
// Convert pins before SPI initialization
5555
let sck = gpiob.pb13;
56-
let miso = gpiob.pb14.into_alternate_push_pull(&mut gpiob.crh);
56+
let miso = gpiob.pb14;
5757
let mosi = gpiob.pb15;
5858

5959
let spi2 = dp.SPI2.spi_slave((sck, miso, mosi), MODE);

src/can.rs

+53-38
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,39 @@
2020
//! | RX | PB5 | PB12 |
2121
2222
use crate::afio::MAPR;
23-
use crate::gpio::{self, Alternate, Cr, Floating, Input, PinMode, PullUp};
23+
use crate::gpio::{self, Alternate, Cr, Floating, Input, NoPin, PinMode, PullUp, PushPull};
2424
use crate::pac::{self, RCC};
2525

2626
pub trait InMode {}
2727
impl InMode for Floating {}
2828
impl InMode for PullUp {}
2929

30+
pub struct Pins<TX, RX> {
31+
pub tx: TX,
32+
pub rx: RX,
33+
}
34+
35+
impl<TX, RX> From<(TX, RX)> for Pins<TX, RX> {
36+
fn from(value: (TX, RX)) -> Self {
37+
Self {
38+
tx: value.0,
39+
rx: value.1,
40+
}
41+
}
42+
}
43+
3044
pub mod can1 {
3145
use super::*;
3246

3347
remap! {
34-
Pins: [
35-
#[cfg(not(feature = "connectivity"))]
36-
All, Tx, Rx, PA12, PA11 => { |_, w| unsafe { w.can_remap().bits(0) } };
37-
#[cfg(feature = "connectivity")]
38-
All, Tx, Rx, PA12, PA11 => { |_, w| unsafe { w.can1_remap().bits(0) } };
39-
#[cfg(not(feature = "connectivity"))]
40-
Remap, RemapTx, RemapRx, PB9, PB8 => { |_, w| unsafe { w.can_remap().bits(10) } };
41-
#[cfg(feature = "connectivity")]
42-
Remap, RemapTx, RemapRx, PB9, PB8 => { |_, w| unsafe { w.can1_remap().bits(10) } };
43-
]
48+
#[cfg(not(feature = "connectivity"))]
49+
PA12, PA11 => { |_, w| unsafe { w.can_remap().bits(0) } };
50+
#[cfg(feature = "connectivity")]
51+
PA12, PA11 => { |_, w| unsafe { w.can1_remap().bits(0) } };
52+
#[cfg(not(feature = "connectivity"))]
53+
PB9, PB8 => { |_, w| unsafe { w.can_remap().bits(10) } };
54+
#[cfg(feature = "connectivity")]
55+
PB9, PB8 => { |_, w| unsafe { w.can1_remap().bits(10) } };
4456
}
4557
}
4658

@@ -49,39 +61,39 @@ pub mod can2 {
4961
use super::*;
5062

5163
remap! {
52-
Pins: [
53-
All, Tx, Rx, PB6, PB5 => { |_, w| w.can2_remap().bit(false) };
54-
Remap, RemapTx, RemapRx, PB13, PB12 => { |_, w| w.can2_remap().bit(true) };
55-
]
64+
PB6, PB5 => { |_, w| w.can2_remap().bit(false) };
65+
PB13, PB12 => { |_, w| w.can2_remap().bit(true) };
5666
}
5767
}
5868

5969
macro_rules! remap {
60-
($name:ident: [
61-
$($(#[$attr:meta])* $rname:ident, $txonly:ident, $rxonly:ident, $TX:ident, $RX:ident => { $remapex:expr };)+
62-
]) => {
63-
pub enum $name<PULL> {
70+
($($(#[$attr:meta])* $TX:ident, $RX:ident => { $remapex:expr };)+) => {
71+
pub enum Tx {
6472
$(
6573
$(#[$attr])*
66-
$rname { tx: gpio::$TX<Alternate>, rx: gpio::$RX<Input<PULL>> },
67-
$(#[$attr])*
68-
$txonly { tx: gpio::$TX<Alternate> },
74+
$TX(gpio::$TX<Alternate>),
75+
)+
76+
None(NoPin<PushPull>),
77+
}
78+
pub enum Rx<PULL> {
79+
$(
6980
$(#[$attr])*
70-
$rxonly { rx: gpio::$RX<Input<PULL>> },
81+
$RX(gpio::$RX<Input<PULL>>),
7182
)+
83+
None(NoPin<PULL>),
7284
}
7385

7486
$(
7587
$(#[$attr])*
76-
impl<PULL: InMode> From<(gpio::$TX<Alternate>, gpio::$RX<Input<PULL>>, &mut MAPR)> for $name<PULL> {
88+
impl<PULL: InMode> From<(gpio::$TX<Alternate>, gpio::$RX<Input<PULL>>, &mut MAPR)> for Pins<Tx, Rx<PULL>> {
7789
fn from(p: (gpio::$TX<Alternate>, gpio::$RX<Input<PULL>>, &mut MAPR)) -> Self {
7890
p.2.modify_mapr($remapex);
79-
Self::$rname { tx: p.0, rx: p.1 }
91+
Self { tx: Tx::$TX(p.0), rx: Rx::$RX(p.1) }
8092
}
8193
}
8294

8395
$(#[$attr])*
84-
impl<PULL> From<(gpio::$TX, gpio::$RX, &mut MAPR)> for $name<PULL>
96+
impl<PULL> From<(gpio::$TX, gpio::$RX, &mut MAPR)> for Pins<Tx, Rx<PULL>>
8597
where
8698
Input<PULL>: PinMode,
8799
PULL: InMode,
@@ -91,29 +103,29 @@ macro_rules! remap {
91103
let tx = p.0.into_mode(&mut cr);
92104
let rx = p.1.into_mode(&mut cr);
93105
p.2.modify_mapr($remapex);
94-
Self::$rname { tx, rx }
106+
Self { tx: Tx::$TX(tx), rx: Rx::$RX(rx) }
95107
}
96108
}
97109

98110
$(#[$attr])*
99-
impl From<(gpio::$TX, &mut MAPR)> for $name<Floating> {
111+
impl From<(gpio::$TX, &mut MAPR)> for Pins<Tx, Rx<Floating>> {
100112
fn from(p: (gpio::$TX, &mut MAPR)) -> Self {
101113
let tx = p.0.into_mode(&mut Cr);
102114
p.1.modify_mapr($remapex);
103-
Self::$txonly { tx }
115+
Self { tx: Tx::$TX(tx), rx: Rx::None(NoPin::new()) }
104116
}
105117
}
106118

107119
$(#[$attr])*
108-
impl<PULL> From<(gpio::$RX, &mut MAPR)> for $name<PULL>
120+
impl<PULL> From<(gpio::$RX, &mut MAPR)> for Pins<Tx, Rx<PULL>>
109121
where
110122
Input<PULL>: PinMode,
111123
PULL: InMode,
112124
{
113125
fn from(p: (gpio::$RX, &mut MAPR)) -> Self {
114126
let rx = p.0.into_mode(&mut Cr);
115127
p.1.modify_mapr($remapex);
116-
Self::$rxonly { rx }
128+
Self { tx: Tx::None(NoPin::new()), rx: Rx::$RX(rx) }
117129
}
118130
}
119131
)+
@@ -125,7 +137,7 @@ pub trait CanExt: Sized + Instance {
125137
fn can(
126138
self,
127139
#[cfg(not(feature = "connectivity"))] usb: pac::USB,
128-
pins: impl Into<Self::Pins<Floating>>,
140+
pins: impl Into<Pins<Self::Tx, Self::Rx<Floating>>>,
129141
) -> Can<Self, Floating>;
130142
fn can_loopback(
131143
self,
@@ -137,7 +149,7 @@ impl<CAN: Instance> CanExt for CAN {
137149
fn can(
138150
self,
139151
#[cfg(not(feature = "connectivity"))] usb: pac::USB,
140-
pins: impl Into<Self::Pins<Floating>>,
152+
pins: impl Into<Pins<Self::Tx, Self::Rx<Floating>>>,
141153
) -> Can<Self, Floating> {
142154
Can::new(
143155
self,
@@ -159,21 +171,24 @@ impl<CAN: Instance> CanExt for CAN {
159171
}
160172

161173
pub trait Instance: crate::rcc::Enable {
162-
type Pins<PULL>;
174+
type Tx;
175+
type Rx<PULL>;
163176
}
164177
impl Instance for pac::CAN1 {
165-
type Pins<PULL> = can1::Pins<PULL>;
178+
type Tx = can1::Tx;
179+
type Rx<PULL> = can1::Rx<PULL>;
166180
}
167181
#[cfg(feature = "connectivity")]
168182
impl Instance for pac::CAN2 {
169-
type Pins<PULL> = can2::Pins<PULL>;
183+
type Tx = can2::Tx;
184+
type Rx<PULL> = can2::Rx<PULL>;
170185
}
171186

172187
/// Interface to the CAN peripheral.
173188
#[allow(unused)]
174189
pub struct Can<CAN: Instance, PULL = Floating> {
175190
can: CAN,
176-
pins: Option<CAN::Pins<PULL>>,
191+
pins: Option<Pins<CAN::Tx, CAN::Rx<PULL>>>,
177192
}
178193

179194
impl<CAN: Instance, PULL> Can<CAN, PULL> {
@@ -184,7 +199,7 @@ impl<CAN: Instance, PULL> Can<CAN, PULL> {
184199
pub fn new(
185200
can: CAN,
186201
#[cfg(not(feature = "connectivity"))] _usb: pac::USB,
187-
pins: impl Into<CAN::Pins<PULL>>,
202+
pins: impl Into<Pins<CAN::Tx, CAN::Rx<PULL>>>,
188203
) -> Can<CAN, PULL> {
189204
let rcc = unsafe { &(*RCC::ptr()) };
190205
CAN::enable(rcc);

src/gpio.rs

+8
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ pub trait GpioExt {
143143
unsafe fn split_without_reset(self) -> Self::Parts;
144144
}
145145

146+
#[derive(Debug, Default)]
147+
pub struct NoPin<MODE>(PhantomData<MODE>);
148+
impl<MODE> NoPin<MODE> {
149+
pub fn new() -> Self {
150+
Self(PhantomData)
151+
}
152+
}
153+
146154
/// Marker trait for active states.
147155
pub trait Active {}
148156

0 commit comments

Comments
 (0)