diff options
| author | Dion Dokter <[email protected]> | 2024-07-08 16:54:06 +0200 |
|---|---|---|
| committer | Dion Dokter <[email protected]> | 2024-07-08 16:54:06 +0200 |
| commit | 203297b56912c05d2dd6a009ffeb433fb2ffbea6 (patch) | |
| tree | fa1708215925ad861d68dc8454069c11ae5c861c /embassy-stm32 | |
| parent | b1ea90a87e5ce6b16bbc155ad30d6d3473a998bb (diff) | |
Make clocks repr C.
Add shared data.
Modify freq functions to use shared data.
Modify examples to use new init/
Diffstat (limited to 'embassy-stm32')
| -rw-r--r-- | embassy-stm32/Cargo.toml | 123 | ||||
| -rw-r--r-- | embassy-stm32/build.rs | 7 | ||||
| -rw-r--r-- | embassy-stm32/src/lib.rs | 116 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 27 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc/mod.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/time.rs | 36 |
6 files changed, 247 insertions, 64 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 523bacb11..a72a1a667 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -181,6 +181,9 @@ split-pc3 = ["_split-pins-enabled"] | |||
| 181 | ## internal use only | 181 | ## internal use only |
| 182 | _split-pins-enabled = [] | 182 | _split-pins-enabled = [] |
| 183 | 183 | ||
| 184 | ## internal use only | ||
| 185 | _dual-core = [] | ||
| 186 | |||
| 184 | #! ## Chip-selection features | 187 | #! ## Chip-selection features |
| 185 | #! Select your chip by specifying the model as a feature, e.g. `stm32c011d6`. | 188 | #! Select your chip by specifying the model as a feature, e.g. `stm32c011d6`. |
| 186 | #! Check the `Cargo.toml` for the latest list of supported chips. | 189 | #! Check the `Cargo.toml` for the latest list of supported chips. |
| @@ -1004,40 +1007,40 @@ stm32h743xg = [ "stm32-metapac/stm32h743xg" ] | |||
| 1004 | stm32h743xi = [ "stm32-metapac/stm32h743xi" ] | 1007 | stm32h743xi = [ "stm32-metapac/stm32h743xi" ] |
| 1005 | stm32h743zg = [ "stm32-metapac/stm32h743zg" ] | 1008 | stm32h743zg = [ "stm32-metapac/stm32h743zg" ] |
| 1006 | stm32h743zi = [ "stm32-metapac/stm32h743zi" ] | 1009 | stm32h743zi = [ "stm32-metapac/stm32h743zi" ] |
| 1007 | stm32h745bg-cm7 = [ "stm32-metapac/stm32h745bg-cm7" ] | 1010 | stm32h745bg-cm7 = [ "stm32-metapac/stm32h745bg-cm7", "_dual-core" ] |
| 1008 | stm32h745bg-cm4 = [ "stm32-metapac/stm32h745bg-cm4" ] | 1011 | stm32h745bg-cm4 = [ "stm32-metapac/stm32h745bg-cm4", "_dual-core" ] |
| 1009 | stm32h745bi-cm7 = [ "stm32-metapac/stm32h745bi-cm7" ] | 1012 | stm32h745bi-cm7 = [ "stm32-metapac/stm32h745bi-cm7", "_dual-core" ] |
| 1010 | stm32h745bi-cm4 = [ "stm32-metapac/stm32h745bi-cm4" ] | 1013 | stm32h745bi-cm4 = [ "stm32-metapac/stm32h745bi-cm4", "_dual-core" ] |
| 1011 | stm32h745ig-cm7 = [ "stm32-metapac/stm32h745ig-cm7" ] | 1014 | stm32h745ig-cm7 = [ "stm32-metapac/stm32h745ig-cm7", "_dual-core" ] |
| 1012 | stm32h745ig-cm4 = [ "stm32-metapac/stm32h745ig-cm4" ] | 1015 | stm32h745ig-cm4 = [ "stm32-metapac/stm32h745ig-cm4", "_dual-core" ] |
| 1013 | stm32h745ii-cm7 = [ "stm32-metapac/stm32h745ii-cm7" ] | 1016 | stm32h745ii-cm7 = [ "stm32-metapac/stm32h745ii-cm7", "_dual-core" ] |
| 1014 | stm32h745ii-cm4 = [ "stm32-metapac/stm32h745ii-cm4" ] | 1017 | stm32h745ii-cm4 = [ "stm32-metapac/stm32h745ii-cm4", "_dual-core" ] |
| 1015 | stm32h745xg-cm7 = [ "stm32-metapac/stm32h745xg-cm7" ] | 1018 | stm32h745xg-cm7 = [ "stm32-metapac/stm32h745xg-cm7", "_dual-core" ] |
| 1016 | stm32h745xg-cm4 = [ "stm32-metapac/stm32h745xg-cm4" ] | 1019 | stm32h745xg-cm4 = [ "stm32-metapac/stm32h745xg-cm4", "_dual-core" ] |
| 1017 | stm32h745xi-cm7 = [ "stm32-metapac/stm32h745xi-cm7" ] | 1020 | stm32h745xi-cm7 = [ "stm32-metapac/stm32h745xi-cm7", "_dual-core" ] |
| 1018 | stm32h745xi-cm4 = [ "stm32-metapac/stm32h745xi-cm4" ] | 1021 | stm32h745xi-cm4 = [ "stm32-metapac/stm32h745xi-cm4", "_dual-core" ] |
| 1019 | stm32h745zg-cm7 = [ "stm32-metapac/stm32h745zg-cm7" ] | 1022 | stm32h745zg-cm7 = [ "stm32-metapac/stm32h745zg-cm7", "_dual-core" ] |
| 1020 | stm32h745zg-cm4 = [ "stm32-metapac/stm32h745zg-cm4" ] | 1023 | stm32h745zg-cm4 = [ "stm32-metapac/stm32h745zg-cm4", "_dual-core" ] |
| 1021 | stm32h745zi-cm7 = [ "stm32-metapac/stm32h745zi-cm7" ] | 1024 | stm32h745zi-cm7 = [ "stm32-metapac/stm32h745zi-cm7", "_dual-core" ] |
| 1022 | stm32h745zi-cm4 = [ "stm32-metapac/stm32h745zi-cm4" ] | 1025 | stm32h745zi-cm4 = [ "stm32-metapac/stm32h745zi-cm4", "_dual-core" ] |
| 1023 | stm32h747ag-cm7 = [ "stm32-metapac/stm32h747ag-cm7" ] | 1026 | stm32h747ag-cm7 = [ "stm32-metapac/stm32h747ag-cm7", "_dual-core" ] |
| 1024 | stm32h747ag-cm4 = [ "stm32-metapac/stm32h747ag-cm4" ] | 1027 | stm32h747ag-cm4 = [ "stm32-metapac/stm32h747ag-cm4", "_dual-core" ] |
| 1025 | stm32h747ai-cm7 = [ "stm32-metapac/stm32h747ai-cm7" ] | 1028 | stm32h747ai-cm7 = [ "stm32-metapac/stm32h747ai-cm7", "_dual-core" ] |
| 1026 | stm32h747ai-cm4 = [ "stm32-metapac/stm32h747ai-cm4" ] | 1029 | stm32h747ai-cm4 = [ "stm32-metapac/stm32h747ai-cm4", "_dual-core" ] |
| 1027 | stm32h747bg-cm7 = [ "stm32-metapac/stm32h747bg-cm7" ] | 1030 | stm32h747bg-cm7 = [ "stm32-metapac/stm32h747bg-cm7", "_dual-core" ] |
| 1028 | stm32h747bg-cm4 = [ "stm32-metapac/stm32h747bg-cm4" ] | 1031 | stm32h747bg-cm4 = [ "stm32-metapac/stm32h747bg-cm4", "_dual-core" ] |
| 1029 | stm32h747bi-cm7 = [ "stm32-metapac/stm32h747bi-cm7" ] | 1032 | stm32h747bi-cm7 = [ "stm32-metapac/stm32h747bi-cm7", "_dual-core" ] |
| 1030 | stm32h747bi-cm4 = [ "stm32-metapac/stm32h747bi-cm4" ] | 1033 | stm32h747bi-cm4 = [ "stm32-metapac/stm32h747bi-cm4", "_dual-core" ] |
| 1031 | stm32h747ig-cm7 = [ "stm32-metapac/stm32h747ig-cm7" ] | 1034 | stm32h747ig-cm7 = [ "stm32-metapac/stm32h747ig-cm7", "_dual-core" ] |
| 1032 | stm32h747ig-cm4 = [ "stm32-metapac/stm32h747ig-cm4" ] | 1035 | stm32h747ig-cm4 = [ "stm32-metapac/stm32h747ig-cm4", "_dual-core" ] |
| 1033 | stm32h747ii-cm7 = [ "stm32-metapac/stm32h747ii-cm7" ] | 1036 | stm32h747ii-cm7 = [ "stm32-metapac/stm32h747ii-cm7", "_dual-core" ] |
| 1034 | stm32h747ii-cm4 = [ "stm32-metapac/stm32h747ii-cm4" ] | 1037 | stm32h747ii-cm4 = [ "stm32-metapac/stm32h747ii-cm4", "_dual-core" ] |
| 1035 | stm32h747xg-cm7 = [ "stm32-metapac/stm32h747xg-cm7" ] | 1038 | stm32h747xg-cm7 = [ "stm32-metapac/stm32h747xg-cm7", "_dual-core" ] |
| 1036 | stm32h747xg-cm4 = [ "stm32-metapac/stm32h747xg-cm4" ] | 1039 | stm32h747xg-cm4 = [ "stm32-metapac/stm32h747xg-cm4", "_dual-core" ] |
| 1037 | stm32h747xi-cm7 = [ "stm32-metapac/stm32h747xi-cm7" ] | 1040 | stm32h747xi-cm7 = [ "stm32-metapac/stm32h747xi-cm7", "_dual-core" ] |
| 1038 | stm32h747xi-cm4 = [ "stm32-metapac/stm32h747xi-cm4" ] | 1041 | stm32h747xi-cm4 = [ "stm32-metapac/stm32h747xi-cm4", "_dual-core" ] |
| 1039 | stm32h747zi-cm7 = [ "stm32-metapac/stm32h747zi-cm7" ] | 1042 | stm32h747zi-cm7 = [ "stm32-metapac/stm32h747zi-cm7", "_dual-core" ] |
| 1040 | stm32h747zi-cm4 = [ "stm32-metapac/stm32h747zi-cm4" ] | 1043 | stm32h747zi-cm4 = [ "stm32-metapac/stm32h747zi-cm4", "_dual-core" ] |
| 1041 | stm32h750ib = [ "stm32-metapac/stm32h750ib" ] | 1044 | stm32h750ib = [ "stm32-metapac/stm32h750ib" ] |
| 1042 | stm32h750vb = [ "stm32-metapac/stm32h750vb" ] | 1045 | stm32h750vb = [ "stm32-metapac/stm32h750vb" ] |
| 1043 | stm32h750xb = [ "stm32-metapac/stm32h750xb" ] | 1046 | stm32h750xb = [ "stm32-metapac/stm32h750xb" ] |
| @@ -1048,24 +1051,24 @@ stm32h753ii = [ "stm32-metapac/stm32h753ii" ] | |||
| 1048 | stm32h753vi = [ "stm32-metapac/stm32h753vi" ] | 1051 | stm32h753vi = [ "stm32-metapac/stm32h753vi" ] |
| 1049 | stm32h753xi = [ "stm32-metapac/stm32h753xi" ] | 1052 | stm32h753xi = [ "stm32-metapac/stm32h753xi" ] |
| 1050 | stm32h753zi = [ "stm32-metapac/stm32h753zi" ] | 1053 | stm32h753zi = [ "stm32-metapac/stm32h753zi" ] |
| 1051 | stm32h755bi-cm7 = [ "stm32-metapac/stm32h755bi-cm7" ] | 1054 | stm32h755bi-cm7 = [ "stm32-metapac/stm32h755bi-cm7", "_dual-core" ] |
| 1052 | stm32h755bi-cm4 = [ "stm32-metapac/stm32h755bi-cm4" ] | 1055 | stm32h755bi-cm4 = [ "stm32-metapac/stm32h755bi-cm4", "_dual-core" ] |
| 1053 | stm32h755ii-cm7 = [ "stm32-metapac/stm32h755ii-cm7" ] | 1056 | stm32h755ii-cm7 = [ "stm32-metapac/stm32h755ii-cm7", "_dual-core" ] |
| 1054 | stm32h755ii-cm4 = [ "stm32-metapac/stm32h755ii-cm4" ] | 1057 | stm32h755ii-cm4 = [ "stm32-metapac/stm32h755ii-cm4", "_dual-core" ] |
| 1055 | stm32h755xi-cm7 = [ "stm32-metapac/stm32h755xi-cm7" ] | 1058 | stm32h755xi-cm7 = [ "stm32-metapac/stm32h755xi-cm7", "_dual-core" ] |
| 1056 | stm32h755xi-cm4 = [ "stm32-metapac/stm32h755xi-cm4" ] | 1059 | stm32h755xi-cm4 = [ "stm32-metapac/stm32h755xi-cm4", "_dual-core" ] |
| 1057 | stm32h755zi-cm7 = [ "stm32-metapac/stm32h755zi-cm7" ] | 1060 | stm32h755zi-cm7 = [ "stm32-metapac/stm32h755zi-cm7", "_dual-core" ] |
| 1058 | stm32h755zi-cm4 = [ "stm32-metapac/stm32h755zi-cm4" ] | 1061 | stm32h755zi-cm4 = [ "stm32-metapac/stm32h755zi-cm4", "_dual-core" ] |
| 1059 | stm32h757ai-cm7 = [ "stm32-metapac/stm32h757ai-cm7" ] | 1062 | stm32h757ai-cm7 = [ "stm32-metapac/stm32h757ai-cm7", "_dual-core" ] |
| 1060 | stm32h757ai-cm4 = [ "stm32-metapac/stm32h757ai-cm4" ] | 1063 | stm32h757ai-cm4 = [ "stm32-metapac/stm32h757ai-cm4", "_dual-core" ] |
| 1061 | stm32h757bi-cm7 = [ "stm32-metapac/stm32h757bi-cm7" ] | 1064 | stm32h757bi-cm7 = [ "stm32-metapac/stm32h757bi-cm7", "_dual-core" ] |
| 1062 | stm32h757bi-cm4 = [ "stm32-metapac/stm32h757bi-cm4" ] | 1065 | stm32h757bi-cm4 = [ "stm32-metapac/stm32h757bi-cm4", "_dual-core" ] |
| 1063 | stm32h757ii-cm7 = [ "stm32-metapac/stm32h757ii-cm7" ] | 1066 | stm32h757ii-cm7 = [ "stm32-metapac/stm32h757ii-cm7", "_dual-core" ] |
| 1064 | stm32h757ii-cm4 = [ "stm32-metapac/stm32h757ii-cm4" ] | 1067 | stm32h757ii-cm4 = [ "stm32-metapac/stm32h757ii-cm4", "_dual-core" ] |
| 1065 | stm32h757xi-cm7 = [ "stm32-metapac/stm32h757xi-cm7" ] | 1068 | stm32h757xi-cm7 = [ "stm32-metapac/stm32h757xi-cm7", "_dual-core" ] |
| 1066 | stm32h757xi-cm4 = [ "stm32-metapac/stm32h757xi-cm4" ] | 1069 | stm32h757xi-cm4 = [ "stm32-metapac/stm32h757xi-cm4", "_dual-core" ] |
| 1067 | stm32h757zi-cm7 = [ "stm32-metapac/stm32h757zi-cm7" ] | 1070 | stm32h757zi-cm7 = [ "stm32-metapac/stm32h757zi-cm7", "_dual-core" ] |
| 1068 | stm32h757zi-cm4 = [ "stm32-metapac/stm32h757zi-cm4" ] | 1071 | stm32h757zi-cm4 = [ "stm32-metapac/stm32h757zi-cm4", "_dual-core" ] |
| 1069 | stm32h7a3ag = [ "stm32-metapac/stm32h7a3ag" ] | 1072 | stm32h7a3ag = [ "stm32-metapac/stm32h7a3ag" ] |
| 1070 | stm32h7a3ai = [ "stm32-metapac/stm32h7a3ai" ] | 1073 | stm32h7a3ai = [ "stm32-metapac/stm32h7a3ai" ] |
| 1071 | stm32h7a3ig = [ "stm32-metapac/stm32h7a3ig" ] | 1074 | stm32h7a3ig = [ "stm32-metapac/stm32h7a3ig" ] |
| @@ -1598,14 +1601,14 @@ stm32wba55he = [ "stm32-metapac/stm32wba55he" ] | |||
| 1598 | stm32wba55hg = [ "stm32-metapac/stm32wba55hg" ] | 1601 | stm32wba55hg = [ "stm32-metapac/stm32wba55hg" ] |
| 1599 | stm32wba55ue = [ "stm32-metapac/stm32wba55ue" ] | 1602 | stm32wba55ue = [ "stm32-metapac/stm32wba55ue" ] |
| 1600 | stm32wba55ug = [ "stm32-metapac/stm32wba55ug" ] | 1603 | stm32wba55ug = [ "stm32-metapac/stm32wba55ug" ] |
| 1601 | stm32wl54cc-cm4 = [ "stm32-metapac/stm32wl54cc-cm4" ] | 1604 | stm32wl54cc-cm4 = [ "stm32-metapac/stm32wl54cc-cm4", "_dual-core" ] |
| 1602 | stm32wl54cc-cm0p = [ "stm32-metapac/stm32wl54cc-cm0p" ] | 1605 | stm32wl54cc-cm0p = [ "stm32-metapac/stm32wl54cc-cm0p", "_dual-core" ] |
| 1603 | stm32wl54jc-cm4 = [ "stm32-metapac/stm32wl54jc-cm4" ] | 1606 | stm32wl54jc-cm4 = [ "stm32-metapac/stm32wl54jc-cm4", "_dual-core" ] |
| 1604 | stm32wl54jc-cm0p = [ "stm32-metapac/stm32wl54jc-cm0p" ] | 1607 | stm32wl54jc-cm0p = [ "stm32-metapac/stm32wl54jc-cm0p", "_dual-core" ] |
| 1605 | stm32wl55cc-cm4 = [ "stm32-metapac/stm32wl55cc-cm4" ] | 1608 | stm32wl55cc-cm4 = [ "stm32-metapac/stm32wl55cc-cm4", "_dual-core" ] |
| 1606 | stm32wl55cc-cm0p = [ "stm32-metapac/stm32wl55cc-cm0p" ] | 1609 | stm32wl55cc-cm0p = [ "stm32-metapac/stm32wl55cc-cm0p", "_dual-core" ] |
| 1607 | stm32wl55jc-cm4 = [ "stm32-metapac/stm32wl55jc-cm4" ] | 1610 | stm32wl55jc-cm4 = [ "stm32-metapac/stm32wl55jc-cm4", "_dual-core" ] |
| 1608 | stm32wl55jc-cm0p = [ "stm32-metapac/stm32wl55jc-cm0p" ] | 1611 | stm32wl55jc-cm0p = [ "stm32-metapac/stm32wl55jc-cm0p", "_dual-core" ] |
| 1609 | stm32wle4c8 = [ "stm32-metapac/stm32wle4c8" ] | 1612 | stm32wle4c8 = [ "stm32-metapac/stm32wle4c8" ] |
| 1610 | stm32wle4cb = [ "stm32-metapac/stm32wle4cb" ] | 1613 | stm32wle4cb = [ "stm32-metapac/stm32wle4cb" ] |
| 1611 | stm32wle4cc = [ "stm32-metapac/stm32wle4cc" ] | 1614 | stm32wle4cc = [ "stm32-metapac/stm32wle4cc" ] |
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 8457e3a13..d8a7ea0e6 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -480,7 +480,7 @@ fn main() { | |||
| 480 | self.clock_names.insert(name.to_ascii_lowercase()); | 480 | self.clock_names.insert(name.to_ascii_lowercase()); |
| 481 | quote!(unsafe { | 481 | quote!(unsafe { |
| 482 | unwrap!( | 482 | unwrap!( |
| 483 | crate::rcc::get_freqs().#clock_name, | 483 | crate::rcc::get_freqs().#clock_name.to_hertz(), |
| 484 | "peripheral '{}' is configured to use the '{}' clock, which is not running. \ | 484 | "peripheral '{}' is configured to use the '{}' clock, which is not running. \ |
| 485 | Either enable it in 'config.rcc' or change 'config.rcc.mux' to use another clock", | 485 | Either enable it in 'config.rcc' or change 'config.rcc.mux' to use another clock", |
| 486 | #peripheral, | 486 | #peripheral, |
| @@ -713,9 +713,10 @@ fn main() { | |||
| 713 | g.extend(quote! { | 713 | g.extend(quote! { |
| 714 | #[derive(Clone, Copy, Debug)] | 714 | #[derive(Clone, Copy, Debug)] |
| 715 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 715 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 716 | #[repr(C)] | ||
| 716 | pub struct Clocks { | 717 | pub struct Clocks { |
| 717 | #( | 718 | #( |
| 718 | pub #clock_idents: Option<crate::time::Hertz>, | 719 | pub #clock_idents: crate::time::MaybeHertz, |
| 719 | )* | 720 | )* |
| 720 | } | 721 | } |
| 721 | }); | 722 | }); |
| @@ -732,7 +733,7 @@ fn main() { | |||
| 732 | $($(#[$m])* $k: $v,)* | 733 | $($(#[$m])* $k: $v,)* |
| 733 | }; | 734 | }; |
| 734 | crate::rcc::set_freqs(crate::rcc::Clocks { | 735 | crate::rcc::set_freqs(crate::rcc::Clocks { |
| 735 | #( #clock_idents: all.#clock_idents, )* | 736 | #( #clock_idents: all.#clock_idents.into(), )* |
| 736 | }); | 737 | }); |
| 737 | } | 738 | } |
| 738 | }; | 739 | }; |
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 95f59360a..8f001f03b 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs | |||
| @@ -273,7 +273,123 @@ impl Default for Config { | |||
| 273 | /// This returns the peripheral singletons that can be used for creating drivers. | 273 | /// This returns the peripheral singletons that can be used for creating drivers. |
| 274 | /// | 274 | /// |
| 275 | /// This should only be called once at startup, otherwise it panics. | 275 | /// This should only be called once at startup, otherwise it panics. |
| 276 | #[cfg(not(feature = "_dual-core"))] | ||
| 276 | pub fn init(config: Config) -> Peripherals { | 277 | pub fn init(config: Config) -> Peripherals { |
| 278 | init_hw(config) | ||
| 279 | } | ||
| 280 | |||
| 281 | #[cfg(feature = "_dual-core")] | ||
| 282 | mod dual_core { | ||
| 283 | use rcc::Clocks; | ||
| 284 | |||
| 285 | use super::*; | ||
| 286 | use core::{ | ||
| 287 | mem::MaybeUninit, | ||
| 288 | sync::atomic::{AtomicUsize, Ordering}, | ||
| 289 | }; | ||
| 290 | |||
| 291 | /// Object containing data that embassy needs to share between cores. | ||
| 292 | /// | ||
| 293 | /// It cannot be initialized by the user. The intended use is: | ||
| 294 | /// | ||
| 295 | /// ``` | ||
| 296 | /// #[link_section = ".ram_d3"] | ||
| 297 | /// static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit(); | ||
| 298 | /// | ||
| 299 | /// init_secondary(&SHARED_DATA); | ||
| 300 | /// ``` | ||
| 301 | /// | ||
| 302 | /// This static must be placed in the same position for both cores. How and where this is done is left to the user. | ||
| 303 | pub struct SharedData { | ||
| 304 | init_flag: AtomicUsize, | ||
| 305 | clocks: MaybeUninit<Clocks>, | ||
| 306 | } | ||
| 307 | |||
| 308 | const INIT_DONE_FLAG: usize = 0xca11ab1e; | ||
| 309 | |||
| 310 | /// Initialize the `embassy-stm32` HAL with the provided configuration. | ||
| 311 | /// This function does the actual initialization of the hardware, in contrast to [init_secondary] or [try_init_secondary]. | ||
| 312 | /// Any core can do the init, but it's important only one core does it. | ||
| 313 | /// | ||
| 314 | /// This returns the peripheral singletons that can be used for creating drivers. | ||
| 315 | /// | ||
| 316 | /// This should only be called once at startup, otherwise it panics. | ||
| 317 | /// | ||
| 318 | /// The `shared_data` is used to coordinate the init with the second core. Read the [SharedData] docs | ||
| 319 | /// for more information on its requirements. | ||
| 320 | pub fn init_primary(config: Config, shared_data: &'static MaybeUninit<SharedData>) -> Peripherals { | ||
| 321 | let shared_data = unsafe { shared_data.assume_init_ref() }; | ||
| 322 | |||
| 323 | rcc::set_freqs_ptr(&shared_data.clocks); | ||
| 324 | let p = init_hw(config); | ||
| 325 | |||
| 326 | shared_data.init_flag.store(INIT_DONE_FLAG, Ordering::SeqCst); | ||
| 327 | |||
| 328 | p | ||
| 329 | } | ||
| 330 | |||
| 331 | /// Try to initialize the `embassy-stm32` HAL based on the init done by the other core using [init_primary]. | ||
| 332 | /// | ||
| 333 | /// This returns the peripheral singletons that can be used for creating drivers if the other core is done with its init. | ||
| 334 | /// If the other core is not done yet, this will return `None`. | ||
| 335 | /// | ||
| 336 | /// This should only be called once at startup, otherwise it may panic. | ||
| 337 | /// | ||
| 338 | /// The `shared_data` is used to coordinate the init with the second core. Read the [SharedData] docs | ||
| 339 | /// for more information on its requirements. | ||
| 340 | pub fn try_init_secondary(shared_data: &'static MaybeUninit<SharedData>) -> Option<Peripherals> { | ||
| 341 | let shared_data = unsafe { shared_data.assume_init_ref() }; | ||
| 342 | |||
| 343 | if shared_data | ||
| 344 | .init_flag | ||
| 345 | .compare_exchange(INIT_DONE_FLAG, 0, Ordering::SeqCst, Ordering::SeqCst) | ||
| 346 | .is_err() | ||
| 347 | { | ||
| 348 | return None; | ||
| 349 | } | ||
| 350 | |||
| 351 | Some(init_secondary_hw(shared_data)) | ||
| 352 | } | ||
| 353 | |||
| 354 | /// Initialize the `embassy-stm32` HAL based on the init done by the other core using [init_primary]. | ||
| 355 | /// | ||
| 356 | /// This returns the peripheral singletons that can be used for creating drivers when the other core is done with its init. | ||
| 357 | /// If the other core is not done yet, this will spinloop wait on it. | ||
| 358 | /// | ||
| 359 | /// This should only be called once at startup, otherwise it may panic. | ||
| 360 | /// | ||
| 361 | /// The `shared_data` is used to coordinate the init with the second core. Read the [SharedData] docs | ||
| 362 | /// for more information on its requirements. | ||
| 363 | pub fn init_secondary(shared_data: &'static MaybeUninit<SharedData>) -> Peripherals { | ||
| 364 | let shared_data = unsafe { shared_data.assume_init_ref() }; | ||
| 365 | |||
| 366 | while shared_data | ||
| 367 | .init_flag | ||
| 368 | .compare_exchange(INIT_DONE_FLAG, 0, Ordering::SeqCst, Ordering::SeqCst) | ||
| 369 | .is_err() | ||
| 370 | {} | ||
| 371 | |||
| 372 | init_secondary_hw(shared_data) | ||
| 373 | } | ||
| 374 | |||
| 375 | fn init_secondary_hw(shared_data: &'static SharedData) -> Peripherals { | ||
| 376 | rcc::set_freqs_ptr(&shared_data.clocks); | ||
| 377 | |||
| 378 | // We use different timers on the different cores, so we have to still initialize one here | ||
| 379 | critical_section::with(|cs| { | ||
| 380 | // must be after rcc init | ||
| 381 | #[cfg(feature = "_time-driver")] | ||
| 382 | time_driver::init(cs); | ||
| 383 | }); | ||
| 384 | |||
| 385 | Peripherals::take() | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | #[cfg(feature = "_dual-core")] | ||
| 390 | pub use dual_core::*; | ||
| 391 | |||
| 392 | fn init_hw(config: Config) -> Peripherals { | ||
| 277 | critical_section::with(|cs| { | 393 | critical_section::with(|cs| { |
| 278 | let p = Peripherals::take_with_cs(cs); | 394 | let p = Peripherals::take_with_cs(cs); |
| 279 | 395 | ||
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 024c63cf5..587231b0c 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -48,11 +48,22 @@ pub(crate) static mut REFCOUNT_STOP1: u32 = 0; | |||
| 48 | /// May be read without a critical section | 48 | /// May be read without a critical section |
| 49 | pub(crate) static mut REFCOUNT_STOP2: u32 = 0; | 49 | pub(crate) static mut REFCOUNT_STOP2: u32 = 0; |
| 50 | 50 | ||
| 51 | #[cfg(not(feature = "_dual-core"))] | ||
| 51 | /// Frozen clock frequencies | 52 | /// Frozen clock frequencies |
| 52 | /// | 53 | /// |
| 53 | /// The existence of this value indicates that the clock configuration can no longer be changed | 54 | /// The existence of this value indicates that the clock configuration can no longer be changed |
| 54 | static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit(); | 55 | static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit(); |
| 55 | 56 | ||
| 57 | #[cfg(feature = "_dual-core")] | ||
| 58 | static CLOCK_FREQS_PTR: core::sync::atomic::AtomicPtr<MaybeUninit<Clocks>> = | ||
| 59 | core::sync::atomic::AtomicPtr::new(core::ptr::null_mut()); | ||
| 60 | |||
| 61 | #[cfg(feature = "_dual-core")] | ||
| 62 | pub(crate) fn set_freqs_ptr(freqs: &'static MaybeUninit<Clocks>) { | ||
| 63 | CLOCK_FREQS_PTR.store(freqs as *const _ as *mut _, core::sync::atomic::Ordering::SeqCst); | ||
| 64 | } | ||
| 65 | |||
| 66 | #[cfg(not(feature = "_dual-core"))] | ||
| 56 | /// Sets the clock frequencies | 67 | /// Sets the clock frequencies |
| 57 | /// | 68 | /// |
| 58 | /// Safety: Sets a mutable global. | 69 | /// Safety: Sets a mutable global. |
| @@ -61,11 +72,27 @@ pub(crate) unsafe fn set_freqs(freqs: Clocks) { | |||
| 61 | CLOCK_FREQS = MaybeUninit::new(freqs); | 72 | CLOCK_FREQS = MaybeUninit::new(freqs); |
| 62 | } | 73 | } |
| 63 | 74 | ||
| 75 | #[cfg(feature = "_dual-core")] | ||
| 76 | /// Sets the clock frequencies | ||
| 77 | /// | ||
| 78 | /// Safety: Sets a mutable global. | ||
| 79 | pub(crate) unsafe fn set_freqs(freqs: Clocks) { | ||
| 80 | debug!("rcc: {:?}", freqs); | ||
| 81 | CLOCK_FREQS_PTR.load(core::sync::atomic::Ordering::SeqCst).write(MaybeUninit::new(freqs)); | ||
| 82 | } | ||
| 83 | |||
| 84 | #[cfg(not(feature = "_dual-core"))] | ||
| 64 | /// Safety: Reads a mutable global. | 85 | /// Safety: Reads a mutable global. |
| 65 | pub(crate) unsafe fn get_freqs() -> &'static Clocks { | 86 | pub(crate) unsafe fn get_freqs() -> &'static Clocks { |
| 66 | CLOCK_FREQS.assume_init_ref() | 87 | CLOCK_FREQS.assume_init_ref() |
| 67 | } | 88 | } |
| 68 | 89 | ||
| 90 | #[cfg(feature = "_dual-core")] | ||
| 91 | /// Safety: Reads a mutable global. | ||
| 92 | pub(crate) unsafe fn get_freqs() -> &'static Clocks { | ||
| 93 | unwrap!(CLOCK_FREQS_PTR.load(core::sync::atomic::Ordering::SeqCst).as_ref()).assume_init_ref() | ||
| 94 | } | ||
| 95 | |||
| 69 | pub(crate) trait SealedRccPeripheral { | 96 | pub(crate) trait SealedRccPeripheral { |
| 70 | fn frequency() -> Hertz; | 97 | fn frequency() -> Hertz; |
| 71 | const RCC_INFO: RccInfo; | 98 | const RCC_INFO: RccInfo; |
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index a7f70b153..fe57cfe66 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs | |||
| @@ -168,7 +168,7 @@ impl Rtc { | |||
| 168 | 168 | ||
| 169 | fn frequency() -> Hertz { | 169 | fn frequency() -> Hertz { |
| 170 | let freqs = unsafe { crate::rcc::get_freqs() }; | 170 | let freqs = unsafe { crate::rcc::get_freqs() }; |
| 171 | freqs.rtc.unwrap() | 171 | freqs.rtc.to_hertz().unwrap() |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | /// Acquire a [`RtcTimeProvider`] instance. | 174 | /// Acquire a [`RtcTimeProvider`] instance. |
diff --git a/embassy-stm32/src/time.rs b/embassy-stm32/src/time.rs index 17690aefc..d7337191d 100644 --- a/embassy-stm32/src/time.rs +++ b/embassy-stm32/src/time.rs | |||
| @@ -87,3 +87,39 @@ impl Div<Hertz> for Hertz { | |||
| 87 | self.0 / rhs.0 | 87 | self.0 / rhs.0 |
| 88 | } | 88 | } |
| 89 | } | 89 | } |
| 90 | |||
| 91 | #[repr(C)] | ||
| 92 | #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug, Default)] | ||
| 93 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 94 | /// A variant on [Hertz] that acts as an `Option<Hertz>` that is smaller and repr C. | ||
| 95 | /// | ||
| 96 | /// An `Option<Hertz>` can be `.into()`'d into this type and back. | ||
| 97 | /// The only restriction is that that [Hertz] cannot have the value 0 since that's | ||
| 98 | /// seen as the `None` variant. | ||
| 99 | pub struct MaybeHertz(u32); | ||
| 100 | |||
| 101 | impl MaybeHertz { | ||
| 102 | /// Same as calling the `.into()` function, but without type inference. | ||
| 103 | pub fn to_hertz(self) -> Option<Hertz> { | ||
| 104 | self.into() | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | impl From<Option<Hertz>> for MaybeHertz { | ||
| 109 | fn from(value: Option<Hertz>) -> Self { | ||
| 110 | match value { | ||
| 111 | Some(Hertz(0)) => panic!("Hertz cannot be 0"), | ||
| 112 | Some(Hertz(val)) => Self(val), | ||
| 113 | None => Self(0), | ||
| 114 | } | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 118 | impl From<MaybeHertz> for Option<Hertz> { | ||
| 119 | fn from(value: MaybeHertz) -> Self { | ||
| 120 | match value { | ||
| 121 | MaybeHertz(0) => None, | ||
| 122 | MaybeHertz(val) => Some(Hertz(val)), | ||
| 123 | } | ||
| 124 | } | ||
| 125 | } | ||
