Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generated internal conditional compilation gates #281

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7fc9530
move feature check into build.rs for correctness
Crzyrndm Dec 24, 2021
3bda397
import the feature tables from macro branch
Crzyrndm Dec 24, 2021
74afb53
feature gate struct allows this to be a simple check->print loop
Crzyrndm Dec 24, 2021
3f67d2a
add L485 which shows up in the ST HAL
Crzyrndm Dec 24, 2021
c4299b4
update peripheral feature tables based on L4 cube package v1.17.1
Crzyrndm Dec 24, 2021
f568cf6
update serial gates
Crzyrndm Dec 24, 2021
802d688
PAC support for UART4/5 is not great
Crzyrndm Dec 24, 2021
a2571d0
add RTC type3 gate
Crzyrndm Dec 24, 2021
f8296c0
add gates for device family (L4xx groups)
Crzyrndm Dec 24, 2021
be416c3
update i2c gates
Crzyrndm Dec 24, 2021
1ae4871
gpio f/g
Crzyrndm Dec 24, 2021
ebf99a8
CAN pin gating
Crzyrndm Dec 24, 2021
0b96ba8
more GPIO F/G
Crzyrndm Dec 24, 2021
1d6abd5
unreachable instead of an (incorrect) register block
Crzyrndm Dec 24, 2021
a39efd2
fix copy paste errors in device family gates
Crzyrndm Dec 25, 2021
40107da
add gates for pretty much every peripheral (including those that are …
Crzyrndm Dec 25, 2021
919a532
update lib.rs gating
Crzyrndm Dec 25, 2021
153431e
add a few missed peripherals (mostly L4+ exclusives)
Crzyrndm Dec 25, 2021
284ad6d
add gpioh and gpioi
Crzyrndm Dec 25, 2021
17a0580
missed the L4q5 pka peripheral
Crzyrndm Dec 25, 2021
8f5fd18
update spi gates
Crzyrndm Dec 25, 2021
816d121
timer gates
Crzyrndm Dec 25, 2021
44e115f
fix l442 duplication
Crzyrndm Dec 25, 2021
a10f398
enable gates
Crzyrndm Dec 25, 2021
4260ae0
fix spi gates
Crzyrndm Dec 25, 2021
9cac39e
update signature gates
Crzyrndm Dec 25, 2021
790ac09
update rtc2 conditional
Crzyrndm Dec 25, 2021
f78a52f
update watchdog conditional
Crzyrndm Dec 25, 2021
d22a5e8
add l485 to ci
Crzyrndm Dec 25, 2021
5ee0f29
split feature check and generation into a child module
Crzyrndm Feb 9, 2022
135d0ba
documentation cleanup, split peripherals into presence and variants
Crzyrndm Feb 9, 2022
9cb7e98
Swap QSPI pins and remove conflicting/wrong implementations (#283)
DerFetzer Jan 9, 2022
4873b9e
forgot to update the gates in source...
Crzyrndm Feb 9, 2022
7731dc9
rtc type is now seperated from peripheral presense
Crzyrndm Feb 9, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
- stm32l471
- stm32l475
- stm32l476
- stm32l485
- stm32l486
- stm32l496
- stm32l4a6
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ exclude = [
"docs/*"
]
edition = "2018"
build = "build/build.rs"

[dependencies]
cortex-m = "0.7"
Expand Down Expand Up @@ -85,6 +86,7 @@ stm32l443 = [ "stm32l4/stm32l4x3" ]

# L4x5
stm32l475 = [ "stm32l4/stm32l4x5" ]
stm32l485 = [ "stm32l4/stm32l4x5" ]

# L4x6
stm32l476 = [ "stm32l4/stm32l4x6" ]
Expand Down
22 changes: 22 additions & 0 deletions build/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
pub(crate) mod features;

fn main() {
assert!(
features::validate_selected_features(),
"
This crate requires exactly one of the following features to be enabled:
stm32l431, stm32l451, stm32l471
stm32l412, stm32l422, stm32l432, stm32l442, stm32l452, stm32l462
stm32l433, stm32l443
stm32l475,
stm32l476, stm32l486, stm32l496, stm32l4a6
stm32l4r9, stm32l4s9
"
);
features::generate_internal_features();
}

pub(crate) struct FeatureGate<'a> {
pub name: &'a str,
pub state: bool,
}
86 changes: 86 additions & 0 deletions build/features/family.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use crate::{features::*, FeatureGate};

/// list of peripherals to be gated and whether they are present for the selected features
/// see [crate::features::generate_internal_features()] for how to reference these
pub(crate) const DEVICE_FAMILY: &[FeatureGate] = &[
FeatureGate {
name: "L4x1",
state: IS_FEATURE_ENABLED_L431 || IS_FEATURE_ENABLED_L451 || IS_FEATURE_ENABLED_L471,
},
FeatureGate {
name: "L4x2",
state: IS_FEATURE_ENABLED_L412
|| IS_FEATURE_ENABLED_L422
|| IS_FEATURE_ENABLED_L432
|| IS_FEATURE_ENABLED_L442
|| IS_FEATURE_ENABLED_L452
|| IS_FEATURE_ENABLED_L462,
},
FeatureGate {
name: "L4x3",
state: IS_FEATURE_ENABLED_L433 || IS_FEATURE_ENABLED_L443,
},
FeatureGate {
name: "L4x5",
state: IS_FEATURE_ENABLED_L475 || IS_FEATURE_ENABLED_L485,
},
FeatureGate {
name: "L4x6",
state: IS_FEATURE_ENABLED_L476
|| IS_FEATURE_ENABLED_L486
|| IS_FEATURE_ENABLED_L496
|| IS_FEATURE_ENABLED_L4A6,
},
FeatureGate {
name: "L4+x5",
state: IS_FEATURE_ENABLED_L4P5
|| IS_FEATURE_ENABLED_L4Q5
|| IS_FEATURE_ENABLED_L4R5
|| IS_FEATURE_ENABLED_L4S5,
},
FeatureGate {
name: "L4+x7",
state: IS_FEATURE_ENABLED_L4S7 || IS_FEATURE_ENABLED_L4R7,
},
FeatureGate {
name: "L4+x9",
state: IS_FEATURE_ENABLED_L4S9 || IS_FEATURE_ENABLED_L4R9,
},
FeatureGate {
name: "L41_42",
state: IS_FEATURE_ENABLED_L412 || IS_FEATURE_ENABLED_L422,
},
FeatureGate {
name: "L43_44",
state: IS_FEATURE_ENABLED_L431
|| IS_FEATURE_ENABLED_L432
|| IS_FEATURE_ENABLED_L433
|| IS_FEATURE_ENABLED_L442
|| IS_FEATURE_ENABLED_L443,
},
FeatureGate {
name: "L45_46",
state: IS_FEATURE_ENABLED_L451 || IS_FEATURE_ENABLED_L452 || IS_FEATURE_ENABLED_L462,
},
FeatureGate {
name: "L47_48",
state: IS_FEATURE_ENABLED_L471
|| IS_FEATURE_ENABLED_L475
|| IS_FEATURE_ENABLED_L476
|| IS_FEATURE_ENABLED_L485
|| IS_FEATURE_ENABLED_L486,
},
FeatureGate {
name: "L4P_4Q",
state: IS_FEATURE_ENABLED_L4P5 || IS_FEATURE_ENABLED_L4Q5,
},
FeatureGate {
name: "L4R_4S",
state: IS_FEATURE_ENABLED_L4R5
|| IS_FEATURE_ENABLED_L4S5
|| IS_FEATURE_ENABLED_L4R7
|| IS_FEATURE_ENABLED_L4S7
|| IS_FEATURE_ENABLED_L4R9
|| IS_FEATURE_ENABLED_L4S9,
},
];
105 changes: 105 additions & 0 deletions build/features/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
pub(crate) mod family;
pub(crate) mod peripherals;

/// check that a valid combination of externally visible features has been enabled by dependant crates
/// this check asserts:
/// * exactly one of the device selection features is enabled (e.g. stm32l432)
pub(crate) fn validate_selected_features() -> bool {
const DEVICE_FEATURES: &[bool] = &[
IS_FEATURE_ENABLED_L412,
IS_FEATURE_ENABLED_L422,
IS_FEATURE_ENABLED_L431,
IS_FEATURE_ENABLED_L432,
IS_FEATURE_ENABLED_L433,
IS_FEATURE_ENABLED_L442,
IS_FEATURE_ENABLED_L443,
IS_FEATURE_ENABLED_L451,
IS_FEATURE_ENABLED_L452,
IS_FEATURE_ENABLED_L462,
IS_FEATURE_ENABLED_L471,
IS_FEATURE_ENABLED_L475,
IS_FEATURE_ENABLED_L476,
IS_FEATURE_ENABLED_L485,
IS_FEATURE_ENABLED_L486,
IS_FEATURE_ENABLED_L496,
IS_FEATURE_ENABLED_L4A6,
// These don't count since there isn't an official feature for them
//IS_FEATURE_ENABLED_L4P5,
//IS_FEATURE_ENABLED_L4Q5,
//IS_FEATURE_ENABLED_L4R5,
//IS_FEATURE_ENABLED_L4S5,
//IS_FEATURE_ENABLED_L4R7,
//IS_FEATURE_ENABLED_L4S7,
IS_FEATURE_ENABLED_L4R9,
IS_FEATURE_ENABLED_L4S9,
];
let check_selected_device = DEVICE_FEATURES.iter().filter(|&&b| b).count() == 1;

check_selected_device
}

/// the features listed in the crate TOML (e.g. stm32l432) aren't the most enlightening things when developing
/// (e.g. which U(S)ARTs are present). This function produces a number of internal gates which can be checked almost
/// exactly like a standard cargo feature
///
/// ## To check if the device belongs to a family group
/// e.g. for the L432, the following conditions are true
/// ```ignore
/// #[cfg(family = "L43_44")] // group by the second digit
/// #[cfg(family = "L4x2")] // group by the third digit
/// ```
/// ## To check whether a peripheral is present
/// For completeness, even the peripherals which are always present can be checked
/// NOTE: A peripheral missing from the list is a bug
/// ```ignore
/// #[cfg(has_peripheral = "adc1")]
/// ```
/// ## To check a peripheral variant
/// Some peripherals have a limited number of variations that it may be clearer to check against
/// e.g. The L4 RTC comes in two types (RTC2 / RTC3. See AN4759)
/// ```ignore
/// #[cfg(has_peripheral_variant = "rtc_type3")]
/// ```
pub(crate) fn generate_internal_features() {
for gate in family::DEVICE_FAMILY {
if gate.state {
println!(r#"cargo:rustc-cfg=family="{}""#, gate.name);
}
}
for gate in peripherals::PERIPHERAL_FEATURES {
if gate.state {
println!(r#"cargo:rustc-cfg=has_peripheral="{}""#, gate.name);
}
}
for gate in peripherals::PERIPHERAL_VARIANTS {
if gate.state {
println!(r#"cargo:rustc-cfg=has_peripheral_variant="{}""#, gate.name);
}
}
}

pub(crate) const IS_FEATURE_ENABLED_L412: bool = cfg!(feature = "stm32l412");
pub(crate) const IS_FEATURE_ENABLED_L422: bool = cfg!(feature = "stm32l422");
pub(crate) const IS_FEATURE_ENABLED_L431: bool = cfg!(feature = "stm32l431");
pub(crate) const IS_FEATURE_ENABLED_L432: bool = cfg!(feature = "stm32l432");
pub(crate) const IS_FEATURE_ENABLED_L433: bool = cfg!(feature = "stm32l433");
pub(crate) const IS_FEATURE_ENABLED_L442: bool = cfg!(feature = "stm32l442");
pub(crate) const IS_FEATURE_ENABLED_L443: bool = cfg!(feature = "stm32l443");
pub(crate) const IS_FEATURE_ENABLED_L451: bool = cfg!(feature = "stm32l451");
pub(crate) const IS_FEATURE_ENABLED_L452: bool = cfg!(feature = "stm32l452");
pub(crate) const IS_FEATURE_ENABLED_L462: bool = cfg!(feature = "stm32l462");
pub(crate) const IS_FEATURE_ENABLED_L471: bool = cfg!(feature = "stm32l471");
pub(crate) const IS_FEATURE_ENABLED_L475: bool = cfg!(feature = "stm32l475");
pub(crate) const IS_FEATURE_ENABLED_L476: bool = cfg!(feature = "stm32l476");
pub(crate) const IS_FEATURE_ENABLED_L485: bool = cfg!(feature = "stm32l485");
pub(crate) const IS_FEATURE_ENABLED_L486: bool = cfg!(feature = "stm32l486");
pub(crate) const IS_FEATURE_ENABLED_L496: bool = cfg!(feature = "stm32l496");
pub(crate) const IS_FEATURE_ENABLED_L4A6: bool = cfg!(feature = "stm32l4a6");
pub(crate) const IS_FEATURE_ENABLED_L4P5: bool = cfg!(feature = "stm32l4p5");
pub(crate) const IS_FEATURE_ENABLED_L4Q5: bool = cfg!(feature = "stm32l4q5");
pub(crate) const IS_FEATURE_ENABLED_L4R5: bool = cfg!(feature = "stm32l4r5");
pub(crate) const IS_FEATURE_ENABLED_L4S5: bool = cfg!(feature = "stm32l4s5");
pub(crate) const IS_FEATURE_ENABLED_L4R7: bool = cfg!(feature = "stm32l4r7");
pub(crate) const IS_FEATURE_ENABLED_L4S7: bool = cfg!(feature = "stm32l4s7");
pub(crate) const IS_FEATURE_ENABLED_L4R9: bool = cfg!(feature = "stm32l4r9");
pub(crate) const IS_FEATURE_ENABLED_L4S9: bool = cfg!(feature = "stm32l4s9");
Loading