Skip to content

Commit 231c959

Browse files
authored
Merge pull request #189 from Piroro-hs/gpio-collapse
GPIO refactor (Simplify macro, reduce type states, and support interrupt)
2 parents f8eb292 + 3dc5239 commit 231c959

21 files changed

+1994
-1484
lines changed

CHANGELOG.md

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,34 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10-
## [v0.7.0] - 2021-03-10
11-
1210
### Added
1311

14-
- Replace custom time based units with types defined in the [embedded-time][] crate ([#192])
1512
- Make `Clocks` `ppre1()` and `ppre2()` methods public, to get the current
1613
Prescaler value. ([#210])
14+
- Implement `into_xxx` methods for partially erased pins ([#189])
15+
- Enable better GPIO internal resistor configuration ([#189])
16+
- Support for GPIO output slew rate configuration ([#189])
17+
- Support for GPIO interrupts ([#189])
1718

18-
### Breaking changes
19+
### Changed
1920

21+
- Added support for more CAN bit rates and modes. ([#186])
22+
- The structure of `gpio.rs` is greatly changed. Generic `Pin` struct is used
23+
for every GPIO pin now ([#189])
24+
25+
### Fixed
26+
27+
- Delay based on systick no longer panics ([#203]) for to high values
28+
and support longer delays ([#208])
29+
30+
### Breaking Changes
31+
32+
- Replace custom time based units with types defined in the [embedded-time][]
33+
crate ([#192])
2034
- The `rcc` public API now expects time based units in `Megahertz`.
2135
If the supplied frequency cannot be converted to `Hertz` the code
2236
will `panic`. This will occur if the supplied `Megahertz` frequency
23-
cannot fit into `u32::MAX` when converting to `Hertz`
37+
cannot fit into `u32::MAX` when converting to `Hertz` ([#192])
2438

2539
```rust
2640
// The supplied frequencies must be in `MHz`.
@@ -34,21 +48,17 @@ let clocks = rcc
3448
```
3549

3650
- Bump dependencies: ([#211])
37-
- `stm32f3` dependency to 0.13.0
38-
- `nb` to 1.0
51+
- `stm32f3` dependency to 0.13
52+
- `nb` to 1
3953
- `cortex-m` to 0.7
4054
- `stm32-usbd` to 0.6
4155
- `defmt` to 0.2
42-
43-
[embedded-time]: https://github.com/FluenTech/embedded-time/
44-
### Changed
45-
46-
- Added support for more CAN bit rates and modes. ([#186])
47-
48-
### Fixed
49-
50-
- Delay based on systick no longer panics ([#203]) for to high values
51-
and support longer delays ([#208])
56+
- `into_afx` methods are splitted into `into_afx_push_pull` and
57+
`into_afx_open_drain` ([#189])
58+
- GPIO output mode (`PushPull` or `OpenDrain`) is encoded into pin typestate
59+
in alternate function mode ([#189])
60+
- GPIO internal resistor configuration is no longer encoded into pin typestate
61+
in input mode ([#189])
5262

5363
## [v0.6.1] - 2020-12-10
5464

@@ -69,8 +79,7 @@ let clocks = rcc
6979
- Impls for all SPI pins for all `stm32f302` sub-targets, `stm32f303`
7080
subtargets, `stm32f3x8` targets, `stm32f334`, and `stm32f373`
7181
([#99])
72-
- SPI4 peripheral for supported
73-
devices. ([#99])
82+
- SPI4 peripheral for supported devices. ([#99])
7483
- Support for I2C transfer of more than 255 bytes, and 0 byte write ([#154])
7584
- Support for HSE bypass and CSS ([#156])
7685
- Impls for missing I2C pin definitions ([#164])
@@ -85,9 +94,6 @@ let clocks = rcc
8594
The support of this feature is subject to change as the development
8695
of [defmt][] is advancing.
8796

88-
[defmt]: https://github.com/knurling-rs/defmt
89-
[filter]: https://defmt.ferrous-systems.com/filtering.html
90-
9197
### Changed
9298

9399
- Introduced auto-generated GPIO mappings based on the STM32CubeMX database
@@ -99,8 +105,6 @@ let clocks = rcc
99105
([#152])
100106
- Wrong I2C clock source ([#164])
101107

102-
[#151]: https://github.com/stm32-rs/stm32f3xx-hal/issues/151
103-
104108
### Breaking Changes
105109

106110
- Removed impl for `SckPin<SPI2>` for `PB13<AF5>` from `stm32f328` and
@@ -305,20 +309,21 @@ let clocks = rcc
305309

306310
- Support `stm32f303` device
307311

312+
[embedded-time]: https://github.com/FluenTech/embedded-time/
313+
[defmt]: https://github.com/knurling-rs/defmt
314+
[filter]: https://defmt.ferrous-systems.com/filtering.html
315+
308316
[#211]: https://github.com/stm32-rs/stm32f3xx-hal/pull/211
309317
[#210]: https://github.com/stm32-rs/stm32f3xx-hal/pull/210
310318
[#208]: https://github.com/stm32-rs/stm32f3xx-hal/pull/208
311319
[#203]: https://github.com/stm32-rs/stm32f3xx-hal/issues/203
312320
[#192]: https://github.com/stm32-rs/stm32f3xx-hal/pull/192
321+
[#189]: https://github.com/stm32-rs/stm32f3xx-hal/pull/189
313322
[#186]: https://github.com/stm32-rs/stm32f3xx-hal/pull/186
314323
[#184]: https://github.com/stm32-rs/stm32f3xx-hal/pull/184
315324
[#172]: https://github.com/stm32-rs/stm32f3xx-hal/pull/172
316325
[#170]: https://github.com/stm32-rs/stm32f3xx-hal/pull/170
317326
[#164]: https://github.com/stm32-rs/stm32f3xx-hal/pull/164
318-
[#164]: https://github.com/stm32-rs/stm32f3xx-hal/pull/164
319-
[#164]: https://github.com/stm32-rs/stm32f3xx-hal/pull/164
320-
[#164]: https://github.com/stm32-rs/stm32f3xx-hal/pull/164
321-
[#164]: https://github.com/stm32-rs/stm32f3xx-hal/pull/164
322327
[#156]: https://github.com/stm32-rs/stm32f3xx-hal/pull/156
323328
[#154]: https://github.com/stm32-rs/stm32f3xx-hal/pull/154
324329
[#152]: https://github.com/stm32-rs/stm32f3xx-hal/pull/152
@@ -333,30 +338,24 @@ let clocks = rcc
333338
[#101]: https://github.com/stm32-rs/stm32f3xx-hal/pull/101
334339
[#100]: https://github.com/stm32-rs/stm32f3xx-hal/pull/100
335340
[#99]: https://github.com/stm32-rs/stm32f3xx-hal/pull/99
336-
[#99]: https://github.com/stm32-rs/stm32f3xx-hal/pull/99
337-
[#99]: https://github.com/stm32-rs/stm32f3xx-hal/pull/99
338341
[#98]: https://github.com/stm32-rs/stm32f3xx-hal/pull/98
339342
[#97]: https://github.com/stm32-rs/stm32f3xx-hal/pull/97
340343
[#91]: https://github.com/stm32-rs/stm32f3xx-hal/pull/91
341344
[#86]: https://github.com/stm32-rs/stm32f3xx-hal/pull/86
342-
[#86]: https://github.com/stm32-rs/stm32f3xx-hal/pull/86
343345
[#82]: https://github.com/stm32-rs/stm32f3xx-hal/pull/82
344346
[#75]: https://github.com/stm32-rs/stm32f3xx-hal/pull/75
345347
[#72]: https://github.com/stm32-rs/stm32f3xx-hal/pull/72
346348
[#70]: https://github.com/stm32-rs/stm32f3xx-hal/pull/70
347349
[#67]: https://github.com/stm32-rs/stm32f3xx-hal/pull/67
348-
[#67]: https://github.com/stm32-rs/stm32f3xx-hal/pull/67
349350
[#60]: https://github.com/stm32-rs/stm32f3xx-hal/pull/60
350351
[#58]: https://github.com/stm32-rs/stm32f3xx-hal/pull/58
351352
[#56]: https://github.com/stm32-rs/stm32f3xx-hal/pull/56
352353
[#52]: https://github.com/stm32-rs/stm32f3xx-hal/pull/52
353354
[#50]: https://github.com/stm32-rs/stm32f3xx-hal/pull/50
354-
[#50]: https://github.com/stm32-rs/stm32f3xx-hal/pull/50
355355
[#47]: https://github.com/stm32-rs/stm32f3xx-hal/pull/47
356356
[#42]: https://github.com/stm32-rs/stm32f3xx-hal/pull/42
357357
[#39]: https://github.com/stm32-rs/stm32f3xx-hal/pull/39
358358
[#35]: https://github.com/stm32-rs/stm32f3xx-hal/pull/18
359-
[#35]: https://github.com/stm32-rs/stm32f3xx-hal/pull/35
360359
[#34]: https://github.com/stm32-rs/stm32f3xx-hal/pull/34
361360
[#33]: https://github.com/stm32-rs/stm32f3xx-hal/pull/33
362361
[#31]: https://github.com/stm32-rs/stm32f3xx-hal/pull/33
@@ -369,7 +368,6 @@ let clocks = rcc
369368
[#16]: https://github.com/stm32-rs/stm32f3xx-hal/pull/16
370369
[#14]: https://github.com/stm32-rs/stm32f3xx-hal/pull/14
371370
[#12]: https://github.com/stm32-rs/stm32f3xx-hal/pull/12
372-
[#12]: https://github.com/stm32-rs/stm32f3xx-hal/pull/12
373371
[#11]: https://github.com/stm32-rs/stm32f3xx-hal/pull/11
374372
[#6]: https://github.com/stm32-rs/stm32f3xx-hal/pull/6
375373
[#4]: https://github.com/stm32-rs/stm32f3xx-hal/pull/4

Cargo.toml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,22 @@ features = ["stm32f303xc", "rt", "stm32-usbd", "can"]
2424
targets = ["thumbv7em-none-eabihf"]
2525

2626
[dependencies]
27-
cfg-if = "1.0"
27+
cfg-if = "1"
2828
cortex-m = "0.7"
2929
cortex-m-rt = "0.6"
3030
embedded-dma = "0.1"
3131
embedded-hal = "0.2"
32-
nb = "1.0"
32+
embedded-time = "0.10"
33+
nb = "1"
3334
paste = "1"
3435
rtcc = "0.2"
3536
stm32f3 = "0.13"
36-
embedded-time = "0.10"
37+
typenum = "1"
3738

3839
[dependencies.embedded-hal-can]
3940
version = "0.1.0"
4041
optional = true
4142

42-
[dependencies.bare-metal]
43-
version = "1.0"
44-
4543
[dependencies.stm32-usbd]
4644
version = "0.6"
4745
optional = true
@@ -95,12 +93,12 @@ stm32f303xb = ["stm32f303", "gpio-f303", "device-selected"]
9593
stm32f303xc = ["stm32f303", "gpio-f303", "device-selected"]
9694
stm32f303xd = ["stm32f303", "gpio-f303e", "device-selected"]
9795
stm32f303xe = ["stm32f303", "gpio-f303e", "device-selected"]
98-
stm32f373 = ["gpio-f373", "stm32f3/stm32f373", "device-selected"]
99-
stm32f378 = ["gpio-f373", "stm32f3/stm32f373", "device-selected"]
100-
stm32f334 = ["gpio-f333", "stm32f3/stm32f3x4", "device-selected"]
10196
stm32f328 = ["gpio-f333", "stm32f3/stm32f303", "device-selected"]
10297
stm32f358 = ["gpio-f303", "stm32f3/stm32f303", "device-selected"]
10398
stm32f398 = ["gpio-f303e", "stm32f3/stm32f303", "device-selected"]
99+
stm32f373 = ["gpio-f373", "stm32f3/stm32f373", "device-selected"]
100+
stm32f378 = ["gpio-f373", "stm32f3/stm32f373", "device-selected"]
101+
stm32f334 = ["gpio-f333", "stm32f3/stm32f3x4", "device-selected"]
104102

105103
defmt-default = ["defmt"]
106104
defmt-trace = ["defmt"]
@@ -154,6 +152,10 @@ required-features = ["stm32f303xc"]
154152
name = "gpio_erased"
155153
required-features = ["rt", "stm32f303xc"]
156154

155+
[[example]]
156+
name = "gpio_interrupts"
157+
required-features = ["rt", "stm32f303xc"]
158+
157159
[[test]]
158160
name = "rcc"
159161
required-features = ["rt", "defmt"]

codegen/src/codegen/gpio.rs

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,32 +60,60 @@ fn merge_pins_by_port(pins: &[gpio::Pin]) -> Result<Vec<Port>> {
6060
}
6161

6262
fn gen_gpio_macro_call(ports: &[Port], feature: &str) -> Result<()> {
63-
println!("gpio!([");
63+
println!("gpio!({{");
64+
65+
gen_pac_list(ports, feature);
66+
67+
println!(" ports: [");
6468
for port in ports {
6569
gen_port(port, feature)?;
6670
}
67-
println!("]);");
71+
println!(" ],");
72+
73+
println!("}});");
6874
Ok(())
6975
}
7076

77+
fn gen_pac_list(ports: &[Port], feature: &str) {
78+
let mut pac_modules: Vec<_> = ports
79+
.iter()
80+
.map(|port| get_port_pac_module(port, feature))
81+
.collect();
82+
pac_modules.sort_unstable();
83+
pac_modules.dedup();
84+
println!(" pacs: [{}],", pac_modules.join(", "));
85+
}
86+
7187
fn gen_port(port: &Port, feature: &str) -> Result<()> {
7288
let pac_module = get_port_pac_module(port, feature);
89+
let port_index = match port.id {
90+
'A' => 0,
91+
'B' => 1,
92+
'C' => 2,
93+
'D' => 3,
94+
'E' => 4,
95+
'F' => 5,
96+
'G' => 6,
97+
'H' => 7,
98+
_ => unreachable!(),
99+
};
73100

74-
println!(" {{");
101+
println!(" {{");
75102
println!(
76-
" port: ({}/{}, pac: {}),",
103+
" port: ({}/{}, {}, {}),",
77104
port.id,
78105
port.id.to_lowercase(),
106+
port_index,
79107
pac_module,
80108
);
81-
println!(" pins: [");
109+
println!(" pins: [");
82110

83111
for pin in &port.pins {
84112
gen_pin(pin)?;
85113
}
86114

87-
println!(" ],");
88-
println!(" }},");
115+
println!(" ],");
116+
println!(" }},");
89117
Ok(())
90118
}
91119

@@ -107,23 +135,19 @@ fn gen_pin(pin: &gpio::Pin) -> Result<()> {
107135
let af_numbers = get_pin_af_numbers(pin)?;
108136

109137
println!(
110-
" {} => {{ reset: {}, afr: {}/{}, af: {:?} }},",
111-
nr,
112-
reset_mode,
113-
afr,
114-
afr.to_lowercase(),
115-
af_numbers,
138+
" {} => {{ reset: {}, afr: {}, af: {:?} }},",
139+
nr, reset_mode, afr, af_numbers,
116140
);
117141

118142
Ok(())
119143
}
120144

121145
fn get_pin_reset_mode(pin: &gpio::Pin) -> Result<&'static str> {
122146
// Debug pins default to their debug function (AF0), everything else
123-
// defaults to floating input.
147+
// defaults to input.
124148
let mode = match (pin.port()?, pin.number()?) {
125-
('A', 13) | ('A', 14) | ('A', 15) | ('B', 3) | ('B', 4) => "AF0",
126-
_ => "Input<Floating>",
149+
('A', 13) | ('A', 14) | ('A', 15) | ('B', 3) | ('B', 4) => "AF0<PushPull>",
150+
_ => "Input",
127151
};
128152
Ok(mode)
129153
}
@@ -134,7 +158,7 @@ fn get_pin_af_numbers(pin: &gpio::Pin) -> Result<Vec<u8>> {
134158
numbers.push(signal.af()?);
135159
}
136160

137-
numbers.sort();
161+
numbers.sort_unstable();
138162
numbers.dedup();
139163

140164
Ok(numbers)

examples/can.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,20 @@ fn main() -> ! {
3838
.freeze(&mut flash.acr);
3939

4040
// Configure CAN RX and TX pins (AF9)
41-
let can_rx = gpioa.pa11.into_af9(&mut gpioa.moder, &mut gpioa.afrh);
42-
let can_tx = gpioa.pa12.into_af9(&mut gpioa.moder, &mut gpioa.afrh);
41+
let rx = gpioa
42+
.pa11
43+
.into_af9_push_pull(&mut gpioa.moder, &mut gpioa.otyper, &mut gpioa.afrh);
44+
let tx = gpioa
45+
.pa12
46+
.into_af9_push_pull(&mut gpioa.moder, &mut gpioa.otyper, &mut gpioa.afrh);
4347

4448
// Initialize the CAN peripheral
45-
let can = Can::new(dp.CAN, can_rx, can_tx, &mut rcc.apb1);
49+
let can = Can::new(dp.CAN, rx, tx, &mut rcc.apb1);
4650

4751
// Uncomment the following line to enable CAN interrupts
4852
// can.listen(Event::Fifo0Fmp);
4953

50-
let (mut can_tx, mut rx0, _rx1) = can.split();
54+
let (mut tx, mut rx0, _rx1) = can.split();
5155

5256
let mut led0 = gpiob
5357
.pb15
@@ -68,7 +72,7 @@ fn main() -> ! {
6872

6973
let frame = CanFrame::new_data(CanId::BaseId(ID), &data);
7074

71-
block!(can_tx.transmit(&frame)).expect("Cannot send first CAN frame");
75+
block!(tx.transmit(&frame)).expect("Cannot send first CAN frame");
7276

7377
loop {
7478
let rcv_frame = block!(rx0.receive()).expect("Cannot receive CAN frame");
@@ -83,7 +87,7 @@ fn main() -> ! {
8387
let data: [u8; 1] = [counter];
8488
let frame = CanFrame::new_data(CanId::BaseId(ID), &data);
8589

86-
block!(can_tx.transmit(&frame)).expect("Cannot send CAN frame");
90+
block!(tx.transmit(&frame)).expect("Cannot send CAN frame");
8791
}
8892

8993
iwdg.feed();

examples/gpio_erased.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use cortex_m::asm;
99
use cortex_m_rt::entry;
1010
use cortex_m_semihosting::hprintln;
1111

12-
use hal::gpio::{self, Floating, Input};
12+
use hal::gpio::{self, Input};
1313
use hal::pac;
1414
use hal::prelude::*;
1515
use stm32f3xx_hal as hal;
@@ -23,7 +23,7 @@ fn main() -> ! {
2323
let mut gpioc = dp.GPIOC.split(&mut rcc.ahb);
2424
let mut gpiod = dp.GPIOD.split(&mut rcc.ahb);
2525

26-
let mut pin_array: [gpio::PXx<Input<Floating>>; 4] = [
26+
let mut pin_array: [gpio::PXx<Input>; 4] = [
2727
gpiob
2828
.pb11
2929
.into_floating_input(&mut gpiob.moder, &mut gpiob.pupdr)

0 commit comments

Comments
 (0)