Skip to content

Commit df3203a

Browse files
authored
Merge branch 'master' into canbus-with-crate
2 parents 6d18d68 + 54e8261 commit df3203a

File tree

28 files changed

+1959
-2584
lines changed

28 files changed

+1959
-2584
lines changed

.github/workflows/ci.yml

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# Note: The checkout@v2 action sometimes checks out the wrong commit:
2-
# https://github.com/actions/checkout/issues/237
3-
# Until that is fixed we use checkout@v1 here instead.
4-
51
name: CI
62

73
on:
@@ -22,6 +18,8 @@ jobs:
2218
- stm32f302xc
2319
- stm32f302xd
2420
- stm32f302xe
21+
- stm32f302x6
22+
- stm32f302x8
2523
- stm32f303xb
2624
- stm32f303xc
2725
- stm32f303xd
@@ -39,7 +37,7 @@ jobs:
3937
- mcu: stm32f303xc
4038
features: rt,stm32-usbd
4139
steps:
42-
- uses: actions/checkout@v1
40+
- uses: actions/checkout@v2
4341
- uses: actions-rs/toolchain@v1
4442
with:
4543
toolchain: stable
@@ -49,13 +47,13 @@ jobs:
4947
- uses: actions-rs/cargo@v1
5048
with:
5149
command: check
52-
args: --features=${{ matrix.mcu }},${{ matrix.features }} --examples
50+
args: --features=${{ matrix.mcu }},${{ matrix.features }} --lib --examples
5351

5452
clippy:
5553
name: Clippy
5654
runs-on: ubuntu-latest
5755
steps:
58-
- uses: actions/checkout@v1
56+
- uses: actions/checkout@v2
5957
- uses: actions-rs/toolchain@v1
6058
with:
6159
toolchain: nightly
@@ -67,14 +65,14 @@ jobs:
6765
with:
6866
token: ${{ secrets.GITHUB_TOKEN }}
6967
args: >
70-
--features=stm32f303xc,rt,stm32-usbd --examples
68+
--features=stm32f303xc,rt,stm32-usbd --lib --examples
7169
-- -D warnings
7270
7371
rustfmt:
7472
name: Rustfmt
7573
runs-on: ubuntu-latest
7674
steps:
77-
- uses: actions/checkout@v1
75+
- uses: actions/checkout@v2
7876
- uses: actions-rs/toolchain@v1
7977
with:
8078
toolchain: stable

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
88
## [Unreleased]
99

1010
### Added
11+
12+
- Support for 16-bit words with SPI ([#107](https://github.com/stm32-rs/stm32f3xx-hal/pull/107))
1113
- SPI support for reclock after initialization ([#98](https://github.com/stm32-rs/stm32f3xx-hal/pull/98))
14+
- Support for `stm32f302x6` and `stm32f302x8` devices ([#132](https://github.com/stm32-rs/stm32f3xx-hal/pull/132))
15+
- Support for the onboard real-time clock (RTC) ([#136](https://github.com/stm32-rs/stm32f3xx-hal/pull/136))
16+
- Enable DMA for USART on `stm32f302` devices ([#139](https://github.com/stm32-rs/stm32f3xx-hal/pull/139))
17+
18+
### Changed
19+
20+
- Introduced auto-generated GPIO mappings based on the STM32CubeMX database
21+
([#129](https://github.com/stm32-rs/stm32f3xx-hal/pull/129))
1222

1323
## [v0.5.0] - 2020-07-21
1424

Cargo.toml

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@ features = ["stm32f303xc", "rt", "stm32-usbd"]
1616
targets = ["thumbv7em-none-eabihf"]
1717

1818
[dependencies]
19+
cfg-if = "0.1"
1920
cortex-m = "0.6"
2021
cortex-m-rt = "0.6"
22+
embedded-dma = "0.1"
2123
embedded-hal = "0.2"
2224
nb = "0.1"
23-
stm32f3 = "0.11"
25+
paste = "1"
26+
rtcc = "0.2"
27+
stm32f3 = "0.12"
2428

2529
[dependencies.embedded-hal-can]
2630
version = "0.1.0"
@@ -38,10 +42,6 @@ features = ["const-fn"]
3842
version = "0.2"
3943
default-features = false
4044

41-
[dependencies.stable_deref_trait]
42-
version = "1"
43-
default-features = false
44-
4545
[dependencies.stm32-usbd]
4646
version = "0.5"
4747
optional = true
@@ -64,30 +64,36 @@ direct-call-deprecated = []
6464
rt = ["stm32f3/rt"]
6565
can = ["embedded-hal-can", "heapless"]
6666

67+
gpio-f302 = []
68+
gpio-f303 = []
69+
gpio-f303e = []
70+
gpio-f333 = []
71+
gpio-f373 = []
72+
6773
# Any Changes here should be mirrored in README.md, src/lib.rs, and
6874
# .github/workflows/ci.yml.
69-
stm32f301 = ["stm32f3/stm32f301", "device-selected"]
70-
stm32f318 = ["stm32f3/stm32f301", "device-selected"]
75+
stm32f301 = ["gpio-f302", "stm32f3/stm32f301", "device-selected"]
76+
stm32f318 = ["gpio-f302", "stm32f3/stm32f301", "device-selected"]
7177
stm32f302 = ["stm32f3/stm32f302", "direct-call-deprecated"]
72-
stm32f302xb = ["stm32f302", "device-selected"]
73-
stm32f302xc = ["stm32f302", "device-selected"]
74-
stm32f302xd = ["stm32f302", "device-selected"]
75-
stm32f302xe = ["stm32f302", "device-selected"]
76-
stm32f302x6 = ["stm32f302", "device-selected"]
77-
stm32f302x8 = ["stm32f302", "device-selected"]
78+
stm32f302x6 = ["stm32f302", "gpio-f302", "device-selected"]
79+
stm32f302x8 = ["stm32f302", "gpio-f302", "device-selected"]
80+
stm32f302xb = ["stm32f302", "gpio-f303", "device-selected"]
81+
stm32f302xc = ["stm32f302", "gpio-f303", "device-selected"]
82+
stm32f302xd = ["stm32f302", "gpio-f303e", "device-selected"]
83+
stm32f302xe = ["stm32f302", "gpio-f303e", "device-selected"]
7884
stm32f303 = ["stm32f3/stm32f303", "direct-call-deprecated"]
79-
stm32f303xb = ["stm32f303", "stm32-usbd/ram_access_1x16", "device-selected"]
80-
stm32f303xc = ["stm32f303", "stm32-usbd/ram_access_1x16", "device-selected"]
81-
stm32f303xd = ["stm32f303", "stm32-usbd/ram_access_2x16", "device-selected"]
82-
stm32f303xe = ["stm32f303", "stm32-usbd/ram_access_2x16", "device-selected"]
83-
stm32f303x6 = ["stm32f303", "device-selected"]
84-
stm32f303x8 = ["stm32f303", "device-selected"]
85-
stm32f373 = ["stm32f3/stm32f373", "device-selected"]
86-
stm32f378 = ["stm32f3/stm32f373", "device-selected"]
87-
stm32f334 = ["stm32f3/stm32f3x4", "device-selected"]
88-
stm32f328 = ["stm32f3/stm32f3x8", "device-selected"]
89-
stm32f358 = ["stm32f3/stm32f3x8", "device-selected"]
90-
stm32f398 = ["stm32f3/stm32f3x8", "device-selected"]
85+
stm32f303x6 = ["stm32f303", "gpio-f333", "device-selected"]
86+
stm32f303x8 = ["stm32f303", "gpio-f333", "device-selected"]
87+
stm32f303xb = ["stm32f303", "gpio-f303", "stm32-usbd/ram_access_1x16", "device-selected"]
88+
stm32f303xc = ["stm32f303", "gpio-f303", "stm32-usbd/ram_access_1x16", "device-selected"]
89+
stm32f303xd = ["stm32f303", "gpio-f303e", "stm32-usbd/ram_access_2x16", "device-selected"]
90+
stm32f303xe = ["stm32f303", "gpio-f303e", "stm32-usbd/ram_access_2x16", "device-selected"]
91+
stm32f373 = ["gpio-f373", "stm32f3/stm32f373", "device-selected"]
92+
stm32f378 = ["gpio-f373", "stm32f3/stm32f373", "device-selected"]
93+
stm32f334 = ["gpio-f333", "stm32f3/stm32f3x4", "device-selected"]
94+
stm32f328 = ["gpio-f333", "stm32f3/stm32f3x8", "device-selected"]
95+
stm32f358 = ["gpio-f303", "stm32f3/stm32f3x8", "device-selected"]
96+
stm32f398 = ["gpio-f303e", "stm32f3/stm32f3x8", "device-selected"]
9197

9298
[profile.dev]
9399
debug = true

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ Note: `x` denotes any character in [a-z]
5959
* stm32f302xc
6060
* stm32f302xd
6161
* stm32f302xe
62-
* stm32f302x6
63-
* stm32f302x8
62+
* stm32f302x6
63+
* stm32f302x8
6464
* stm32f303xb
6565
* stm32f303xc
6666
* stm32f303xd

codegen/.cargo/config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[build]
2+
target = "x86_64-unknown-linux-gnu"

codegen/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target/
2+
**/*.rs.bk

codegen/Cargo.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "codegen"
3+
version = "0.1.0"
4+
authors = ["Jan Teske <[email protected]>"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
anyhow = "1"
9+
once_cell = "1"
10+
regex = "1"
11+
serde-xml-rs = "0.4"
12+
13+
[dependencies.structopt]
14+
version = "0.3"
15+
default-features = false
16+
17+
[dependencies.serde]
18+
version = "1"
19+
features = ["derive"]

codegen/README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Codegen
2+
3+
This crate provides code-generation for the stm32f3xx-hal. It reads information
4+
from an [STM32CubeMX](https://www.st.com/en/development-tools/stm32cubemx.html)
5+
database and uses that to output code that can directly be included into the
6+
source code of the stm32f3xx-hal crate.
7+
8+
For more information on how the STM32CubeMX database is structured, check out
9+
the README in the [cube-parse](https://github.com/dbrgn/cube-parse) repository.
10+
11+
Because by default cargo tries to use the `x86_64-unknown-linux-gnu` target,
12+
when building `codegen`, due to what's specified in the `.cargo/config`, you
13+
need to manually specify your host's target if it differs from that, e.g.:
14+
15+
```
16+
$ cargo run --target x86_64-apple-darwin -- help
17+
```
18+
19+
`codgen` can generate the following code:
20+
21+
- [GPIO mappings](#gpio-mappings)
22+
23+
## GPIO mappings
24+
25+
Running `codegen`'s `gpio` subcommand generates the `gpio!` macro
26+
invocations at the end of `src/gpio.rs`. Re-generating those macro-invocations
27+
is simply a matter of deleting the old ones and then executing:
28+
29+
```
30+
$ cargo run -- gpio $cubemx_db_path >> ../src/gpio.rs
31+
```
32+
33+
`$cubemx_db_path` must be the path to the `db/` directory under an
34+
STM32CubeMX installation. With a default Linux install, this would be
35+
`/opt/stm32cubemx/db`.
36+
37+
The generated `gpio!` invocations are gated by features whose names are derived
38+
from the respective GPIO internal peripheral (IP) version:
39+
40+
- gpio-f302
41+
- gpio-f303
42+
- gpio-f303e
43+
- gpio-f333
44+
- gpio-f373
45+
46+
`codegen` collects those IP versions from the relevant GPIO IP description
47+
files (located at `$cubemx_db_path/mcu/IP/GPIO-*.xml`). The root `<IP>` element
48+
has a `Version` attribute with a value in the form of "STM32Fxxx_gpio_v1_0".
49+
The feature name is constructed by dropping the parts constant between all
50+
version strings and prepending "gpio-".
51+
52+
Note that the GPIO IP version names don't necessarily match the MCUs they are
53+
used in. For example, the GPIOs in `STM32F302xB` MCUs have the IP version
54+
"STM32F303_gpio_v1_0". The MCU features of the `stm32f3xx-hal` also select the
55+
correct `gpio-*` features, so users generally don't have to care about these
56+
details.

codegen/src/codegen/gpio.rs

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
use crate::cubemx::ip::gpio;
2+
use anyhow::{Context, Result};
3+
use once_cell::sync::Lazy;
4+
use regex::Regex;
5+
use std::collections::HashMap;
6+
7+
struct Port<'a> {
8+
id: char,
9+
pins: Vec<&'a gpio::Pin>,
10+
}
11+
12+
pub fn gen_mappings(gpio_ips: &[gpio::Ip]) -> Result<()> {
13+
for ip in gpio_ips.iter() {
14+
println!();
15+
gen_gpio_ip(ip)?;
16+
}
17+
Ok(())
18+
}
19+
20+
fn gen_gpio_ip(ip: &gpio::Ip) -> Result<()> {
21+
let feature = ip_version_to_feature(&ip.version)?;
22+
let ports = merge_pins_by_port(&ip.pins)?;
23+
24+
println!(r#"#[cfg(feature = "{}")]"#, feature);
25+
gen_gpio_macro_call(&ports, &feature)?;
26+
Ok(())
27+
}
28+
29+
fn ip_version_to_feature(ip_version: &str) -> Result<String> {
30+
static VERSION: Lazy<Regex> =
31+
Lazy::new(|| Regex::new(r"^STM32(?P<version>\w+)_gpio_v1_0$").unwrap());
32+
33+
let captures = VERSION
34+
.captures(&ip_version)
35+
.with_context(|| format!("invalid GPIO IP version: {}", ip_version))?;
36+
37+
let version = captures.name("version").unwrap().as_str();
38+
let feature = format!("gpio-{}", version.to_lowercase());
39+
Ok(feature)
40+
}
41+
42+
fn merge_pins_by_port(pins: &[gpio::Pin]) -> Result<Vec<Port>> {
43+
let mut pins_by_port = HashMap::new();
44+
for pin in pins.iter() {
45+
pins_by_port
46+
.entry(pin.port()?)
47+
.and_modify(|e: &mut Vec<_>| e.push(pin))
48+
.or_insert_with(|| vec![pin]);
49+
}
50+
51+
let mut ports = Vec::new();
52+
for (id, mut pins) in pins_by_port {
53+
pins.sort_by_key(|p| p.number().unwrap_or_default());
54+
pins.dedup_by_key(|p| p.number().unwrap_or_default());
55+
ports.push(Port { id, pins });
56+
}
57+
ports.sort_by_key(|p| p.id);
58+
59+
Ok(ports)
60+
}
61+
62+
fn gen_gpio_macro_call(ports: &[Port], feature: &str) -> Result<()> {
63+
println!("gpio!([");
64+
for port in ports {
65+
gen_port(port, feature)?;
66+
}
67+
println!("]);");
68+
Ok(())
69+
}
70+
71+
fn gen_port(port: &Port, feature: &str) -> Result<()> {
72+
let pac_module = get_port_pac_module(port, feature);
73+
74+
println!(" {{");
75+
println!(
76+
" port: ({}/{}, pac: {}),",
77+
port.id,
78+
port.id.to_lowercase(),
79+
pac_module,
80+
);
81+
println!(" pins: [");
82+
83+
for pin in &port.pins {
84+
gen_pin(pin)?;
85+
}
86+
87+
println!(" ],");
88+
println!(" }},");
89+
Ok(())
90+
}
91+
92+
fn get_port_pac_module(port: &Port, feature: &str) -> &'static str {
93+
// The registers in ports A and B have different reset values due to the
94+
// presence of debug pins, so they get dedicated PAC modules.
95+
match port.id {
96+
'A' => "gpioa",
97+
'B' => "gpiob",
98+
'D' if feature == "gpio-f373" => "gpiod",
99+
_ => "gpioc",
100+
}
101+
}
102+
103+
fn gen_pin(pin: &gpio::Pin) -> Result<()> {
104+
let nr = pin.number()?;
105+
let reset_mode = get_pin_reset_mode(pin)?;
106+
let afr = if nr < 8 { 'L' } else { 'H' };
107+
let af_numbers = get_pin_af_numbers(pin)?;
108+
109+
println!(
110+
" {} => {{ reset: {}, afr: {}/{}, af: {:?} }},",
111+
nr,
112+
reset_mode,
113+
afr,
114+
afr.to_lowercase(),
115+
af_numbers,
116+
);
117+
118+
Ok(())
119+
}
120+
121+
fn get_pin_reset_mode(pin: &gpio::Pin) -> Result<&'static str> {
122+
// Debug pins default to their debug function (AF0), everything else
123+
// defaults to floating input.
124+
let mode = match (pin.port()?, pin.number()?) {
125+
('A', 13) | ('A', 14) | ('A', 15) | ('B', 3) | ('B', 4) => "AF0",
126+
_ => "Input<Floating>",
127+
};
128+
Ok(mode)
129+
}
130+
131+
fn get_pin_af_numbers(pin: &gpio::Pin) -> Result<Vec<u8>> {
132+
let mut numbers = Vec::new();
133+
for signal in &pin.pin_signals {
134+
numbers.push(signal.af()?);
135+
}
136+
137+
numbers.sort();
138+
numbers.dedup();
139+
140+
Ok(numbers)
141+
}

0 commit comments

Comments
 (0)