stm32: add stm32wba support.
This commit is contained in:
		
							parent
							
								
									a2a26f489b
								
							
						
					
					
						commit
						8315cf064e
					
				
							
								
								
									
										1
									
								
								ci.sh
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								ci.sh
									
									
									
									
									
								
							| @ -145,6 +145,7 @@ cargo batch  \ | |||||||
|     --- build --release --manifest-path examples/stm32l5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32l5 \ |     --- build --release --manifest-path examples/stm32l5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32l5 \ | ||||||
|     --- build --release --manifest-path examples/stm32u5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32u5 \ |     --- build --release --manifest-path examples/stm32u5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32u5 \ | ||||||
|     --- build --release --manifest-path examples/stm32wb/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wb \ |     --- build --release --manifest-path examples/stm32wb/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wb \ | ||||||
|  |     --- build --release --manifest-path examples/stm32wba/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32wba \ | ||||||
|     --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wl \ |     --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wl \ | ||||||
|     --- 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  \ |     --- 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  \ | ||||||
|     --- 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 \ |     --- 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 \ | ||||||
|  | |||||||
| @ -27,6 +27,7 @@ flavors = [ | |||||||
|     { regex_feature = "stm32l5.*", target = "thumbv8m.main-none-eabihf" }, |     { regex_feature = "stm32l5.*", target = "thumbv8m.main-none-eabihf" }, | ||||||
|     { regex_feature = "stm32u5.*", target = "thumbv8m.main-none-eabihf" }, |     { regex_feature = "stm32u5.*", target = "thumbv8m.main-none-eabihf" }, | ||||||
|     { regex_feature = "stm32wb.*", target = "thumbv7em-none-eabi" }, |     { regex_feature = "stm32wb.*", target = "thumbv7em-none-eabi" }, | ||||||
|  |     { regex_feature = "stm32wba.*", target = "thumbv8m.main-none-eabihf" }, | ||||||
|     { regex_feature = "stm32wl.*", target = "thumbv7em-none-eabi" }, |     { regex_feature = "stm32wl.*", target = "thumbv7em-none-eabi" }, | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| @ -58,7 +59,7 @@ sdio-host = "0.5.0" | |||||||
| embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } | ||||||
| critical-section = "1.1" | critical-section = "1.1" | ||||||
| atomic-polyfill = "1.0.1" | atomic-polyfill = "1.0.1" | ||||||
| stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4d58d2d6648d526feb6bc45748dc73a05d41a5f3" } | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-546aead07086342605102d66dec49c5e2d459a0c" } | ||||||
| vcell = "0.1.3" | vcell = "0.1.3" | ||||||
| bxcan = "0.7.0" | bxcan = "0.7.0" | ||||||
| nb = "1.0.0" | nb = "1.0.0" | ||||||
| @ -77,7 +78,7 @@ critical-section = { version = "1.1", features = ["std"] } | |||||||
| [build-dependencies] | [build-dependencies] | ||||||
| proc-macro2 = "1.0.36" | proc-macro2 = "1.0.36" | ||||||
| quote = "1.0.15" | quote = "1.0.15" | ||||||
| stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4d58d2d6648d526feb6bc45748dc73a05d41a5f3", default-features = false, features = ["metadata"]} | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-546aead07086342605102d66dec49c5e2d459a0c", default-features = false, features = ["metadata"]} | ||||||
| 
 | 
 | ||||||
| [features] | [features] | ||||||
| default = ["rt"] | default = ["rt"] | ||||||
| @ -1454,6 +1455,10 @@ stm32wb55vc = [ "stm32-metapac/stm32wb55vc" ] | |||||||
| stm32wb55ve = [ "stm32-metapac/stm32wb55ve" ] | stm32wb55ve = [ "stm32-metapac/stm32wb55ve" ] | ||||||
| stm32wb55vg = [ "stm32-metapac/stm32wb55vg" ] | stm32wb55vg = [ "stm32-metapac/stm32wb55vg" ] | ||||||
| stm32wb55vy = [ "stm32-metapac/stm32wb55vy" ] | stm32wb55vy = [ "stm32-metapac/stm32wb55vy" ] | ||||||
|  | stm32wba52ce = [ "stm32-metapac/stm32wba52ce" ] | ||||||
|  | stm32wba52cg = [ "stm32-metapac/stm32wba52cg" ] | ||||||
|  | stm32wba52ke = [ "stm32-metapac/stm32wba52ke" ] | ||||||
|  | stm32wba52kg = [ "stm32-metapac/stm32wba52kg" ] | ||||||
| stm32wl54cc-cm4 = [ "stm32-metapac/stm32wl54cc-cm4" ] | stm32wl54cc-cm4 = [ "stm32-metapac/stm32wl54cc-cm4" ] | ||||||
| stm32wl54cc-cm0p = [ "stm32-metapac/stm32wl54cc-cm0p" ] | stm32wl54cc-cm0p = [ "stm32-metapac/stm32wl54cc-cm0p" ] | ||||||
| stm32wl54jc-cm4 = [ "stm32-metapac/stm32wl54jc-cm4" ] | stm32wl54jc-cm4 = [ "stm32-metapac/stm32wl54jc-cm4" ] | ||||||
|  | |||||||
| @ -1005,10 +1005,15 @@ fn main() { | |||||||
|     // =======
 |     // =======
 | ||||||
|     // Features for targeting groups of chips
 |     // Features for targeting groups of chips
 | ||||||
| 
 | 
 | ||||||
|     println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4
 |     if &chip_name[..8] == "stm32wba" { | ||||||
|     println!("cargo:rustc-cfg={}", &chip_name[..9]); // stm32f429
 |         println!("cargo:rustc-cfg={}", &chip_name[..8]); // stm32wba
 | ||||||
|     println!("cargo:rustc-cfg={}x", &chip_name[..8]); // stm32f42x
 |         println!("cargo:rustc-cfg={}", &chip_name[..10]); // stm32wba52
 | ||||||
|     println!("cargo:rustc-cfg={}x{}", &chip_name[..7], &chip_name[8..9]); // stm32f4x9
 |     } else { | ||||||
|  |         println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4
 | ||||||
|  |         println!("cargo:rustc-cfg={}", &chip_name[..9]); // stm32f429
 | ||||||
|  |         println!("cargo:rustc-cfg={}x", &chip_name[..8]); // stm32f42x
 | ||||||
|  |         println!("cargo:rustc-cfg={}x{}", &chip_name[..7], &chip_name[8..9]); // stm32f4x9
 | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     // Handle time-driver-XXXX features.
 |     // Handle time-driver-XXXX features.
 | ||||||
|     if env::var("CARGO_FEATURE_TIME_DRIVER_ANY").is_ok() {} |     if env::var("CARGO_FEATURE_TIME_DRIVER_ANY").is_ok() {} | ||||||
|  | |||||||
| @ -154,7 +154,7 @@ pub fn init(config: Config) -> Peripherals { | |||||||
|     #[cfg(dbgmcu)] |     #[cfg(dbgmcu)] | ||||||
|     if config.enable_debug_during_sleep { |     if config.enable_debug_during_sleep { | ||||||
|         crate::pac::DBGMCU.cr().modify(|cr| { |         crate::pac::DBGMCU.cr().modify(|cr| { | ||||||
|             #[cfg(any(dbgmcu_f0, dbgmcu_c0, dbgmcu_g0, dbgmcu_u5))] |             #[cfg(any(dbgmcu_f0, dbgmcu_c0, dbgmcu_g0, dbgmcu_u5, dbgmcu_wba))] | ||||||
|             { |             { | ||||||
|                 cr.set_dbg_stop(true); |                 cr.set_dbg_stop(true); | ||||||
|                 cr.set_dbg_standby(true); |                 cr.set_dbg_standby(true); | ||||||
|  | |||||||
| @ -26,19 +26,7 @@ impl From<LseDrive> for crate::pac::rcc::vals::Lsedrv { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[allow(dead_code)] | pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource; | ||||||
| #[derive(Copy, Clone, Debug, PartialEq)] |  | ||||||
| #[repr(u8)] |  | ||||||
| pub enum RtcClockSource { |  | ||||||
|     /// 00: No clock
 |  | ||||||
|     NoClock = 0b00, |  | ||||||
|     /// 01: LSE oscillator clock used as RTC clock
 |  | ||||||
|     LSE = 0b01, |  | ||||||
|     /// 10: LSI oscillator clock used as RTC clock
 |  | ||||||
|     LSI = 0b10, |  | ||||||
|     /// 11: HSE oscillator clock divided by 32 used as RTC clock
 |  | ||||||
|     HSE = 0b11, |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| #[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))] | #[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))] | ||||||
| #[allow(dead_code)] | #[allow(dead_code)] | ||||||
| @ -109,17 +97,17 @@ impl BackupDomain { | |||||||
|                 let csr = crate::pac::RCC.csr(); |                 let csr = crate::pac::RCC.csr(); | ||||||
| 
 | 
 | ||||||
|                 Self::modify(|_| { |                 Self::modify(|_| { | ||||||
|                     #[cfg(not(rtc_v2wb))] |                     #[cfg(not(any(rcc_wb, rcc_wba)))] | ||||||
|                     csr.modify(|w| w.set_lsion(true)); |                     csr.modify(|w| w.set_lsion(true)); | ||||||
| 
 | 
 | ||||||
|                     #[cfg(rtc_v2wb)] |                     #[cfg(any(rcc_wb, rcc_wba))] | ||||||
|                     csr.modify(|w| w.set_lsi1on(true)); |                     csr.modify(|w| w.set_lsi1on(true)); | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|                 #[cfg(not(rtc_v2wb))] |                 #[cfg(not(any(rcc_wb, rcc_wba)))] | ||||||
|                 while !csr.read().lsirdy() {} |                 while !csr.read().lsirdy() {} | ||||||
| 
 | 
 | ||||||
|                 #[cfg(rtc_v2wb)] |                 #[cfg(any(rcc_wb, rcc_wba))] | ||||||
|                 while !csr.read().lsi1rdy() {} |                 while !csr.read().lsi1rdy() {} | ||||||
|             } |             } | ||||||
|             RtcClockSource::LSE => { |             RtcClockSource::LSE => { | ||||||
| @ -136,64 +124,50 @@ impl BackupDomain { | |||||||
|             _ => {} |             _ => {} | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         Self::configure_rtc(clock_source); |         if clock_source == RtcClockSource::NOCLOCK { | ||||||
|     } |             // disable it
 | ||||||
| 
 |  | ||||||
|     #[cfg(any(
 |  | ||||||
|         rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, |  | ||||||
|         rtc_v3u5 |  | ||||||
|     ))] |  | ||||||
|     #[allow(dead_code, unused_variables)] |  | ||||||
|     pub fn configure_rtc(clock_source: RtcClockSource) { |  | ||||||
|         let clock_source = clock_source as u8; |  | ||||||
|         #[cfg(any(
 |  | ||||||
|             not(any(rtc_v3, rtc_v3u5, rtc_v2wb)), |  | ||||||
|             all(any(rtc_v3, rtc_v3u5), not(any(rcc_wl5, rcc_wle))) |  | ||||||
|         ))] |  | ||||||
|         let clock_source = crate::pac::rcc::vals::Rtcsel::from_bits(clock_source); |  | ||||||
| 
 |  | ||||||
|         #[cfg(not(rtc_v2wb))] |  | ||||||
|         Self::modify(|w| { |  | ||||||
|             // Select RTC source
 |  | ||||||
|             w.set_rtcsel(clock_source); |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     #[cfg(any(
 |  | ||||||
|         rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, |  | ||||||
|         rtc_v3u5 |  | ||||||
|     ))] |  | ||||||
|     #[allow(dead_code)] |  | ||||||
|     pub fn enable_rtc() { |  | ||||||
|         let reg = Self::read(); |  | ||||||
| 
 |  | ||||||
|         #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] |  | ||||||
|         assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); |  | ||||||
| 
 |  | ||||||
|         if !reg.rtcen() { |  | ||||||
|             #[cfg(not(any(rtc_v2l0, rtc_v2l1, rtc_v2f2)))] |  | ||||||
|             Self::modify(|w| w.set_bdrst(true)); |  | ||||||
| 
 |  | ||||||
|             Self::modify(|w| { |             Self::modify(|w| { | ||||||
|                 // Reset
 |                 #[cfg(not(rcc_wba))] | ||||||
|                 #[cfg(not(any(rtc_v2l0, rtc_v2l1, rtc_v2f2)))] |                 w.set_rtcen(false); | ||||||
|                 w.set_bdrst(false); |                 w.set_rtcsel(clock_source); | ||||||
| 
 |  | ||||||
|                 w.set_rtcen(true); |  | ||||||
|                 w.set_rtcsel(reg.rtcsel()); |  | ||||||
| 
 |  | ||||||
|                 // Restore bcdr
 |  | ||||||
|                 #[cfg(any(rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] |  | ||||||
|                 w.set_lscosel(reg.lscosel()); |  | ||||||
|                 #[cfg(any(rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] |  | ||||||
|                 w.set_lscoen(reg.lscoen()); |  | ||||||
| 
 |  | ||||||
|                 w.set_lseon(reg.lseon()); |  | ||||||
| 
 |  | ||||||
|                 #[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] |  | ||||||
|                 w.set_lsedrv(reg.lsedrv()); |  | ||||||
|                 w.set_lsebyp(reg.lsebyp()); |  | ||||||
|             }); |             }); | ||||||
|  |         } else { | ||||||
|  |             // check if it's already enabled and in the source we want.
 | ||||||
|  |             let reg = Self::read(); | ||||||
|  |             let ok = reg.rtcsel() == clock_source; | ||||||
|  |             #[cfg(not(rcc_wba))] | ||||||
|  |             let ok = ok & reg.rtcen(); | ||||||
|  | 
 | ||||||
|  |             // if not, configure it.
 | ||||||
|  |             if !ok { | ||||||
|  |                 #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] | ||||||
|  |                 assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); | ||||||
|  | 
 | ||||||
|  |                 #[cfg(not(any(rcc_l0, rcc_l1)))] | ||||||
|  |                 Self::modify(|w| w.set_bdrst(true)); | ||||||
|  | 
 | ||||||
|  |                 Self::modify(|w| { | ||||||
|  |                     // Reset
 | ||||||
|  |                     #[cfg(not(any(rcc_l0, rcc_l1)))] | ||||||
|  |                     w.set_bdrst(false); | ||||||
|  | 
 | ||||||
|  |                     #[cfg(not(rcc_wba))] | ||||||
|  |                     w.set_rtcen(true); | ||||||
|  |                     w.set_rtcsel(clock_source); | ||||||
|  | 
 | ||||||
|  |                     // Restore bcdr
 | ||||||
|  |                     #[cfg(any(rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] | ||||||
|  |                     w.set_lscosel(reg.lscosel()); | ||||||
|  |                     #[cfg(any(rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] | ||||||
|  |                     w.set_lscoen(reg.lscoen()); | ||||||
|  | 
 | ||||||
|  |                     w.set_lseon(reg.lseon()); | ||||||
|  | 
 | ||||||
|  |                     #[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] | ||||||
|  |                     w.set_lsedrv(reg.lsedrv()); | ||||||
|  |                     w.set_lsebyp(reg.lsebyp()); | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -79,10 +79,7 @@ impl From<AHBPrescaler> for rcc::vals::Hpre { | |||||||
|         use rcc::vals::Hpre; |         use rcc::vals::Hpre; | ||||||
| 
 | 
 | ||||||
|         match val { |         match val { | ||||||
|             #[cfg(not(rcc_u5))] |  | ||||||
|             AHBPrescaler::NotDivided => Hpre::DIV1, |             AHBPrescaler::NotDivided => Hpre::DIV1, | ||||||
|             #[cfg(rcc_u5)] |  | ||||||
|             AHBPrescaler::NotDivided => Hpre::NONE, |  | ||||||
|             AHBPrescaler::Div2 => Hpre::DIV2, |             AHBPrescaler::Div2 => Hpre::DIV2, | ||||||
|             AHBPrescaler::Div4 => Hpre::DIV4, |             AHBPrescaler::Div4 => Hpre::DIV4, | ||||||
|             AHBPrescaler::Div8 => Hpre::DIV8, |             AHBPrescaler::Div8 => Hpre::DIV8, | ||||||
| @ -148,10 +145,7 @@ impl From<APBPrescaler> for rcc::vals::Ppre { | |||||||
|         use rcc::vals::Ppre; |         use rcc::vals::Ppre; | ||||||
| 
 | 
 | ||||||
|         match val { |         match val { | ||||||
|             #[cfg(not(rcc_u5))] |  | ||||||
|             APBPrescaler::NotDivided => Ppre::DIV1, |             APBPrescaler::NotDivided => Ppre::DIV1, | ||||||
|             #[cfg(rcc_u5)] |  | ||||||
|             APBPrescaler::NotDivided => Ppre::NONE, |  | ||||||
|             APBPrescaler::Div2 => Ppre::DIV2, |             APBPrescaler::Div2 => Ppre::DIV2, | ||||||
|             APBPrescaler::Div4 => Ppre::DIV4, |             APBPrescaler::Div4 => Ppre::DIV4, | ||||||
|             APBPrescaler::Div8 => Ppre::DIV8, |             APBPrescaler::Div8 => Ppre::DIV8, | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #![macro_use] | #![macro_use] | ||||||
| 
 | 
 | ||||||
| pub(crate) mod bd; | pub(crate) mod bd; | ||||||
|  | #[cfg(not(rcc_wba))] | ||||||
| pub mod bus; | pub mod bus; | ||||||
| use core::mem::MaybeUninit; | use core::mem::MaybeUninit; | ||||||
| 
 | 
 | ||||||
| @ -23,6 +24,7 @@ use crate::time::Hertz; | |||||||
| #[cfg_attr(rcc_l5, path = "l5.rs")] | #[cfg_attr(rcc_l5, path = "l5.rs")] | ||||||
| #[cfg_attr(rcc_u5, path = "u5.rs")] | #[cfg_attr(rcc_u5, path = "u5.rs")] | ||||||
| #[cfg_attr(rcc_wb, path = "wb.rs")] | #[cfg_attr(rcc_wb, path = "wb.rs")] | ||||||
|  | #[cfg_attr(rcc_wba, path = "wba.rs")] | ||||||
| #[cfg_attr(any(rcc_wl5, rcc_wle), path = "wl.rs")] | #[cfg_attr(any(rcc_wl5, rcc_wle), path = "wl.rs")] | ||||||
| #[cfg_attr(any(rcc_h5, rcc_h50), path = "h5.rs")] | #[cfg_attr(any(rcc_h5, rcc_h50), path = "h5.rs")] | ||||||
| mod _version; | mod _version; | ||||||
| @ -46,12 +48,14 @@ pub struct Clocks { | |||||||
|     pub apb3: Hertz, |     pub apb3: Hertz, | ||||||
|     #[cfg(any(rcc_h7, rcc_h7ab))] |     #[cfg(any(rcc_h7, rcc_h7ab))] | ||||||
|     pub apb4: Hertz, |     pub apb4: Hertz, | ||||||
|  |     #[cfg(any(rcc_wba))] | ||||||
|  |     pub apb7: Hertz, | ||||||
| 
 | 
 | ||||||
|     // AHB
 |     // AHB
 | ||||||
|     pub ahb1: Hertz, |     pub ahb1: Hertz, | ||||||
|     #[cfg(any(
 |     #[cfg(any(
 | ||||||
|         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, |         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, | ||||||
|         rcc_wl5, rcc_wle |         rcc_wba, rcc_wl5, rcc_wle | ||||||
|     ))] |     ))] | ||||||
|     pub ahb2: Hertz, |     pub ahb2: Hertz, | ||||||
|     #[cfg(any(
 |     #[cfg(any(
 | ||||||
| @ -59,7 +63,7 @@ pub struct Clocks { | |||||||
|         rcc_wle |         rcc_wle | ||||||
|     ))] |     ))] | ||||||
|     pub ahb3: Hertz, |     pub ahb3: Hertz, | ||||||
|     #[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7ab))] |     #[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7ab, rcc_wba))] | ||||||
|     pub ahb4: Hertz, |     pub ahb4: Hertz, | ||||||
| 
 | 
 | ||||||
|     #[cfg(any(rcc_f2, rcc_f4, rcc_f410, rcc_f7))] |     #[cfg(any(rcc_f2, rcc_f4, rcc_f410, rcc_f7))] | ||||||
|  | |||||||
| @ -165,7 +165,7 @@ impl Into<Sw> for ClockSrc { | |||||||
|             ClockSrc::MSI(..) => Sw::MSIS, |             ClockSrc::MSI(..) => Sw::MSIS, | ||||||
|             ClockSrc::HSE(..) => Sw::HSE, |             ClockSrc::HSE(..) => Sw::HSE, | ||||||
|             ClockSrc::HSI16 => Sw::HSI16, |             ClockSrc::HSI16 => Sw::HSI16, | ||||||
|             ClockSrc::PLL1R(..) => Sw::PLL1R, |             ClockSrc::PLL1R(..) => Sw::PLL1_R, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										184
									
								
								embassy-stm32/src/rcc/wba.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								embassy-stm32/src/rcc/wba.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,184 @@ | |||||||
|  | use stm32_metapac::rcc::vals::{Pllsrc, Sw}; | ||||||
|  | 
 | ||||||
|  | use crate::pac::{FLASH, RCC}; | ||||||
|  | use crate::rcc::{set_freqs, Clocks}; | ||||||
|  | use crate::time::Hertz; | ||||||
|  | 
 | ||||||
|  | /// HSI speed
 | ||||||
|  | pub const HSI_FREQ: Hertz = Hertz(16_000_000); | ||||||
|  | 
 | ||||||
|  | /// LSI speed
 | ||||||
|  | pub const LSI_FREQ: Hertz = Hertz(32_000); | ||||||
|  | 
 | ||||||
|  | pub use crate::pac::pwr::vals::Vos as VoltageScale; | ||||||
|  | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; | ||||||
|  | 
 | ||||||
|  | #[derive(Copy, Clone)] | ||||||
|  | pub enum ClockSrc { | ||||||
|  |     HSE(Hertz), | ||||||
|  |     HSI16, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Clone, Copy, Debug)] | ||||||
|  | pub enum PllSrc { | ||||||
|  |     HSE(Hertz), | ||||||
|  |     HSI16, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Into<Pllsrc> for PllSrc { | ||||||
|  |     fn into(self) -> Pllsrc { | ||||||
|  |         match self { | ||||||
|  |             PllSrc::HSE(..) => Pllsrc::HSE32, | ||||||
|  |             PllSrc::HSI16 => Pllsrc::HSI16, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Into<Sw> for ClockSrc { | ||||||
|  |     fn into(self) -> Sw { | ||||||
|  |         match self { | ||||||
|  |             ClockSrc::HSE(..) => Sw::HSE32, | ||||||
|  |             ClockSrc::HSI16 => Sw::HSI16, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | trait Div { | ||||||
|  |     fn div(&self) -> u8; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Div for APBPrescaler { | ||||||
|  |     fn div(&self) -> u8 { | ||||||
|  |         match self { | ||||||
|  |             Self::DIV1 => 1, | ||||||
|  |             Self::DIV2 => 2, | ||||||
|  |             Self::DIV4 => 4, | ||||||
|  |             Self::DIV8 => 8, | ||||||
|  |             Self::DIV16 => 16, | ||||||
|  |             _ => unreachable!(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Div for AHBPrescaler { | ||||||
|  |     fn div(&self) -> u8 { | ||||||
|  |         match self { | ||||||
|  |             Self::DIV1 => 1, | ||||||
|  |             Self::DIV2 => 2, | ||||||
|  |             Self::DIV4 => 4, | ||||||
|  |             Self::DIV8 => 8, | ||||||
|  |             Self::DIV16 => 16, | ||||||
|  |             _ => unreachable!(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Copy, Clone)] | ||||||
|  | pub struct Config { | ||||||
|  |     pub mux: ClockSrc, | ||||||
|  |     pub ahb_pre: AHBPrescaler, | ||||||
|  |     pub apb1_pre: APBPrescaler, | ||||||
|  |     pub apb2_pre: APBPrescaler, | ||||||
|  |     pub apb7_pre: APBPrescaler, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Default for Config { | ||||||
|  |     fn default() -> Self { | ||||||
|  |         Self { | ||||||
|  |             mux: ClockSrc::HSI16, | ||||||
|  |             ahb_pre: AHBPrescaler::DIV1, | ||||||
|  |             apb1_pre: APBPrescaler::DIV1, | ||||||
|  |             apb2_pre: APBPrescaler::DIV1, | ||||||
|  |             apb7_pre: APBPrescaler::DIV1, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub(crate) unsafe fn init(config: Config) { | ||||||
|  |     let sys_clk = match config.mux { | ||||||
|  |         ClockSrc::HSE(freq) => { | ||||||
|  |             RCC.cr().write(|w| w.set_hseon(true)); | ||||||
|  |             while !RCC.cr().read().hserdy() {} | ||||||
|  | 
 | ||||||
|  |             freq.0 | ||||||
|  |         } | ||||||
|  |         ClockSrc::HSI16 => { | ||||||
|  |             RCC.cr().write(|w| w.set_hsion(true)); | ||||||
|  |             while !RCC.cr().read().hsirdy() {} | ||||||
|  | 
 | ||||||
|  |             HSI_FREQ.0 | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // TODO make configurable
 | ||||||
|  |     let power_vos = VoltageScale::RANGE1; | ||||||
|  | 
 | ||||||
|  |     // states and programming delay
 | ||||||
|  |     let wait_states = match power_vos { | ||||||
|  |         VoltageScale::RANGE1 => match sys_clk { | ||||||
|  |             ..=32_000_000 => 0, | ||||||
|  |             ..=64_000_000 => 1, | ||||||
|  |             ..=96_000_000 => 2, | ||||||
|  |             ..=100_000_000 => 3, | ||||||
|  |             _ => 4, | ||||||
|  |         }, | ||||||
|  |         VoltageScale::RANGE2 => match sys_clk { | ||||||
|  |             ..=8_000_000 => 0, | ||||||
|  |             ..=16_000_000 => 1, | ||||||
|  |             _ => 2, | ||||||
|  |         }, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     FLASH.acr().modify(|w| { | ||||||
|  |         w.set_latency(wait_states); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     RCC.cfgr1().modify(|w| { | ||||||
|  |         w.set_sw(config.mux.into()); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     RCC.cfgr2().modify(|w| { | ||||||
|  |         w.set_hpre(config.ahb_pre.into()); | ||||||
|  |         w.set_ppre1(config.apb1_pre.into()); | ||||||
|  |         w.set_ppre2(config.apb2_pre.into()); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     RCC.cfgr3().modify(|w| { | ||||||
|  |         w.set_ppre7(config.apb7_pre.into()); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     let ahb_freq: u32 = sys_clk / config.ahb_pre.div() as u32; | ||||||
|  |     let (apb1_freq, apb1_tim_freq) = match config.apb1_pre.div() { | ||||||
|  |         1 => (ahb_freq, ahb_freq), | ||||||
|  |         div => { | ||||||
|  |             let freq = ahb_freq / div as u32; | ||||||
|  |             (freq, freq * 2) | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |     let (apb2_freq, apb2_tim_freq) = match config.apb2_pre.div() { | ||||||
|  |         1 => (ahb_freq, ahb_freq), | ||||||
|  |         div => { | ||||||
|  |             let freq = ahb_freq / div as u32; | ||||||
|  |             (freq, freq * 2) | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |     let (apb7_freq, _apb7_tim_freq) = match config.apb7_pre.div() { | ||||||
|  |         1 => (ahb_freq, ahb_freq), | ||||||
|  |         div => { | ||||||
|  |             let freq = ahb_freq / div as u32; | ||||||
|  |             (freq, freq * 2) | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     set_freqs(Clocks { | ||||||
|  |         sys: Hertz(sys_clk), | ||||||
|  |         ahb1: Hertz(ahb_freq), | ||||||
|  |         ahb2: Hertz(ahb_freq), | ||||||
|  |         ahb4: Hertz(ahb_freq), | ||||||
|  |         apb1: Hertz(apb1_freq), | ||||||
|  |         apb2: Hertz(apb2_freq), | ||||||
|  |         apb7: Hertz(apb7_freq), | ||||||
|  |         apb1_tim: Hertz(apb1_tim_freq), | ||||||
|  |         apb2_tim: Hertz(apb2_tim_freq), | ||||||
|  |     }); | ||||||
|  | } | ||||||
| @ -10,7 +10,6 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | |||||||
| use embassy_sync::blocking_mutex::Mutex; | use embassy_sync::blocking_mutex::Mutex; | ||||||
| 
 | 
 | ||||||
| pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; | pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; | ||||||
| use crate::rcc::bd::BackupDomain; |  | ||||||
| pub use crate::rcc::RtcClockSource; | pub use crate::rcc::RtcClockSource; | ||||||
| use crate::time::Hertz; | use crate::time::Hertz; | ||||||
| 
 | 
 | ||||||
| @ -125,7 +124,6 @@ impl Default for RtcCalibrationCyclePeriod { | |||||||
| impl Rtc { | impl Rtc { | ||||||
|     pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { |     pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { | ||||||
|         RTC::enable_peripheral_clk(); |         RTC::enable_peripheral_clk(); | ||||||
|         BackupDomain::enable_rtc(); |  | ||||||
| 
 | 
 | ||||||
|         let mut this = Self { |         let mut this = Self { | ||||||
|             #[cfg(feature = "low-power")] |             #[cfg(feature = "low-power")] | ||||||
|  | |||||||
							
								
								
									
										8
									
								
								examples/stm32wba/.cargo/config.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								examples/stm32wba/.cargo/config.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||||||
|  | runner = "probe-rs run --chip STM32WBA52CGUxT" | ||||||
|  | 
 | ||||||
|  | [build] | ||||||
|  | target = "thumbv8m.main-none-eabihf" | ||||||
|  | 
 | ||||||
|  | [env] | ||||||
|  | DEFMT_LOG = "trace" | ||||||
							
								
								
									
										26
									
								
								examples/stm32wba/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								examples/stm32wba/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | [package] | ||||||
|  | edition = "2021" | ||||||
|  | name = "embassy-stm32wba-examples" | ||||||
|  | version = "0.1.0" | ||||||
|  | license = "MIT OR Apache-2.0" | ||||||
|  | 
 | ||||||
|  | [dependencies] | ||||||
|  | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"]  } | ||||||
|  | embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } | ||||||
|  | embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | ||||||
|  | embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | ||||||
|  | embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } | ||||||
|  | 
 | ||||||
|  | defmt = "0.3" | ||||||
|  | defmt-rtt = "0.4" | ||||||
|  | 
 | ||||||
|  | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | ||||||
|  | cortex-m-rt = "0.7.0" | ||||||
|  | embedded-hal = "0.2.6" | ||||||
|  | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||||||
|  | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||||||
|  | heapless = { version = "0.7.5", default-features = false } | ||||||
|  | static_cell = { version = "1.1", features = ["nightly"]} | ||||||
|  | 
 | ||||||
|  | [profile.release] | ||||||
|  | debug = 2 | ||||||
							
								
								
									
										10
									
								
								examples/stm32wba/build.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								examples/stm32wba/build.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | use std::error::Error; | ||||||
|  | 
 | ||||||
|  | fn main() -> Result<(), Box<dyn Error>> { | ||||||
|  |     println!("cargo:rerun-if-changed=link.x"); | ||||||
|  |     println!("cargo:rustc-link-arg-bins=--nmagic"); | ||||||
|  |     println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||||||
|  |     println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||||||
|  | 
 | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
							
								
								
									
										27
									
								
								examples/stm32wba/src/bin/blinky.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								examples/stm32wba/src/bin/blinky.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | #![no_std] | ||||||
|  | #![no_main] | ||||||
|  | #![feature(type_alias_impl_trait)] | ||||||
|  | 
 | ||||||
|  | use defmt::*; | ||||||
|  | use embassy_executor::Spawner; | ||||||
|  | use embassy_stm32::gpio::{Level, Output, Speed}; | ||||||
|  | use embassy_time::{Duration, Timer}; | ||||||
|  | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  | 
 | ||||||
|  | #[embassy_executor::main] | ||||||
|  | async fn main(_spawner: Spawner) { | ||||||
|  |     let p = embassy_stm32::init(Default::default()); | ||||||
|  |     info!("Hello World!"); | ||||||
|  | 
 | ||||||
|  |     let mut led = Output::new(p.PB4, Level::High, Speed::Low); | ||||||
|  | 
 | ||||||
|  |     loop { | ||||||
|  |         info!("high"); | ||||||
|  |         led.set_high(); | ||||||
|  |         Timer::after(Duration::from_millis(500)).await; | ||||||
|  | 
 | ||||||
|  |         info!("low"); | ||||||
|  |         led.set_low(); | ||||||
|  |         Timer::after(Duration::from_millis(500)).await; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										27
									
								
								examples/stm32wba/src/bin/button_exti.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								examples/stm32wba/src/bin/button_exti.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | #![no_std] | ||||||
|  | #![no_main] | ||||||
|  | #![feature(type_alias_impl_trait)] | ||||||
|  | 
 | ||||||
|  | use defmt::*; | ||||||
|  | use embassy_executor::Spawner; | ||||||
|  | use embassy_stm32::exti::ExtiInput; | ||||||
|  | use embassy_stm32::gpio::{Input, Pull}; | ||||||
|  | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  | 
 | ||||||
|  | #[embassy_executor::main] | ||||||
|  | async fn main(_spawner: Spawner) { | ||||||
|  |     let p = embassy_stm32::init(Default::default()); | ||||||
|  |     info!("Hello World!"); | ||||||
|  | 
 | ||||||
|  |     let button = Input::new(p.PC13, Pull::Up); | ||||||
|  |     let mut button = ExtiInput::new(button, p.EXTI13); | ||||||
|  | 
 | ||||||
|  |     info!("Press the USER button..."); | ||||||
|  | 
 | ||||||
|  |     loop { | ||||||
|  |         button.wait_for_falling_edge().await; | ||||||
|  |         info!("Pressed!"); | ||||||
|  |         button.wait_for_rising_edge().await; | ||||||
|  |         info!("Released!"); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user