aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-09-16 02:06:22 +0000
committerGitHub <[email protected]>2023-09-16 02:06:22 +0000
commit80d7193b5b7442fb7a9cee00a5a51300778acdcd (patch)
tree6eaa13745fc8df757e07c9c4e749aa7343a7f206
parentf27620cc0b7a50c0ba5e93c96a6a88be252af286 (diff)
parent8315cf064eab133006e1397819b50f072fec6398 (diff)
Merge pull request #1911 from embassy-rs/stm32wba
stm32: add stm32wba support.
-rwxr-xr-x.github/ci/build-stable.sh4
-rwxr-xr-x.github/ci/build.sh4
-rwxr-xr-x.github/ci/test.sh4
-rwxr-xr-xci.sh1
-rw-r--r--embassy-stm32/Cargo.toml9
-rw-r--r--embassy-stm32/build.rs13
-rw-r--r--embassy-stm32/src/lib.rs2
-rw-r--r--embassy-stm32/src/rcc/bd.rs110
-rw-r--r--embassy-stm32/src/rcc/bus.rs6
-rw-r--r--embassy-stm32/src/rcc/mod.rs8
-rw-r--r--embassy-stm32/src/rcc/u5.rs2
-rw-r--r--embassy-stm32/src/rcc/wba.rs184
-rw-r--r--embassy-stm32/src/rtc/mod.rs2
-rw-r--r--examples/stm32wba/.cargo/config.toml8
-rw-r--r--examples/stm32wba/Cargo.toml26
-rw-r--r--examples/stm32wba/build.rs10
-rw-r--r--examples/stm32wba/src/bin/blinky.rs27
-rw-r--r--examples/stm32wba/src/bin/button_exti.rs27
18 files changed, 361 insertions, 86 deletions
diff --git a/.github/ci/build-stable.sh b/.github/ci/build-stable.sh
index 0dadd6102..8012f6923 100755
--- a/.github/ci/build-stable.sh
+++ b/.github/ci/build-stable.sh
@@ -8,6 +8,10 @@ export RUSTUP_HOME=/ci/cache/rustup
8export CARGO_HOME=/ci/cache/cargo 8export CARGO_HOME=/ci/cache/cargo
9export CARGO_TARGET_DIR=/ci/cache/target 9export CARGO_TARGET_DIR=/ci/cache/target
10 10
11# needed for "dumb HTTP" transport support
12# used when pointing stm32-metapac to a CI-built one.
13export CARGO_NET_GIT_FETCH_WITH_CLI=true
14
11hashtime restore /ci/cache/filetime.json || true 15hashtime restore /ci/cache/filetime.json || true
12hashtime save /ci/cache/filetime.json 16hashtime save /ci/cache/filetime.json
13 17
diff --git a/.github/ci/build.sh b/.github/ci/build.sh
index 36bf7e7dc..78ab976df 100755
--- a/.github/ci/build.sh
+++ b/.github/ci/build.sh
@@ -14,6 +14,10 @@ if [ -f /ci/secrets/teleprobe-token.txt ]; then
14 export TELEPROBE_CACHE=/ci/cache/teleprobe_cache.json 14 export TELEPROBE_CACHE=/ci/cache/teleprobe_cache.json
15fi 15fi
16 16
17# needed for "dumb HTTP" transport support
18# used when pointing stm32-metapac to a CI-built one.
19export CARGO_NET_GIT_FETCH_WITH_CLI=true
20
17hashtime restore /ci/cache/filetime.json || true 21hashtime restore /ci/cache/filetime.json || true
18hashtime save /ci/cache/filetime.json 22hashtime save /ci/cache/filetime.json
19 23
diff --git a/.github/ci/test.sh b/.github/ci/test.sh
index 04f4fc7c4..af0f21c2a 100755
--- a/.github/ci/test.sh
+++ b/.github/ci/test.sh
@@ -8,6 +8,10 @@ export RUSTUP_HOME=/ci/cache/rustup
8export CARGO_HOME=/ci/cache/cargo 8export CARGO_HOME=/ci/cache/cargo
9export CARGO_TARGET_DIR=/ci/cache/target 9export CARGO_TARGET_DIR=/ci/cache/target
10 10
11# needed for "dumb HTTP" transport support
12# used when pointing stm32-metapac to a CI-built one.
13export CARGO_NET_GIT_FETCH_WITH_CLI=true
14
11hashtime restore /ci/cache/filetime.json || true 15hashtime restore /ci/cache/filetime.json || true
12hashtime save /ci/cache/filetime.json 16hashtime save /ci/cache/filetime.json
13 17
diff --git a/ci.sh b/ci.sh
index da35c5a45..a3d9ef81a 100755
--- a/ci.sh
+++ b/ci.sh
@@ -145,6 +145,7 @@ cargo batch \
145 --- build --release --manifest-path examples/stm32l5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32l5 \ 145 --- build --release --manifest-path examples/stm32l5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32l5 \
146 --- build --release --manifest-path examples/stm32u5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32u5 \ 146 --- build --release --manifest-path examples/stm32u5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32u5 \
147 --- build --release --manifest-path examples/stm32wb/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wb \ 147 --- build --release --manifest-path examples/stm32wb/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wb \
148 --- build --release --manifest-path examples/stm32wba/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32wba \
148 --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wl \ 149 --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wl \
149 --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840,skip-include --out-dir out/examples/boot/nrf52840 \ 150 --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840,skip-include --out-dir out/examples/boot/nrf52840 \
150 --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns,skip-include --out-dir out/examples/boot/nrf9160 \ 151 --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns,skip-include --out-dir out/examples/boot/nrf9160 \
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 51909e43b..699995bc5 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -27,6 +27,7 @@ flavors = [
27 { regex_feature = "stm32l5.*", target = "thumbv8m.main-none-eabihf" }, 27 { regex_feature = "stm32l5.*", target = "thumbv8m.main-none-eabihf" },
28 { regex_feature = "stm32u5.*", target = "thumbv8m.main-none-eabihf" }, 28 { regex_feature = "stm32u5.*", target = "thumbv8m.main-none-eabihf" },
29 { regex_feature = "stm32wb.*", target = "thumbv7em-none-eabi" }, 29 { regex_feature = "stm32wb.*", target = "thumbv7em-none-eabi" },
30 { regex_feature = "stm32wba.*", target = "thumbv8m.main-none-eabihf" },
30 { regex_feature = "stm32wl.*", target = "thumbv7em-none-eabi" }, 31 { regex_feature = "stm32wl.*", target = "thumbv7em-none-eabi" },
31] 32]
32 33
@@ -58,7 +59,7 @@ sdio-host = "0.5.0"
58embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } 59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
59critical-section = "1.1" 60critical-section = "1.1"
60atomic-polyfill = "1.0.1" 61atomic-polyfill = "1.0.1"
61stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4d58d2d6648d526feb6bc45748dc73a05d41a5f3" } 62stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-546aead07086342605102d66dec49c5e2d459a0c" }
62vcell = "0.1.3" 63vcell = "0.1.3"
63bxcan = "0.7.0" 64bxcan = "0.7.0"
64nb = "1.0.0" 65nb = "1.0.0"
@@ -77,7 +78,7 @@ critical-section = { version = "1.1", features = ["std"] }
77[build-dependencies] 78[build-dependencies]
78proc-macro2 = "1.0.36" 79proc-macro2 = "1.0.36"
79quote = "1.0.15" 80quote = "1.0.15"
80stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4d58d2d6648d526feb6bc45748dc73a05d41a5f3", default-features = false, features = ["metadata"]} 81stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-546aead07086342605102d66dec49c5e2d459a0c", default-features = false, features = ["metadata"]}
81 82
82[features] 83[features]
83default = ["rt"] 84default = ["rt"]
@@ -1454,6 +1455,10 @@ stm32wb55vc = [ "stm32-metapac/stm32wb55vc" ]
1454stm32wb55ve = [ "stm32-metapac/stm32wb55ve" ] 1455stm32wb55ve = [ "stm32-metapac/stm32wb55ve" ]
1455stm32wb55vg = [ "stm32-metapac/stm32wb55vg" ] 1456stm32wb55vg = [ "stm32-metapac/stm32wb55vg" ]
1456stm32wb55vy = [ "stm32-metapac/stm32wb55vy" ] 1457stm32wb55vy = [ "stm32-metapac/stm32wb55vy" ]
1458stm32wba52ce = [ "stm32-metapac/stm32wba52ce" ]
1459stm32wba52cg = [ "stm32-metapac/stm32wba52cg" ]
1460stm32wba52ke = [ "stm32-metapac/stm32wba52ke" ]
1461stm32wba52kg = [ "stm32-metapac/stm32wba52kg" ]
1457stm32wl54cc-cm4 = [ "stm32-metapac/stm32wl54cc-cm4" ] 1462stm32wl54cc-cm4 = [ "stm32-metapac/stm32wl54cc-cm4" ]
1458stm32wl54cc-cm0p = [ "stm32-metapac/stm32wl54cc-cm0p" ] 1463stm32wl54cc-cm0p = [ "stm32-metapac/stm32wl54cc-cm0p" ]
1459stm32wl54jc-cm4 = [ "stm32-metapac/stm32wl54jc-cm4" ] 1464stm32wl54jc-cm4 = [ "stm32-metapac/stm32wl54jc-cm4" ]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 6d7f788db..b36af4795 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -1005,10 +1005,15 @@ fn main() {
1005 // ======= 1005 // =======
1006 // Features for targeting groups of chips 1006 // Features for targeting groups of chips
1007 1007
1008 println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4 1008 if &chip_name[..8] == "stm32wba" {
1009 println!("cargo:rustc-cfg={}", &chip_name[..9]); // stm32f429 1009 println!("cargo:rustc-cfg={}", &chip_name[..8]); // stm32wba
1010 println!("cargo:rustc-cfg={}x", &chip_name[..8]); // stm32f42x 1010 println!("cargo:rustc-cfg={}", &chip_name[..10]); // stm32wba52
1011 println!("cargo:rustc-cfg={}x{}", &chip_name[..7], &chip_name[8..9]); // stm32f4x9 1011 } else {
1012 println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4
1013 println!("cargo:rustc-cfg={}", &chip_name[..9]); // stm32f429
1014 println!("cargo:rustc-cfg={}x", &chip_name[..8]); // stm32f42x
1015 println!("cargo:rustc-cfg={}x{}", &chip_name[..7], &chip_name[8..9]); // stm32f4x9
1016 }
1012 1017
1013 // Handle time-driver-XXXX features. 1018 // Handle time-driver-XXXX features.
1014 if env::var("CARGO_FEATURE_TIME_DRIVER_ANY").is_ok() {} 1019 if env::var("CARGO_FEATURE_TIME_DRIVER_ANY").is_ok() {}
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index ec8648ee4..6a53f8762 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -154,7 +154,7 @@ pub fn init(config: Config) -> Peripherals {
154 #[cfg(dbgmcu)] 154 #[cfg(dbgmcu)]
155 if config.enable_debug_during_sleep { 155 if config.enable_debug_during_sleep {
156 crate::pac::DBGMCU.cr().modify(|cr| { 156 crate::pac::DBGMCU.cr().modify(|cr| {
157 #[cfg(any(dbgmcu_f0, dbgmcu_c0, dbgmcu_g0, dbgmcu_u5))] 157 #[cfg(any(dbgmcu_f0, dbgmcu_c0, dbgmcu_g0, dbgmcu_u5, dbgmcu_wba))]
158 { 158 {
159 cr.set_dbg_stop(true); 159 cr.set_dbg_stop(true);
160 cr.set_dbg_standby(true); 160 cr.set_dbg_standby(true);
diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs
index 059a32116..d774b993b 100644
--- a/embassy-stm32/src/rcc/bd.rs
+++ b/embassy-stm32/src/rcc/bd.rs
@@ -26,19 +26,7 @@ impl From<LseDrive> for crate::pac::rcc::vals::Lsedrv {
26 } 26 }
27} 27}
28 28
29#[allow(dead_code)] 29pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource;
30#[derive(Copy, Clone, Debug, PartialEq)]
31#[repr(u8)]
32pub enum RtcClockSource {
33 /// 00: No clock
34 NoClock = 0b00,
35 /// 01: LSE oscillator clock used as RTC clock
36 LSE = 0b01,
37 /// 10: LSI oscillator clock used as RTC clock
38 LSI = 0b10,
39 /// 11: HSE oscillator clock divided by 32 used as RTC clock
40 HSE = 0b11,
41}
42 30
43#[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))] 31#[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))]
44#[allow(dead_code)] 32#[allow(dead_code)]
@@ -109,17 +97,17 @@ impl BackupDomain {
109 let csr = crate::pac::RCC.csr(); 97 let csr = crate::pac::RCC.csr();
110 98
111 Self::modify(|_| { 99 Self::modify(|_| {
112 #[cfg(not(rtc_v2wb))] 100 #[cfg(not(any(rcc_wb, rcc_wba)))]
113 csr.modify(|w| w.set_lsion(true)); 101 csr.modify(|w| w.set_lsion(true));
114 102
115 #[cfg(rtc_v2wb)] 103 #[cfg(any(rcc_wb, rcc_wba))]
116 csr.modify(|w| w.set_lsi1on(true)); 104 csr.modify(|w| w.set_lsi1on(true));
117 }); 105 });
118 106
119 #[cfg(not(rtc_v2wb))] 107 #[cfg(not(any(rcc_wb, rcc_wba)))]
120 while !csr.read().lsirdy() {} 108 while !csr.read().lsirdy() {}
121 109
122 #[cfg(rtc_v2wb)] 110 #[cfg(any(rcc_wb, rcc_wba))]
123 while !csr.read().lsi1rdy() {} 111 while !csr.read().lsi1rdy() {}
124 } 112 }
125 RtcClockSource::LSE => { 113 RtcClockSource::LSE => {
@@ -136,64 +124,50 @@ impl BackupDomain {
136 _ => {} 124 _ => {}
137 }; 125 };
138 126
139 Self::configure_rtc(clock_source); 127 if clock_source == RtcClockSource::NOCLOCK {
140 } 128 // disable it
141 129 Self::modify(|w| {
142 #[cfg(any( 130 #[cfg(not(rcc_wba))]
143 rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, 131 w.set_rtcen(false);
144 rtc_v3u5 132 w.set_rtcsel(clock_source);
145 ))] 133 });
146 #[allow(dead_code, unused_variables)] 134 } else {
147 pub fn configure_rtc(clock_source: RtcClockSource) { 135 // check if it's already enabled and in the source we want.
148 let clock_source = clock_source as u8; 136 let reg = Self::read();
149 #[cfg(any( 137 let ok = reg.rtcsel() == clock_source;
150 not(any(rtc_v3, rtc_v3u5, rtc_v2wb)), 138 #[cfg(not(rcc_wba))]
151 all(any(rtc_v3, rtc_v3u5), not(any(rcc_wl5, rcc_wle))) 139 let ok = ok & reg.rtcen();
152 ))]
153 let clock_source = crate::pac::rcc::vals::Rtcsel::from_bits(clock_source);
154
155 #[cfg(not(rtc_v2wb))]
156 Self::modify(|w| {
157 // Select RTC source
158 w.set_rtcsel(clock_source);
159 });
160 }
161
162 #[cfg(any(
163 rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
164 rtc_v3u5
165 ))]
166 #[allow(dead_code)]
167 pub fn enable_rtc() {
168 let reg = Self::read();
169 140
170 #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] 141 // if not, configure it.
171 assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); 142 if !ok {
143 #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
144 assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
172 145
173 if !reg.rtcen() { 146 #[cfg(not(any(rcc_l0, rcc_l1)))]
174 #[cfg(not(any(rtc_v2l0, rtc_v2l1, rtc_v2f2)))] 147 Self::modify(|w| w.set_bdrst(true));
175 Self::modify(|w| w.set_bdrst(true));
176 148
177 Self::modify(|w| { 149 Self::modify(|w| {
178 // Reset 150 // Reset
179 #[cfg(not(any(rtc_v2l0, rtc_v2l1, rtc_v2f2)))] 151 #[cfg(not(any(rcc_l0, rcc_l1)))]
180 w.set_bdrst(false); 152 w.set_bdrst(false);
181 153
182 w.set_rtcen(true); 154 #[cfg(not(rcc_wba))]
183 w.set_rtcsel(reg.rtcsel()); 155 w.set_rtcen(true);
156 w.set_rtcsel(clock_source);
184 157
185 // Restore bcdr 158 // Restore bcdr
186 #[cfg(any(rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] 159 #[cfg(any(rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
187 w.set_lscosel(reg.lscosel()); 160 w.set_lscosel(reg.lscosel());
188 #[cfg(any(rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] 161 #[cfg(any(rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
189 w.set_lscoen(reg.lscoen()); 162 w.set_lscoen(reg.lscoen());
190 163
191 w.set_lseon(reg.lseon()); 164 w.set_lseon(reg.lseon());
192 165
193 #[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] 166 #[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
194 w.set_lsedrv(reg.lsedrv()); 167 w.set_lsedrv(reg.lsedrv());
195 w.set_lsebyp(reg.lsebyp()); 168 w.set_lsebyp(reg.lsebyp());
196 }); 169 });
170 }
197 } 171 }
198 } 172 }
199} 173}
diff --git a/embassy-stm32/src/rcc/bus.rs b/embassy-stm32/src/rcc/bus.rs
index 62736a43a..32e10b7ec 100644
--- a/embassy-stm32/src/rcc/bus.rs
+++ b/embassy-stm32/src/rcc/bus.rs
@@ -79,10 +79,7 @@ impl From<AHBPrescaler> for rcc::vals::Hpre {
79 use rcc::vals::Hpre; 79 use rcc::vals::Hpre;
80 80
81 match val { 81 match val {
82 #[cfg(not(rcc_u5))]
83 AHBPrescaler::NotDivided => Hpre::DIV1, 82 AHBPrescaler::NotDivided => Hpre::DIV1,
84 #[cfg(rcc_u5)]
85 AHBPrescaler::NotDivided => Hpre::NONE,
86 AHBPrescaler::Div2 => Hpre::DIV2, 83 AHBPrescaler::Div2 => Hpre::DIV2,
87 AHBPrescaler::Div4 => Hpre::DIV4, 84 AHBPrescaler::Div4 => Hpre::DIV4,
88 AHBPrescaler::Div8 => Hpre::DIV8, 85 AHBPrescaler::Div8 => Hpre::DIV8,
@@ -148,10 +145,7 @@ impl From<APBPrescaler> for rcc::vals::Ppre {
148 use rcc::vals::Ppre; 145 use rcc::vals::Ppre;
149 146
150 match val { 147 match val {
151 #[cfg(not(rcc_u5))]
152 APBPrescaler::NotDivided => Ppre::DIV1, 148 APBPrescaler::NotDivided => Ppre::DIV1,
153 #[cfg(rcc_u5)]
154 APBPrescaler::NotDivided => Ppre::NONE,
155 APBPrescaler::Div2 => Ppre::DIV2, 149 APBPrescaler::Div2 => Ppre::DIV2,
156 APBPrescaler::Div4 => Ppre::DIV4, 150 APBPrescaler::Div4 => Ppre::DIV4,
157 APBPrescaler::Div8 => Ppre::DIV8, 151 APBPrescaler::Div8 => Ppre::DIV8,
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 4f0b7fd09..b8c12b995 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -1,6 +1,7 @@
1#![macro_use] 1#![macro_use]
2 2
3pub(crate) mod bd; 3pub(crate) mod bd;
4#[cfg(not(rcc_wba))]
4pub mod bus; 5pub mod bus;
5use core::mem::MaybeUninit; 6use core::mem::MaybeUninit;
6 7
@@ -23,6 +24,7 @@ use crate::time::Hertz;
23#[cfg_attr(rcc_l5, path = "l5.rs")] 24#[cfg_attr(rcc_l5, path = "l5.rs")]
24#[cfg_attr(rcc_u5, path = "u5.rs")] 25#[cfg_attr(rcc_u5, path = "u5.rs")]
25#[cfg_attr(rcc_wb, path = "wb.rs")] 26#[cfg_attr(rcc_wb, path = "wb.rs")]
27#[cfg_attr(rcc_wba, path = "wba.rs")]
26#[cfg_attr(any(rcc_wl5, rcc_wle), path = "wl.rs")] 28#[cfg_attr(any(rcc_wl5, rcc_wle), path = "wl.rs")]
27#[cfg_attr(any(rcc_h5, rcc_h50), path = "h5.rs")] 29#[cfg_attr(any(rcc_h5, rcc_h50), path = "h5.rs")]
28mod _version; 30mod _version;
@@ -46,12 +48,14 @@ pub struct Clocks {
46 pub apb3: Hertz, 48 pub apb3: Hertz,
47 #[cfg(any(rcc_h7, rcc_h7ab))] 49 #[cfg(any(rcc_h7, rcc_h7ab))]
48 pub apb4: Hertz, 50 pub apb4: Hertz,
51 #[cfg(any(rcc_wba))]
52 pub apb7: Hertz,
49 53
50 // AHB 54 // AHB
51 pub ahb1: Hertz, 55 pub ahb1: Hertz,
52 #[cfg(any( 56 #[cfg(any(
53 rcc_l4, rcc_l5, rcc_f2, rcc_f4, rcc_f410, rcc_f7, rcc_h5, rcc_h50, rcc_h7, rcc_h7ab, rcc_g4, rcc_u5, rcc_wb, 57 rcc_l4, rcc_l5, rcc_f2, rcc_f4, rcc_f410, rcc_f7, rcc_h5, rcc_h50, rcc_h7, rcc_h7ab, rcc_g4, rcc_u5, rcc_wb,
54 rcc_wl5, rcc_wle 58 rcc_wba, rcc_wl5, rcc_wle
55 ))] 59 ))]
56 pub ahb2: Hertz, 60 pub ahb2: Hertz,
57 #[cfg(any( 61 #[cfg(any(
@@ -59,7 +63,7 @@ pub struct Clocks {
59 rcc_wle 63 rcc_wle
60 ))] 64 ))]
61 pub ahb3: Hertz, 65 pub ahb3: Hertz,
62 #[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7ab))] 66 #[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7ab, rcc_wba))]
63 pub ahb4: Hertz, 67 pub ahb4: Hertz,
64 68
65 #[cfg(any(rcc_f2, rcc_f4, rcc_f410, rcc_f7))] 69 #[cfg(any(rcc_f2, rcc_f4, rcc_f410, rcc_f7))]
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs
index 4aca9cd3d..6540b1f5c 100644
--- a/embassy-stm32/src/rcc/u5.rs
+++ b/embassy-stm32/src/rcc/u5.rs
@@ -165,7 +165,7 @@ impl Into<Sw> for ClockSrc {
165 ClockSrc::MSI(..) => Sw::MSIS, 165 ClockSrc::MSI(..) => Sw::MSIS,
166 ClockSrc::HSE(..) => Sw::HSE, 166 ClockSrc::HSE(..) => Sw::HSE,
167 ClockSrc::HSI16 => Sw::HSI16, 167 ClockSrc::HSI16 => Sw::HSI16,
168 ClockSrc::PLL1R(..) => Sw::PLL1R, 168 ClockSrc::PLL1R(..) => Sw::PLL1_R,
169 } 169 }
170 } 170 }
171} 171}
diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs
new file mode 100644
index 000000000..2a11c9a22
--- /dev/null
+++ b/embassy-stm32/src/rcc/wba.rs
@@ -0,0 +1,184 @@
1use stm32_metapac::rcc::vals::{Pllsrc, Sw};
2
3use crate::pac::{FLASH, RCC};
4use crate::rcc::{set_freqs, Clocks};
5use crate::time::Hertz;
6
7/// HSI speed
8pub const HSI_FREQ: Hertz = Hertz(16_000_000);
9
10/// LSI speed
11pub const LSI_FREQ: Hertz = Hertz(32_000);
12
13pub use crate::pac::pwr::vals::Vos as VoltageScale;
14pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
15
16#[derive(Copy, Clone)]
17pub enum ClockSrc {
18 HSE(Hertz),
19 HSI16,
20}
21
22#[derive(Clone, Copy, Debug)]
23pub enum PllSrc {
24 HSE(Hertz),
25 HSI16,
26}
27
28impl Into<Pllsrc> for PllSrc {
29 fn into(self) -> Pllsrc {
30 match self {
31 PllSrc::HSE(..) => Pllsrc::HSE32,
32 PllSrc::HSI16 => Pllsrc::HSI16,
33 }
34 }
35}
36
37impl Into<Sw> for ClockSrc {
38 fn into(self) -> Sw {
39 match self {
40 ClockSrc::HSE(..) => Sw::HSE32,
41 ClockSrc::HSI16 => Sw::HSI16,
42 }
43 }
44}
45
46trait Div {
47 fn div(&self) -> u8;
48}
49
50impl Div for APBPrescaler {
51 fn div(&self) -> u8 {
52 match self {
53 Self::DIV1 => 1,
54 Self::DIV2 => 2,
55 Self::DIV4 => 4,
56 Self::DIV8 => 8,
57 Self::DIV16 => 16,
58 _ => unreachable!(),
59 }
60 }
61}
62
63impl Div for AHBPrescaler {
64 fn div(&self) -> u8 {
65 match self {
66 Self::DIV1 => 1,
67 Self::DIV2 => 2,
68 Self::DIV4 => 4,
69 Self::DIV8 => 8,
70 Self::DIV16 => 16,
71 _ => unreachable!(),
72 }
73 }
74}
75
76#[derive(Copy, Clone)]
77pub struct Config {
78 pub mux: ClockSrc,
79 pub ahb_pre: AHBPrescaler,
80 pub apb1_pre: APBPrescaler,
81 pub apb2_pre: APBPrescaler,
82 pub apb7_pre: APBPrescaler,
83}
84
85impl Default for Config {
86 fn default() -> Self {
87 Self {
88 mux: ClockSrc::HSI16,
89 ahb_pre: AHBPrescaler::DIV1,
90 apb1_pre: APBPrescaler::DIV1,
91 apb2_pre: APBPrescaler::DIV1,
92 apb7_pre: APBPrescaler::DIV1,
93 }
94 }
95}
96
97pub(crate) unsafe fn init(config: Config) {
98 let sys_clk = match config.mux {
99 ClockSrc::HSE(freq) => {
100 RCC.cr().write(|w| w.set_hseon(true));
101 while !RCC.cr().read().hserdy() {}
102
103 freq.0
104 }
105 ClockSrc::HSI16 => {
106 RCC.cr().write(|w| w.set_hsion(true));
107 while !RCC.cr().read().hsirdy() {}
108
109 HSI_FREQ.0
110 }
111 };
112
113 // TODO make configurable
114 let power_vos = VoltageScale::RANGE1;
115
116 // states and programming delay
117 let wait_states = match power_vos {
118 VoltageScale::RANGE1 => match sys_clk {
119 ..=32_000_000 => 0,
120 ..=64_000_000 => 1,
121 ..=96_000_000 => 2,
122 ..=100_000_000 => 3,
123 _ => 4,
124 },
125 VoltageScale::RANGE2 => match sys_clk {
126 ..=8_000_000 => 0,
127 ..=16_000_000 => 1,
128 _ => 2,
129 },
130 };
131
132 FLASH.acr().modify(|w| {
133 w.set_latency(wait_states);
134 });
135
136 RCC.cfgr1().modify(|w| {
137 w.set_sw(config.mux.into());
138 });
139
140 RCC.cfgr2().modify(|w| {
141 w.set_hpre(config.ahb_pre.into());
142 w.set_ppre1(config.apb1_pre.into());
143 w.set_ppre2(config.apb2_pre.into());
144 });
145
146 RCC.cfgr3().modify(|w| {
147 w.set_ppre7(config.apb7_pre.into());
148 });
149
150 let ahb_freq: u32 = sys_clk / config.ahb_pre.div() as u32;
151 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre.div() {
152 1 => (ahb_freq, ahb_freq),
153 div => {
154 let freq = ahb_freq / div as u32;
155 (freq, freq * 2)
156 }
157 };
158 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre.div() {
159 1 => (ahb_freq, ahb_freq),
160 div => {
161 let freq = ahb_freq / div as u32;
162 (freq, freq * 2)
163 }
164 };
165 let (apb7_freq, _apb7_tim_freq) = match config.apb7_pre.div() {
166 1 => (ahb_freq, ahb_freq),
167 div => {
168 let freq = ahb_freq / div as u32;
169 (freq, freq * 2)
170 }
171 };
172
173 set_freqs(Clocks {
174 sys: Hertz(sys_clk),
175 ahb1: Hertz(ahb_freq),
176 ahb2: Hertz(ahb_freq),
177 ahb4: Hertz(ahb_freq),
178 apb1: Hertz(apb1_freq),
179 apb2: Hertz(apb2_freq),
180 apb7: Hertz(apb7_freq),
181 apb1_tim: Hertz(apb1_tim_freq),
182 apb2_tim: Hertz(apb2_tim_freq),
183 });
184}
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 32a5cc123..3ecf477db 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -10,7 +10,6 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
10use embassy_sync::blocking_mutex::Mutex; 10use embassy_sync::blocking_mutex::Mutex;
11 11
12pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; 12pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError};
13use crate::rcc::bd::BackupDomain;
14pub use crate::rcc::RtcClockSource; 13pub use crate::rcc::RtcClockSource;
15use crate::time::Hertz; 14use crate::time::Hertz;
16 15
@@ -125,7 +124,6 @@ impl Default for RtcCalibrationCyclePeriod {
125impl Rtc { 124impl Rtc {
126 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { 125 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
127 RTC::enable_peripheral_clk(); 126 RTC::enable_peripheral_clk();
128 BackupDomain::enable_rtc();
129 127
130 let mut this = Self { 128 let mut this = Self {
131 #[cfg(feature = "low-power")] 129 #[cfg(feature = "low-power")]
diff --git a/examples/stm32wba/.cargo/config.toml b/examples/stm32wba/.cargo/config.toml
new file mode 100644
index 000000000..477413397
--- /dev/null
+++ b/examples/stm32wba/.cargo/config.toml
@@ -0,0 +1,8 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2runner = "probe-rs run --chip STM32WBA52CGUxT"
3
4[build]
5target = "thumbv8m.main-none-eabihf"
6
7[env]
8DEFMT_LOG = "trace"
diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml
new file mode 100644
index 000000000..26fcce26b
--- /dev/null
+++ b/examples/stm32wba/Cargo.toml
@@ -0,0 +1,26 @@
1[package]
2edition = "2021"
3name = "embassy-stm32wba-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"] }
9embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
10embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
11embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
12embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true }
13
14defmt = "0.3"
15defmt-rtt = "0.4"
16
17cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
18cortex-m-rt = "0.7.0"
19embedded-hal = "0.2.6"
20panic-probe = { version = "0.3", features = ["print-defmt"] }
21futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
22heapless = { version = "0.7.5", default-features = false }
23static_cell = { version = "1.1", features = ["nightly"]}
24
25[profile.release]
26debug = 2
diff --git a/examples/stm32wba/build.rs b/examples/stm32wba/build.rs
new file mode 100644
index 000000000..8fc6faab8
--- /dev/null
+++ b/examples/stm32wba/build.rs
@@ -0,0 +1,10 @@
1use std::error::Error;
2
3fn main() -> Result<(), Box<dyn Error>> {
4 println!("cargo:rerun-if-changed=link.x");
5 println!("cargo:rustc-link-arg-bins=--nmagic");
6 println!("cargo:rustc-link-arg-bins=-Tlink.x");
7 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
8
9 Ok(())
10}
diff --git a/examples/stm32wba/src/bin/blinky.rs b/examples/stm32wba/src/bin/blinky.rs
new file mode 100644
index 000000000..530746296
--- /dev/null
+++ b/examples/stm32wba/src/bin/blinky.rs
@@ -0,0 +1,27 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::*;
6use embassy_executor::Spawner;
7use embassy_stm32::gpio::{Level, Output, Speed};
8use embassy_time::{Duration, Timer};
9use {defmt_rtt as _, panic_probe as _};
10
11#[embassy_executor::main]
12async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!");
15
16 let mut led = Output::new(p.PB4, Level::High, Speed::Low);
17
18 loop {
19 info!("high");
20 led.set_high();
21 Timer::after(Duration::from_millis(500)).await;
22
23 info!("low");
24 led.set_low();
25 Timer::after(Duration::from_millis(500)).await;
26 }
27}
diff --git a/examples/stm32wba/src/bin/button_exti.rs b/examples/stm32wba/src/bin/button_exti.rs
new file mode 100644
index 000000000..ef32d4c4a
--- /dev/null
+++ b/examples/stm32wba/src/bin/button_exti.rs
@@ -0,0 +1,27 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::*;
6use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull};
9use {defmt_rtt as _, panic_probe as _};
10
11#[embassy_executor::main]
12async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!");
15
16 let button = Input::new(p.PC13, Pull::Up);
17 let mut button = ExtiInput::new(button, p.EXTI13);
18
19 info!("Press the USER button...");
20
21 loop {
22 button.wait_for_falling_edge().await;
23 info!("Pressed!");
24 button.wait_for_rising_edge().await;
25 info!("Released!");
26 }
27}