diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-10-23 00:28:54 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-10-23 00:31:36 +0200 |
| commit | b9e13cb5d1ca3e85a02b2a37b7ee14f73663b1bd (patch) | |
| tree | 1ae33453bcee12a6aaf4cfdd8dc1795187c7cadc | |
| parent | 46ff2c82aa3193dd1378b142be284aa746045923 (diff) | |
stm32/rcc: merge wl into l4/l5.
| -rw-r--r-- | embassy-stm32/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/ipcc.rs | 5 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l4l5.rs | 153 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 3 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/u5.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/wl.rs | 184 | ||||
| -rw-r--r-- | examples/stm32l4/src/bin/rtc.rs | 29 | ||||
| -rw-r--r-- | examples/stm32l4/src/bin/spe_adin1110_http_server.rs | 34 | ||||
| -rw-r--r-- | examples/stm32wl/src/bin/lora_lorawan.rs | 22 | ||||
| -rw-r--r-- | examples/stm32wl/src/bin/random.rs | 23 | ||||
| -rw-r--r-- | tests/stm32/src/common.rs | 15 |
11 files changed, 198 insertions, 276 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 2d694267a..568a7eeb9 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -58,7 +58,7 @@ rand_core = "0.6.3" | |||
| 58 | sdio-host = "0.5.0" | 58 | sdio-host = "0.5.0" |
| 59 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } | 59 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } |
| 60 | critical-section = "1.1" | 60 | critical-section = "1.1" |
| 61 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ee64389697d9234af374a89788aa52bb93d59284" } | 61 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4ddcb77c9d213d11eebb048f40e112bc54163cdc" } |
| 62 | vcell = "0.1.3" | 62 | vcell = "0.1.3" |
| 63 | bxcan = "0.7.0" | 63 | bxcan = "0.7.0" |
| 64 | nb = "1.0.0" | 64 | nb = "1.0.0" |
| @@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] } | |||
| 76 | [build-dependencies] | 76 | [build-dependencies] |
| 77 | proc-macro2 = "1.0.36" | 77 | proc-macro2 = "1.0.36" |
| 78 | quote = "1.0.15" | 78 | quote = "1.0.15" |
| 79 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ee64389697d9234af374a89788aa52bb93d59284", default-features = false, features = ["metadata"]} | 79 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4ddcb77c9d213d11eebb048f40e112bc54163cdc", default-features = false, features = ["metadata"]} |
| 80 | 80 | ||
| 81 | 81 | ||
| 82 | [features] | 82 | [features] |
diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index 1b1e182f0..4006dee19 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs | |||
| @@ -5,6 +5,7 @@ use core::task::Poll; | |||
| 5 | use self::sealed::Instance; | 5 | use self::sealed::Instance; |
| 6 | use crate::interrupt; | 6 | use crate::interrupt; |
| 7 | use crate::interrupt::typelevel::Interrupt; | 7 | use crate::interrupt::typelevel::Interrupt; |
| 8 | use crate::pac::rcc::vals::{Lptim1sel, Lptim2sel}; | ||
| 8 | use crate::peripherals::IPCC; | 9 | use crate::peripherals::IPCC; |
| 9 | use crate::rcc::sealed::RccPeripheral; | 10 | use crate::rcc::sealed::RccPeripheral; |
| 10 | 11 | ||
| @@ -273,7 +274,7 @@ fn _configure_pwr() { | |||
| 273 | 274 | ||
| 274 | // set LPTIM1 & LPTIM2 clock source | 275 | // set LPTIM1 & LPTIM2 clock source |
| 275 | rcc.ccipr().modify(|w| { | 276 | rcc.ccipr().modify(|w| { |
| 276 | w.set_lptim1sel(0b00); // PCLK | 277 | w.set_lptim1sel(Lptim1sel::PCLK1); |
| 277 | w.set_lptim2sel(0b00); // PCLK | 278 | w.set_lptim2sel(Lptim2sel::PCLK1); |
| 278 | }); | 279 | }); |
| 279 | } | 280 | } |
diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index 8cf284d1e..b56962270 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs | |||
| @@ -1,8 +1,10 @@ | |||
| 1 | use crate::pac::rcc::regs::Cfgr; | 1 | use crate::pac::rcc::regs::Cfgr; |
| 2 | #[cfg(not(stm32wl))] | ||
| 3 | pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; | ||
| 2 | use crate::pac::rcc::vals::Msirgsel; | 4 | use crate::pac::rcc::vals::Msirgsel; |
| 3 | pub use crate::pac::rcc::vals::{ | 5 | pub use crate::pac::rcc::vals::{ |
| 4 | Clk48sel as Clk48Src, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, | 6 | Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, |
| 5 | Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, | 7 | Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, |
| 6 | }; | 8 | }; |
| 7 | use crate::pac::{FLASH, RCC}; | 9 | use crate::pac::{FLASH, RCC}; |
| 8 | use crate::rcc::{set_freqs, Clocks}; | 10 | use crate::rcc::{set_freqs, Clocks}; |
| @@ -11,6 +13,22 @@ use crate::time::Hertz; | |||
| 11 | /// HSI speed | 13 | /// HSI speed |
| 12 | pub const HSI_FREQ: Hertz = Hertz(16_000_000); | 14 | pub const HSI_FREQ: Hertz = Hertz(16_000_000); |
| 13 | 15 | ||
| 16 | #[derive(Clone, Copy, Eq, PartialEq)] | ||
| 17 | pub enum HseMode { | ||
| 18 | /// crystal/ceramic oscillator (HSEBYP=0) | ||
| 19 | Oscillator, | ||
| 20 | /// external analog clock (low swing) (HSEBYP=1) | ||
| 21 | Bypass, | ||
| 22 | } | ||
| 23 | |||
| 24 | #[derive(Clone, Copy, Eq, PartialEq)] | ||
| 25 | pub struct Hse { | ||
| 26 | /// HSE frequency. | ||
| 27 | pub freq: Hertz, | ||
| 28 | /// HSE mode. | ||
| 29 | pub mode: HseMode, | ||
| 30 | } | ||
| 31 | |||
| 14 | #[derive(Clone, Copy)] | 32 | #[derive(Clone, Copy)] |
| 15 | pub struct Pll { | 33 | pub struct Pll { |
| 16 | /// PLL source | 34 | /// PLL source |
| @@ -35,12 +53,13 @@ pub struct Config { | |||
| 35 | // base clock sources | 53 | // base clock sources |
| 36 | pub msi: Option<MSIRange>, | 54 | pub msi: Option<MSIRange>, |
| 37 | pub hsi: bool, | 55 | pub hsi: bool, |
| 38 | pub hse: Option<Hertz>, | 56 | pub hse: Option<Hse>, |
| 39 | #[cfg(not(any(stm32l47x, stm32l48x)))] | 57 | #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] |
| 40 | pub hsi48: bool, | 58 | pub hsi48: bool, |
| 41 | 59 | ||
| 42 | // pll | 60 | // pll |
| 43 | pub pll: Option<Pll>, | 61 | pub pll: Option<Pll>, |
| 62 | #[cfg(any(stm32l4, stm32l5))] | ||
| 44 | pub pllsai1: Option<Pll>, | 63 | pub pllsai1: Option<Pll>, |
| 45 | #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] | 64 | #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] |
| 46 | pub pllsai2: Option<Pll>, | 65 | pub pllsai2: Option<Pll>, |
| @@ -50,8 +69,11 @@ pub struct Config { | |||
| 50 | pub ahb_pre: AHBPrescaler, | 69 | pub ahb_pre: AHBPrescaler, |
| 51 | pub apb1_pre: APBPrescaler, | 70 | pub apb1_pre: APBPrescaler, |
| 52 | pub apb2_pre: APBPrescaler, | 71 | pub apb2_pre: APBPrescaler, |
| 72 | #[cfg(stm32wl)] | ||
| 73 | pub shared_ahb_pre: AHBPrescaler, | ||
| 53 | 74 | ||
| 54 | // muxes | 75 | // muxes |
| 76 | #[cfg(not(stm32wl))] | ||
| 55 | pub clk48_src: Clk48Src, | 77 | pub clk48_src: Clk48Src, |
| 56 | 78 | ||
| 57 | // low speed LSI/LSE/RTC | 79 | // low speed LSI/LSE/RTC |
| @@ -69,12 +91,16 @@ impl Default for Config { | |||
| 69 | ahb_pre: AHBPrescaler::DIV1, | 91 | ahb_pre: AHBPrescaler::DIV1, |
| 70 | apb1_pre: APBPrescaler::DIV1, | 92 | apb1_pre: APBPrescaler::DIV1, |
| 71 | apb2_pre: APBPrescaler::DIV1, | 93 | apb2_pre: APBPrescaler::DIV1, |
| 94 | #[cfg(stm32wl)] | ||
| 95 | shared_ahb_pre: AHBPrescaler::DIV1, | ||
| 72 | pll: None, | 96 | pll: None, |
| 97 | #[cfg(any(stm32l4, stm32l5))] | ||
| 73 | pllsai1: None, | 98 | pllsai1: None, |
| 74 | #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] | 99 | #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] |
| 75 | pllsai2: None, | 100 | pllsai2: None, |
| 76 | #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] | 101 | #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] |
| 77 | hsi48: true, | 102 | hsi48: true, |
| 103 | #[cfg(not(stm32wl))] | ||
| 78 | clk48_src: Clk48Src::HSI48, | 104 | clk48_src: Clk48Src::HSI48, |
| 79 | ls: Default::default(), | 105 | ls: Default::default(), |
| 80 | } | 106 | } |
| @@ -111,7 +137,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 111 | 137 | ||
| 112 | let msi = config.msi.map(|range| { | 138 | let msi = config.msi.map(|range| { |
| 113 | // Enable MSI | 139 | // Enable MSI |
| 114 | RCC.cr().write(|w| { | 140 | RCC.cr().modify(|w| { |
| 115 | w.set_msirange(range); | 141 | w.set_msirange(range); |
| 116 | w.set_msirgsel(Msirgsel::CR); | 142 | w.set_msirgsel(Msirgsel::CR); |
| 117 | w.set_msion(true); | 143 | w.set_msion(true); |
| @@ -128,20 +154,26 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 128 | }); | 154 | }); |
| 129 | 155 | ||
| 130 | let hsi = config.hsi.then(|| { | 156 | let hsi = config.hsi.then(|| { |
| 131 | RCC.cr().write(|w| w.set_hsion(true)); | 157 | RCC.cr().modify(|w| w.set_hsion(true)); |
| 132 | while !RCC.cr().read().hsirdy() {} | 158 | while !RCC.cr().read().hsirdy() {} |
| 133 | 159 | ||
| 134 | HSI_FREQ | 160 | HSI_FREQ |
| 135 | }); | 161 | }); |
| 136 | 162 | ||
| 137 | let hse = config.hse.map(|freq| { | 163 | let hse = config.hse.map(|hse| { |
| 138 | RCC.cr().write(|w| w.set_hseon(true)); | 164 | RCC.cr().modify(|w| { |
| 165 | #[cfg(stm32wl)] | ||
| 166 | w.set_hsebyppwr(hse.mode == HseMode::Bypass); | ||
| 167 | #[cfg(not(stm32wl))] | ||
| 168 | w.set_hsebyp(hse.mode == HseMode::Bypass); | ||
| 169 | w.set_hseon(true); | ||
| 170 | }); | ||
| 139 | while !RCC.cr().read().hserdy() {} | 171 | while !RCC.cr().read().hserdy() {} |
| 140 | 172 | ||
| 141 | freq | 173 | hse.freq |
| 142 | }); | 174 | }); |
| 143 | 175 | ||
| 144 | #[cfg(not(any(stm32l47x, stm32l48x)))] | 176 | #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] |
| 145 | let hsi48 = config.hsi48.then(|| { | 177 | let hsi48 = config.hsi48.then(|| { |
| 146 | RCC.crrcr().modify(|w| w.set_hsi48on(true)); | 178 | RCC.crrcr().modify(|w| w.set_hsi48on(true)); |
| 147 | while !RCC.crrcr().read().hsi48rdy() {} | 179 | while !RCC.crrcr().read().hsi48rdy() {} |
| @@ -153,6 +185,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 153 | 185 | ||
| 154 | let _plls = [ | 186 | let _plls = [ |
| 155 | &config.pll, | 187 | &config.pll, |
| 188 | #[cfg(any(stm32l4, stm32l5))] | ||
| 156 | &config.pllsai1, | 189 | &config.pllsai1, |
| 157 | #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] | 190 | #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] |
| 158 | &config.pllsai2, | 191 | &config.pllsai2, |
| @@ -169,8 +202,8 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 169 | }), | 202 | }), |
| 170 | }; | 203 | }; |
| 171 | 204 | ||
| 172 | // L4+ has shared PLLSRC, check it's equal in all PLLs. | 205 | // L4+, WL has shared PLLSRC, check it's equal in all PLLs. |
| 173 | #[cfg(any(rcc_l4plus))] | 206 | #[cfg(any(rcc_l4plus, stm32wl))] |
| 174 | match get_equal(_plls.into_iter().flatten().map(|p| p.source)) { | 207 | match get_equal(_plls.into_iter().flatten().map(|p| p.source)) { |
| 175 | Err(()) => panic!("Source must be equal across all enabled PLLs."), | 208 | Err(()) => panic!("Source must be equal across all enabled PLLs."), |
| 176 | Ok(None) => {} | 209 | Ok(None) => {} |
| @@ -181,6 +214,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 181 | 214 | ||
| 182 | let pll_input = PllInput { hse, hsi, msi }; | 215 | let pll_input = PllInput { hse, hsi, msi }; |
| 183 | let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); | 216 | let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); |
| 217 | #[cfg(any(stm32l4, stm32l5))] | ||
| 184 | let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); | 218 | let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); |
| 185 | #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] | 219 | #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] |
| 186 | let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input); | 220 | let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input); |
| @@ -196,6 +230,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 196 | RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src)); | 230 | RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src)); |
| 197 | #[cfg(stm32l5)] | 231 | #[cfg(stm32l5)] |
| 198 | RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src)); | 232 | RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src)); |
| 233 | #[cfg(not(stm32wl))] | ||
| 199 | let _clk48 = match config.clk48_src { | 234 | let _clk48 = match config.clk48_src { |
| 200 | Clk48Src::HSI48 => hsi48, | 235 | Clk48Src::HSI48 => hsi48, |
| 201 | Clk48Src::MSI => msi, | 236 | Clk48Src::MSI => msi, |
| @@ -208,38 +243,6 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 208 | #[cfg(all(stm32l4, not(rcc_l4plus)))] | 243 | #[cfg(all(stm32l4, not(rcc_l4plus)))] |
| 209 | assert!(sys_clk.0 <= 80_000_000); | 244 | assert!(sys_clk.0 <= 80_000_000); |
| 210 | 245 | ||
| 211 | // Set flash wait states | ||
| 212 | #[cfg(stm32l4)] | ||
| 213 | FLASH.acr().modify(|w| { | ||
| 214 | w.set_latency(match sys_clk.0 { | ||
| 215 | 0..=16_000_000 => 0, | ||
| 216 | 0..=32_000_000 => 1, | ||
| 217 | 0..=48_000_000 => 2, | ||
| 218 | 0..=64_000_000 => 3, | ||
| 219 | _ => 4, | ||
| 220 | }) | ||
| 221 | }); | ||
| 222 | // VCORE Range 0 (performance), others TODO | ||
| 223 | #[cfg(stm32l5)] | ||
| 224 | FLASH.acr().modify(|w| { | ||
| 225 | w.set_latency(match sys_clk.0 { | ||
| 226 | 0..=20_000_000 => 0, | ||
| 227 | 0..=40_000_000 => 1, | ||
| 228 | 0..=60_000_000 => 2, | ||
| 229 | 0..=80_000_000 => 3, | ||
| 230 | 0..=100_000_000 => 4, | ||
| 231 | _ => 5, | ||
| 232 | }) | ||
| 233 | }); | ||
| 234 | |||
| 235 | RCC.cfgr().modify(|w| { | ||
| 236 | w.set_sw(config.mux); | ||
| 237 | w.set_hpre(config.ahb_pre); | ||
| 238 | w.set_ppre1(config.apb1_pre); | ||
| 239 | w.set_ppre2(config.apb2_pre); | ||
| 240 | }); | ||
| 241 | while RCC.cfgr().read().sws() != config.mux {} | ||
| 242 | |||
| 243 | let ahb_freq = sys_clk / config.ahb_pre; | 246 | let ahb_freq = sys_clk / config.ahb_pre; |
| 244 | 247 | ||
| 245 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { | 248 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { |
| @@ -258,15 +261,69 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 258 | } | 261 | } |
| 259 | }; | 262 | }; |
| 260 | 263 | ||
| 264 | #[cfg(stm32wl)] | ||
| 265 | let ahb3_freq = sys_clk / config.shared_ahb_pre; | ||
| 266 | |||
| 267 | // Set flash wait states | ||
| 268 | #[cfg(stm32l4)] | ||
| 269 | let latency = match sys_clk.0 { | ||
| 270 | 0..=16_000_000 => 0, | ||
| 271 | 0..=32_000_000 => 1, | ||
| 272 | 0..=48_000_000 => 2, | ||
| 273 | 0..=64_000_000 => 3, | ||
| 274 | _ => 4, | ||
| 275 | }; | ||
| 276 | #[cfg(stm32l5)] | ||
| 277 | let latency = match sys_clk.0 { | ||
| 278 | // VCORE Range 0 (performance), others TODO | ||
| 279 | 0..=20_000_000 => 0, | ||
| 280 | 0..=40_000_000 => 1, | ||
| 281 | 0..=60_000_000 => 2, | ||
| 282 | 0..=80_000_000 => 3, | ||
| 283 | 0..=100_000_000 => 4, | ||
| 284 | _ => 5, | ||
| 285 | }; | ||
| 286 | #[cfg(stm32wl)] | ||
| 287 | let latency = match ahb3_freq.0 { | ||
| 288 | // VOS RANGE1, others TODO. | ||
| 289 | ..=18_000_000 => 0, | ||
| 290 | ..=36_000_000 => 1, | ||
| 291 | _ => 2, | ||
| 292 | }; | ||
| 293 | |||
| 294 | FLASH.acr().modify(|w| w.set_latency(latency)); | ||
| 295 | while FLASH.acr().read().latency() != latency {} | ||
| 296 | |||
| 297 | RCC.cfgr().modify(|w| { | ||
| 298 | w.set_sw(config.mux); | ||
| 299 | w.set_hpre(config.ahb_pre); | ||
| 300 | w.set_ppre1(config.apb1_pre); | ||
| 301 | w.set_ppre2(config.apb2_pre); | ||
| 302 | }); | ||
| 303 | while RCC.cfgr().read().sws() != config.mux {} | ||
| 304 | |||
| 305 | #[cfg(stm32wl)] | ||
| 306 | { | ||
| 307 | RCC.extcfgr().modify(|w| { | ||
| 308 | w.set_shdhpre(config.shared_ahb_pre); | ||
| 309 | }); | ||
| 310 | while !RCC.extcfgr().read().shdhpref() {} | ||
| 311 | } | ||
| 312 | |||
| 261 | set_freqs(Clocks { | 313 | set_freqs(Clocks { |
| 262 | sys: sys_clk, | 314 | sys: sys_clk, |
| 263 | hclk1: ahb_freq, | 315 | hclk1: ahb_freq, |
| 264 | hclk2: ahb_freq, | 316 | hclk2: ahb_freq, |
| 317 | #[cfg(not(stm32wl))] | ||
| 265 | hclk3: ahb_freq, | 318 | hclk3: ahb_freq, |
| 266 | pclk1: apb1_freq, | 319 | pclk1: apb1_freq, |
| 267 | pclk2: apb2_freq, | 320 | pclk2: apb2_freq, |
| 268 | pclk1_tim: apb1_tim_freq, | 321 | pclk1_tim: apb1_tim_freq, |
| 269 | pclk2_tim: apb2_tim_freq, | 322 | pclk2_tim: apb2_tim_freq, |
| 323 | #[cfg(stm32wl)] | ||
| 324 | hclk3: ahb3_freq, | ||
| 325 | #[cfg(stm32wl)] | ||
| 326 | pclk3: ahb3_freq, | ||
| 270 | #[cfg(rcc_l4)] | 327 | #[cfg(rcc_l4)] |
| 271 | hsi: None, | 328 | hsi: None, |
| 272 | #[cfg(rcc_l4)] | 329 | #[cfg(rcc_l4)] |
| @@ -330,6 +387,7 @@ struct PllOutput { | |||
| 330 | #[derive(PartialEq, Eq, Clone, Copy)] | 387 | #[derive(PartialEq, Eq, Clone, Copy)] |
| 331 | enum PllInstance { | 388 | enum PllInstance { |
| 332 | Pll, | 389 | Pll, |
| 390 | #[cfg(any(stm32l4, stm32l5))] | ||
| 333 | Pllsai1, | 391 | Pllsai1, |
| 334 | #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] | 392 | #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] |
| 335 | Pllsai2, | 393 | Pllsai2, |
| @@ -342,6 +400,7 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll | |||
| 342 | RCC.cr().modify(|w| w.set_pllon(false)); | 400 | RCC.cr().modify(|w| w.set_pllon(false)); |
| 343 | while RCC.cr().read().pllrdy() {} | 401 | while RCC.cr().read().pllrdy() {} |
| 344 | } | 402 | } |
| 403 | #[cfg(any(stm32l4, stm32l5))] | ||
| 345 | PllInstance::Pllsai1 => { | 404 | PllInstance::Pllsai1 => { |
| 346 | RCC.cr().modify(|w| w.set_pllsai1on(false)); | 405 | RCC.cr().modify(|w| w.set_pllsai1on(false)); |
| 347 | while RCC.cr().read().pllsai1rdy() {} | 406 | while RCC.cr().read().pllsai1rdy() {} |
| @@ -356,7 +415,7 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll | |||
| 356 | let Some(pll) = config else { return PllOutput::default() }; | 415 | let Some(pll) = config else { return PllOutput::default() }; |
| 357 | 416 | ||
| 358 | let pll_src = match pll.source { | 417 | let pll_src = match pll.source { |
| 359 | PLLSource::NONE => panic!("must not select PLL source as NONE"), | 418 | PLLSource::DISABLE => panic!("must not select PLL source as NONE"), |
| 360 | PLLSource::HSE => input.hse, | 419 | PLLSource::HSE => input.hse, |
| 361 | PLLSource::HSI => input.hsi, | 420 | PLLSource::HSI => input.hsi, |
| 362 | PLLSource::MSI => input.msi, | 421 | PLLSource::MSI => input.msi, |
| @@ -400,6 +459,7 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll | |||
| 400 | w.set_pllsrc(pll.source); | 459 | w.set_pllsrc(pll.source); |
| 401 | write_fields!(w); | 460 | write_fields!(w); |
| 402 | }), | 461 | }), |
| 462 | #[cfg(any(stm32l4, stm32l5))] | ||
| 403 | PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { | 463 | PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { |
| 404 | #[cfg(any(rcc_l4plus, stm32l5))] | 464 | #[cfg(any(rcc_l4plus, stm32l5))] |
| 405 | w.set_pllm(pll.prediv); | 465 | w.set_pllm(pll.prediv); |
| @@ -423,6 +483,7 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll | |||
| 423 | RCC.cr().modify(|w| w.set_pllon(true)); | 483 | RCC.cr().modify(|w| w.set_pllon(true)); |
| 424 | while !RCC.cr().read().pllrdy() {} | 484 | while !RCC.cr().read().pllrdy() {} |
| 425 | } | 485 | } |
| 486 | #[cfg(any(stm32l4, stm32l5))] | ||
| 426 | PllInstance::Pllsai1 => { | 487 | PllInstance::Pllsai1 => { |
| 427 | RCC.cr().modify(|w| w.set_pllsai1on(true)); | 488 | RCC.cr().modify(|w| w.set_pllsai1on(true)); |
| 428 | while !RCC.cr().read().pllsai1rdy() {} | 489 | while !RCC.cr().read().pllsai1rdy() {} |
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 49174b27f..78d54f803 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -19,11 +19,10 @@ pub use mco::*; | |||
| 19 | #[cfg_attr(rcc_g4, path = "g4.rs")] | 19 | #[cfg_attr(rcc_g4, path = "g4.rs")] |
| 20 | #[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")] | 20 | #[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")] |
| 21 | #[cfg_attr(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")] | 21 | #[cfg_attr(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")] |
| 22 | #[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5), path = "l4l5.rs")] | 22 | #[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5, rcc_wl5, rcc_wle), path = "l4l5.rs")] |
| 23 | #[cfg_attr(rcc_u5, path = "u5.rs")] | 23 | #[cfg_attr(rcc_u5, path = "u5.rs")] |
| 24 | #[cfg_attr(rcc_wb, path = "wb.rs")] | 24 | #[cfg_attr(rcc_wb, path = "wb.rs")] |
| 25 | #[cfg_attr(rcc_wba, path = "wba.rs")] | 25 | #[cfg_attr(rcc_wba, path = "wba.rs")] |
| 26 | #[cfg_attr(any(rcc_wl5, rcc_wle), path = "wl.rs")] | ||
| 27 | mod _version; | 26 | mod _version; |
| 28 | #[cfg(feature = "low-power")] | 27 | #[cfg(feature = "low-power")] |
| 29 | use core::sync::atomic::{AtomicU32, Ordering}; | 28 | use core::sync::atomic::{AtomicU32, Ordering}; |
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index 7664557e9..2bbacbbdc 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs | |||
| @@ -170,7 +170,7 @@ impl Config { | |||
| 170 | 170 | ||
| 171 | RCC.icscr1().modify(|w| { | 171 | RCC.icscr1().modify(|w| { |
| 172 | w.set_msisrange(range); | 172 | w.set_msisrange(range); |
| 173 | w.set_msirgsel(Msirgsel::RCC_ICSCR1); | 173 | w.set_msirgsel(Msirgsel::ICSCR1); |
| 174 | }); | 174 | }); |
| 175 | RCC.cr().write(|w| { | 175 | RCC.cr().write(|w| { |
| 176 | w.set_msipllen(false); | 176 | w.set_msipllen(false); |
diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs deleted file mode 100644 index 4d68b55c2..000000000 --- a/embassy-stm32/src/rcc/wl.rs +++ /dev/null | |||
| @@ -1,184 +0,0 @@ | |||
| 1 | pub use crate::pac::pwr::vals::Vos as VoltageScale; | ||
| 2 | use crate::pac::rcc::vals::Sw; | ||
| 3 | pub use crate::pac::rcc::vals::{ | ||
| 4 | Adcsel as AdcClockSource, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm, Plln, Pllp, Pllq, Pllr, | ||
| 5 | Pllsrc as PllSource, Ppre as APBPrescaler, | ||
| 6 | }; | ||
| 7 | use crate::pac::{FLASH, RCC}; | ||
| 8 | use crate::rcc::{set_freqs, Clocks}; | ||
| 9 | use crate::time::Hertz; | ||
| 10 | |||
| 11 | /// HSI speed | ||
| 12 | pub const HSI_FREQ: Hertz = Hertz(16_000_000); | ||
| 13 | |||
| 14 | /// HSE speed | ||
| 15 | pub const HSE_FREQ: Hertz = Hertz(32_000_000); | ||
| 16 | |||
| 17 | /// System clock mux source | ||
| 18 | #[derive(Clone, Copy)] | ||
| 19 | pub enum ClockSrc { | ||
| 20 | MSI(MSIRange), | ||
| 21 | HSE, | ||
| 22 | HSI, | ||
| 23 | } | ||
| 24 | |||
| 25 | /// Clocks configutation | ||
| 26 | pub struct Config { | ||
| 27 | pub mux: ClockSrc, | ||
| 28 | pub ahb_pre: AHBPrescaler, | ||
| 29 | pub shd_ahb_pre: AHBPrescaler, | ||
| 30 | pub apb1_pre: APBPrescaler, | ||
| 31 | pub apb2_pre: APBPrescaler, | ||
| 32 | pub adc_clock_source: AdcClockSource, | ||
| 33 | pub ls: super::LsConfig, | ||
| 34 | } | ||
| 35 | |||
| 36 | impl Default for Config { | ||
| 37 | #[inline] | ||
| 38 | fn default() -> Config { | ||
| 39 | Config { | ||
| 40 | mux: ClockSrc::MSI(MSIRange::RANGE4M), | ||
| 41 | ahb_pre: AHBPrescaler::DIV1, | ||
| 42 | shd_ahb_pre: AHBPrescaler::DIV1, | ||
| 43 | apb1_pre: APBPrescaler::DIV1, | ||
| 44 | apb2_pre: APBPrescaler::DIV1, | ||
| 45 | adc_clock_source: AdcClockSource::HSI, | ||
| 46 | ls: Default::default(), | ||
| 47 | } | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | pub(crate) unsafe fn init(config: Config) { | ||
| 52 | let (sys_clk, sw, vos) = match config.mux { | ||
| 53 | ClockSrc::HSI => (HSI_FREQ, Sw::HSI, VoltageScale::RANGE2), | ||
| 54 | ClockSrc::HSE => (HSE_FREQ, Sw::HSE, VoltageScale::RANGE1), | ||
| 55 | ClockSrc::MSI(range) => (msirange_to_hertz(range), Sw::MSI, msirange_to_vos(range)), | ||
| 56 | }; | ||
| 57 | |||
| 58 | let ahb_freq = sys_clk / config.ahb_pre; | ||
| 59 | let shd_ahb_freq = sys_clk / config.shd_ahb_pre; | ||
| 60 | |||
| 61 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { | ||
| 62 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | ||
| 63 | pre => { | ||
| 64 | let freq = ahb_freq / pre; | ||
| 65 | (freq, freq * 2u32) | ||
| 66 | } | ||
| 67 | }; | ||
| 68 | |||
| 69 | let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { | ||
| 70 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | ||
| 71 | pre => { | ||
| 72 | let freq = ahb_freq / pre; | ||
| 73 | (freq, freq * 2u32) | ||
| 74 | } | ||
| 75 | }; | ||
| 76 | |||
| 77 | // Adjust flash latency | ||
| 78 | let flash_clk_src_freq = shd_ahb_freq; | ||
| 79 | let ws = match vos { | ||
| 80 | VoltageScale::RANGE1 => match flash_clk_src_freq.0 { | ||
| 81 | 0..=18_000_000 => 0b000, | ||
| 82 | 18_000_001..=36_000_000 => 0b001, | ||
| 83 | _ => 0b010, | ||
| 84 | }, | ||
| 85 | VoltageScale::RANGE2 => match flash_clk_src_freq.0 { | ||
| 86 | 0..=6_000_000 => 0b000, | ||
| 87 | 6_000_001..=12_000_000 => 0b001, | ||
| 88 | _ => 0b010, | ||
| 89 | }, | ||
| 90 | _ => unreachable!(), | ||
| 91 | }; | ||
| 92 | |||
| 93 | FLASH.acr().modify(|w| { | ||
| 94 | w.set_latency(ws); | ||
| 95 | }); | ||
| 96 | |||
| 97 | while FLASH.acr().read().latency() != ws {} | ||
| 98 | |||
| 99 | match config.mux { | ||
| 100 | ClockSrc::HSI => { | ||
| 101 | // Enable HSI | ||
| 102 | RCC.cr().write(|w| w.set_hsion(true)); | ||
| 103 | while !RCC.cr().read().hsirdy() {} | ||
| 104 | } | ||
| 105 | ClockSrc::HSE => { | ||
| 106 | // Enable HSE | ||
| 107 | RCC.cr().write(|w| { | ||
| 108 | w.set_hsebyppwr(true); | ||
| 109 | w.set_hseon(true); | ||
| 110 | }); | ||
| 111 | while !RCC.cr().read().hserdy() {} | ||
| 112 | } | ||
| 113 | ClockSrc::MSI(range) => { | ||
| 114 | let cr = RCC.cr().read(); | ||
| 115 | assert!(!cr.msion() || cr.msirdy()); | ||
| 116 | RCC.cr().write(|w| { | ||
| 117 | w.set_msirgsel(true); | ||
| 118 | w.set_msirange(range); | ||
| 119 | w.set_msion(true); | ||
| 120 | |||
| 121 | // If LSE is enabled, enable calibration of MSI | ||
| 122 | w.set_msipllen(config.ls.lse.is_some()); | ||
| 123 | }); | ||
| 124 | while !RCC.cr().read().msirdy() {} | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | RCC.extcfgr().modify(|w| { | ||
| 129 | w.set_shdhpre(config.shd_ahb_pre); | ||
| 130 | }); | ||
| 131 | |||
| 132 | RCC.cfgr().modify(|w| { | ||
| 133 | w.set_sw(sw.into()); | ||
| 134 | w.set_hpre(config.ahb_pre); | ||
| 135 | w.set_ppre1(config.apb1_pre); | ||
| 136 | w.set_ppre2(config.apb2_pre); | ||
| 137 | }); | ||
| 138 | |||
| 139 | // ADC clock MUX | ||
| 140 | RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source)); | ||
| 141 | |||
| 142 | // TODO: switch voltage range | ||
| 143 | |||
| 144 | let rtc = config.ls.init(); | ||
| 145 | |||
| 146 | set_freqs(Clocks { | ||
| 147 | sys: sys_clk, | ||
| 148 | hclk1: ahb_freq, | ||
| 149 | hclk2: ahb_freq, | ||
| 150 | hclk3: shd_ahb_freq, | ||
| 151 | pclk1: apb1_freq, | ||
| 152 | pclk2: apb2_freq, | ||
| 153 | pclk3: shd_ahb_freq, | ||
| 154 | pclk1_tim: apb1_tim_freq, | ||
| 155 | pclk2_tim: apb2_tim_freq, | ||
| 156 | rtc, | ||
| 157 | }); | ||
| 158 | } | ||
| 159 | |||
| 160 | fn msirange_to_hertz(range: MSIRange) -> Hertz { | ||
| 161 | match range { | ||
| 162 | MSIRange::RANGE100K => Hertz(100_000), | ||
| 163 | MSIRange::RANGE200K => Hertz(200_000), | ||
| 164 | MSIRange::RANGE400K => Hertz(400_000), | ||
| 165 | MSIRange::RANGE800K => Hertz(800_000), | ||
| 166 | MSIRange::RANGE1M => Hertz(1_000_000), | ||
| 167 | MSIRange::RANGE2M => Hertz(2_000_000), | ||
| 168 | MSIRange::RANGE4M => Hertz(4_000_000), | ||
| 169 | MSIRange::RANGE8M => Hertz(8_000_000), | ||
| 170 | MSIRange::RANGE16M => Hertz(16_000_000), | ||
| 171 | MSIRange::RANGE24M => Hertz(24_000_000), | ||
| 172 | MSIRange::RANGE32M => Hertz(32_000_000), | ||
| 173 | MSIRange::RANGE48M => Hertz(48_000_000), | ||
| 174 | _ => unreachable!(), | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | fn msirange_to_vos(range: MSIRange) -> VoltageScale { | ||
| 179 | if range.to_bits() > MSIRange::RANGE16M.to_bits() { | ||
| 180 | VoltageScale::RANGE1 | ||
| 181 | } else { | ||
| 182 | VoltageScale::RANGE2 | ||
| 183 | } | ||
| 184 | } | ||
diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index fec0a349d..69527c9ad 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | use chrono::{NaiveDate, NaiveDateTime}; | 5 | use chrono::{NaiveDate, NaiveDateTime}; |
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_stm32::rcc::{ClockSrc, LsConfig, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv}; | ||
| 9 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | 8 | use embassy_stm32::rtc::{Rtc, RtcConfig}; |
| 10 | use embassy_stm32::time::Hertz; | 9 | use embassy_stm32::time::Hertz; |
| 11 | use embassy_stm32::Config; | 10 | use embassy_stm32::Config; |
| @@ -15,17 +14,23 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 15 | #[embassy_executor::main] | 14 | #[embassy_executor::main] |
| 16 | async fn main(_spawner: Spawner) { | 15 | async fn main(_spawner: Spawner) { |
| 17 | let mut config = Config::default(); | 16 | let mut config = Config::default(); |
| 18 | config.rcc.mux = ClockSrc::PLL1_R; | 17 | { |
| 19 | config.rcc.hse = Some(Hertz::mhz(8)); | 18 | use embassy_stm32::rcc::*; |
| 20 | config.rcc.pll = Some(Pll { | 19 | config.rcc.mux = ClockSrc::PLL1_R; |
| 21 | source: PLLSource::HSE, | 20 | config.rcc.hse = Some(Hse { |
| 22 | prediv: PllPreDiv::DIV1, | 21 | freq: Hertz::mhz(8), |
| 23 | mul: PllMul::MUL20, | 22 | mode: HseMode::Oscillator, |
| 24 | divp: None, | 23 | }); |
| 25 | divq: None, | 24 | config.rcc.pll = Some(Pll { |
| 26 | divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) | 25 | source: PLLSource::HSE, |
| 27 | }); | 26 | prediv: PllPreDiv::DIV1, |
| 28 | config.rcc.ls = LsConfig::default_lse(); | 27 | mul: PllMul::MUL20, |
| 28 | divp: None, | ||
| 29 | divq: None, | ||
| 30 | divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) | ||
| 31 | }); | ||
| 32 | config.rcc.ls = LsConfig::default_lse(); | ||
| 33 | } | ||
| 29 | let p = embassy_stm32::init(config); | 34 | let p = embassy_stm32::init(config); |
| 30 | 35 | ||
| 31 | info!("Hello World!"); | 36 | info!("Hello World!"); |
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 3c9d2cfc0..f76b504a7 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs | |||
| @@ -48,7 +48,6 @@ use embassy_net_adin1110::{self, Device, Runner, ADIN1110}; | |||
| 48 | use embedded_hal_bus::spi::ExclusiveDevice; | 48 | use embedded_hal_bus::spi::ExclusiveDevice; |
| 49 | use hal::gpio::Pull; | 49 | use hal::gpio::Pull; |
| 50 | use hal::i2c::Config as I2C_Config; | 50 | use hal::i2c::Config as I2C_Config; |
| 51 | use hal::rcc::{ClockSrc, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv}; | ||
| 52 | use hal::spi::{Config as SPI_Config, Spi}; | 51 | use hal::spi::{Config as SPI_Config, Spi}; |
| 53 | use hal::time::Hertz; | 52 | use hal::time::Hertz; |
| 54 | 53 | ||
| @@ -74,20 +73,25 @@ async fn main(spawner: Spawner) { | |||
| 74 | defmt::println!("Start main()"); | 73 | defmt::println!("Start main()"); |
| 75 | 74 | ||
| 76 | let mut config = embassy_stm32::Config::default(); | 75 | let mut config = embassy_stm32::Config::default(); |
| 77 | 76 | { | |
| 78 | // 80Mhz clock (Source: 8 / SrcDiv: 1 * PLLMul 20 / ClkDiv 2) | 77 | use embassy_stm32::rcc::*; |
| 79 | // 80MHz highest frequency for flash 0 wait. | 78 | // 80Mhz clock (Source: 8 / SrcDiv: 1 * PLLMul 20 / ClkDiv 2) |
| 80 | config.rcc.mux = ClockSrc::PLL1_R; | 79 | // 80MHz highest frequency for flash 0 wait. |
| 81 | config.rcc.hse = Some(Hertz::mhz(8)); | 80 | config.rcc.mux = ClockSrc::PLL1_R; |
| 82 | config.rcc.pll = Some(Pll { | 81 | config.rcc.hse = Some(Hse { |
| 83 | source: PLLSource::HSE, | 82 | freq: Hertz::mhz(8), |
| 84 | prediv: PllPreDiv::DIV1, | 83 | mode: HseMode::Oscillator, |
| 85 | mul: PllMul::MUL20, | 84 | }); |
| 86 | divp: None, | 85 | config.rcc.pll = Some(Pll { |
| 87 | divq: None, | 86 | source: PLLSource::HSE, |
| 88 | divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) | 87 | prediv: PllPreDiv::DIV1, |
| 89 | }); | 88 | mul: PllMul::MUL20, |
| 90 | config.rcc.hsi48 = true; // needed for rng | 89 | divp: None, |
| 90 | divq: None, | ||
| 91 | divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) | ||
| 92 | }); | ||
| 93 | config.rcc.hsi48 = true; // needed for rng | ||
| 94 | } | ||
| 91 | 95 | ||
| 92 | let dp = embassy_stm32::init(config); | 96 | let dp = embassy_stm32::init(config); |
| 93 | 97 | ||
diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs index 8c789afbc..e26c274ad 100644 --- a/examples/stm32wl/src/bin/lora_lorawan.rs +++ b/examples/stm32wl/src/bin/lora_lorawan.rs | |||
| @@ -12,7 +12,8 @@ use embassy_lora::LoraTimer; | |||
| 12 | use embassy_stm32::gpio::{Level, Output, Pin, Speed}; | 12 | use embassy_stm32::gpio::{Level, Output, Pin, Speed}; |
| 13 | use embassy_stm32::rng::{self, Rng}; | 13 | use embassy_stm32::rng::{self, Rng}; |
| 14 | use embassy_stm32::spi::Spi; | 14 | use embassy_stm32::spi::Spi; |
| 15 | use embassy_stm32::{bind_interrupts, pac, peripherals}; | 15 | use embassy_stm32::time::Hertz; |
| 16 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 16 | use embassy_time::Delay; | 17 | use embassy_time::Delay; |
| 17 | use lora_phy::mod_params::*; | 18 | use lora_phy::mod_params::*; |
| 18 | use lora_phy::sx1261_2::SX1261_2; | 19 | use lora_phy::sx1261_2::SX1261_2; |
| @@ -33,11 +34,24 @@ bind_interrupts!(struct Irqs{ | |||
| 33 | #[embassy_executor::main] | 34 | #[embassy_executor::main] |
| 34 | async fn main(_spawner: Spawner) { | 35 | async fn main(_spawner: Spawner) { |
| 35 | let mut config = embassy_stm32::Config::default(); | 36 | let mut config = embassy_stm32::Config::default(); |
| 36 | config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; | 37 | { |
| 38 | use embassy_stm32::rcc::*; | ||
| 39 | config.rcc.hse = Some(Hse { | ||
| 40 | freq: Hertz(32_000_000), | ||
| 41 | mode: HseMode::Bypass, | ||
| 42 | }); | ||
| 43 | config.rcc.mux = ClockSrc::PLL1_R; | ||
| 44 | config.rcc.pll = Some(Pll { | ||
| 45 | source: PLLSource::HSE, | ||
| 46 | prediv: PllPreDiv::DIV2, | ||
| 47 | mul: PllMul::MUL6, | ||
| 48 | divp: None, | ||
| 49 | divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG | ||
| 50 | divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) | ||
| 51 | }); | ||
| 52 | } | ||
| 37 | let p = embassy_stm32::init(config); | 53 | let p = embassy_stm32::init(config); |
| 38 | 54 | ||
| 39 | pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01)); | ||
| 40 | |||
| 41 | let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2); | 55 | let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2); |
| 42 | 56 | ||
| 43 | // Set CTRL1 and CTRL3 for high-power transmission, while CTRL2 acts as an RF switch between tx and rx | 57 | // Set CTRL1 and CTRL3 for high-power transmission, while CTRL2 acts as an RF switch between tx and rx |
diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs index 70676c704..2cf7ef9d0 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs | |||
| @@ -4,9 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::rcc::{ClockSrc, MSIRange}; | ||
| 8 | use embassy_stm32::rng::{self, Rng}; | 7 | use embassy_stm32::rng::{self, Rng}; |
| 9 | use embassy_stm32::{bind_interrupts, pac, peripherals}; | 8 | use embassy_stm32::time::Hertz; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 11 | ||
| 12 | bind_interrupts!(struct Irqs{ | 12 | bind_interrupts!(struct Irqs{ |
| @@ -16,11 +16,24 @@ bind_interrupts!(struct Irqs{ | |||
| 16 | #[embassy_executor::main] | 16 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner) { | 17 | async fn main(_spawner: Spawner) { |
| 18 | let mut config = embassy_stm32::Config::default(); | 18 | let mut config = embassy_stm32::Config::default(); |
| 19 | config.rcc.mux = ClockSrc::MSI(MSIRange::RANGE32M); | 19 | { |
| 20 | use embassy_stm32::rcc::*; | ||
| 21 | config.rcc.hse = Some(Hse { | ||
| 22 | freq: Hertz(32_000_000), | ||
| 23 | mode: HseMode::Bypass, | ||
| 24 | }); | ||
| 25 | config.rcc.mux = ClockSrc::PLL1_R; | ||
| 26 | config.rcc.pll = Some(Pll { | ||
| 27 | source: PLLSource::HSE, | ||
| 28 | prediv: PllPreDiv::DIV2, | ||
| 29 | mul: PllMul::MUL6, | ||
| 30 | divp: None, | ||
| 31 | divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG | ||
| 32 | divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) | ||
| 33 | }); | ||
| 34 | } | ||
| 20 | let p = embassy_stm32::init(config); | 35 | let p = embassy_stm32::init(config); |
| 21 | 36 | ||
| 22 | pac::RCC.ccipr().modify(|w| w.set_rngsel(0b11)); // msi | ||
| 23 | |||
| 24 | info!("Hello World!"); | 37 | info!("Hello World!"); |
| 25 | 38 | ||
| 26 | let mut rng = Rng::new(p.RNG, Irqs); | 39 | let mut rng = Rng::new(p.RNG, Irqs); |
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 0a70e6a7e..cb1738154 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs | |||
| @@ -402,9 +402,18 @@ pub fn config() -> Config { | |||
| 402 | #[cfg(feature = "stm32wl55jc")] | 402 | #[cfg(feature = "stm32wl55jc")] |
| 403 | { | 403 | { |
| 404 | use embassy_stm32::rcc::*; | 404 | use embassy_stm32::rcc::*; |
| 405 | config.rcc.mux = ClockSrc::MSI(MSIRange::RANGE32M); | 405 | config.rcc.hse = Some(Hse { |
| 406 | embassy_stm32::pac::RCC.ccipr().modify(|w| { | 406 | freq: Hertz(32_000_000), |
| 407 | w.set_rngsel(0b11); // msi | 407 | mode: HseMode::Bypass, |
| 408 | }); | ||
| 409 | config.rcc.mux = ClockSrc::PLL1_R; | ||
| 410 | config.rcc.pll = Some(Pll { | ||
| 411 | source: PLLSource::HSE, | ||
| 412 | prediv: PllPreDiv::DIV2, | ||
| 413 | mul: PllMul::MUL6, | ||
| 414 | divp: None, | ||
| 415 | divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG | ||
| 416 | divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) | ||
| 408 | }); | 417 | }); |
| 409 | } | 418 | } |
| 410 | 419 | ||
