diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-10-11 00:12:33 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-10-11 00:12:33 +0200 |
| commit | 0cfa8d1bb5807b25612ab21b9894fd59002e6dab (patch) | |
| tree | 5c605b75dcae810c088c8e704551abe3fd85e0db | |
| parent | eff73d6dfa4c5920a55a5ee2bf5c0b2ef68fbae1 (diff) | |
stm32/rcc: use more PLL etc enums from PAC.
| -rw-r--r-- | embassy-stm32/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-stm32/build.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/c0.rs | 72 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/f2.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/f3.rs | 187 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/g0.rs | 38 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/g4.rs | 127 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/h.rs | 12 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l0.rs | 176 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l1.rs | 207 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l4.rs | 12 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l5.rs | 12 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/wb.rs | 180 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/wba.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/wl.rs | 228 | ||||
| -rw-r--r-- | embassy-stm32/src/time.rs | 7 | ||||
| -rw-r--r-- | examples/stm32f334/src/bin/adc.rs | 4 | ||||
| -rw-r--r-- | examples/stm32f334/src/bin/opamp.rs | 4 | ||||
| -rw-r--r-- | examples/stm32g4/src/bin/adc.rs | 2 | ||||
| -rw-r--r-- | tests/stm32/src/common.rs | 8 |
20 files changed, 366 insertions, 930 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 70e8f2e29..b6641d71d 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -59,7 +59,7 @@ 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 | atomic-polyfill = "1.0.1" | 61 | atomic-polyfill = "1.0.1" |
| 62 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e89b8cfc30e480036aaf502f34c874ee42d68026" } | 62 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ff45aa382efb704dd2275dd69e71af73343f149d" } |
| 63 | vcell = "0.1.3" | 63 | vcell = "0.1.3" |
| 64 | bxcan = "0.7.0" | 64 | bxcan = "0.7.0" |
| 65 | nb = "1.0.0" | 65 | nb = "1.0.0" |
| @@ -77,7 +77,7 @@ critical-section = { version = "1.1", features = ["std"] } | |||
| 77 | [build-dependencies] | 77 | [build-dependencies] |
| 78 | proc-macro2 = "1.0.36" | 78 | proc-macro2 = "1.0.36" |
| 79 | quote = "1.0.15" | 79 | quote = "1.0.15" |
| 80 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e89b8cfc30e480036aaf502f34c874ee42d68026", default-features = false, features = ["metadata"]} | 80 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ff45aa382efb704dd2275dd69e71af73343f149d", default-features = false, features = ["metadata"]} |
| 81 | 81 | ||
| 82 | 82 | ||
| 83 | [features] | 83 | [features] |
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 643f1b6e9..810da37e9 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -908,7 +908,7 @@ fn main() { | |||
| 908 | match e { | 908 | match e { |
| 909 | "Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true, | 909 | "Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true, |
| 910 | "Timpre" | "Pllrclkpre" => false, | 910 | "Timpre" | "Pllrclkpre" => false, |
| 911 | e if e.ends_with("pre") || e.ends_with("div") || e.ends_with("mul") => true, | 911 | e if e.ends_with("pre") || e.ends_with("pres") || e.ends_with("div") || e.ends_with("mul") => true, |
| 912 | _ => false, | 912 | _ => false, |
| 913 | } | 913 | } |
| 914 | } | 914 | } |
diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index efa56de7b..34d339a78 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use crate::pac::flash::vals::Latency; | 1 | use crate::pac::flash::vals::Latency; |
| 2 | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; | 2 | use crate::pac::rcc::vals::Sw; |
| 3 | use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw}; | 3 | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Hsidiv as HSIPrescaler, Ppre as APBPrescaler}; |
| 4 | use crate::pac::{FLASH, RCC}; | 4 | use crate::pac::{FLASH, RCC}; |
| 5 | use crate::rcc::{set_freqs, Clocks}; | 5 | use crate::rcc::{set_freqs, Clocks}; |
| 6 | use crate::time::Hertz; | 6 | use crate::time::Hertz; |
| @@ -19,33 +19,6 @@ pub enum ClockSrc { | |||
| 19 | LSI, | 19 | LSI, |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | #[derive(Clone, Copy)] | ||
| 23 | pub enum HSIPrescaler { | ||
| 24 | NotDivided, | ||
| 25 | Div2, | ||
| 26 | Div4, | ||
| 27 | Div8, | ||
| 28 | Div16, | ||
| 29 | Div32, | ||
| 30 | Div64, | ||
| 31 | Div128, | ||
| 32 | } | ||
| 33 | |||
| 34 | impl Into<Hsidiv> for HSIPrescaler { | ||
| 35 | fn into(self) -> Hsidiv { | ||
| 36 | match self { | ||
| 37 | HSIPrescaler::NotDivided => Hsidiv::DIV1, | ||
| 38 | HSIPrescaler::Div2 => Hsidiv::DIV2, | ||
| 39 | HSIPrescaler::Div4 => Hsidiv::DIV4, | ||
| 40 | HSIPrescaler::Div8 => Hsidiv::DIV8, | ||
| 41 | HSIPrescaler::Div16 => Hsidiv::DIV16, | ||
| 42 | HSIPrescaler::Div32 => Hsidiv::DIV32, | ||
| 43 | HSIPrescaler::Div64 => Hsidiv::DIV64, | ||
| 44 | HSIPrescaler::Div128 => Hsidiv::DIV128, | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | /// Clocks configutation | 22 | /// Clocks configutation |
| 50 | pub struct Config { | 23 | pub struct Config { |
| 51 | pub mux: ClockSrc, | 24 | pub mux: ClockSrc, |
| @@ -57,7 +30,7 @@ impl Default for Config { | |||
| 57 | #[inline] | 30 | #[inline] |
| 58 | fn default() -> Config { | 31 | fn default() -> Config { |
| 59 | Config { | 32 | Config { |
| 60 | mux: ClockSrc::HSI(HSIPrescaler::NotDivided), | 33 | mux: ClockSrc::HSI(HSIPrescaler::DIV1), |
| 61 | ahb_pre: AHBPrescaler::DIV1, | 34 | ahb_pre: AHBPrescaler::DIV1, |
| 62 | apb_pre: APBPrescaler::DIV1, | 35 | apb_pre: APBPrescaler::DIV1, |
| 63 | } | 36 | } |
| @@ -68,33 +41,32 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 68 | let (sys_clk, sw) = match config.mux { | 41 | let (sys_clk, sw) = match config.mux { |
| 69 | ClockSrc::HSI(div) => { | 42 | ClockSrc::HSI(div) => { |
| 70 | // Enable HSI | 43 | // Enable HSI |
| 71 | let div: Hsidiv = div.into(); | ||
| 72 | RCC.cr().write(|w| { | 44 | RCC.cr().write(|w| { |
| 73 | w.set_hsidiv(div); | 45 | w.set_hsidiv(div); |
| 74 | w.set_hsion(true) | 46 | w.set_hsion(true) |
| 75 | }); | 47 | }); |
| 76 | while !RCC.cr().read().hsirdy() {} | 48 | while !RCC.cr().read().hsirdy() {} |
| 77 | 49 | ||
| 78 | (HSI_FREQ.0 >> div.to_bits(), Sw::HSI) | 50 | (HSI_FREQ / div, Sw::HSI) |
| 79 | } | 51 | } |
| 80 | ClockSrc::HSE(freq) => { | 52 | ClockSrc::HSE(freq) => { |
| 81 | // Enable HSE | 53 | // Enable HSE |
| 82 | RCC.cr().write(|w| w.set_hseon(true)); | 54 | RCC.cr().write(|w| w.set_hseon(true)); |
| 83 | while !RCC.cr().read().hserdy() {} | 55 | while !RCC.cr().read().hserdy() {} |
| 84 | 56 | ||
| 85 | (freq.0, Sw::HSE) | 57 | (freq, Sw::HSE) |
| 86 | } | 58 | } |
| 87 | ClockSrc::LSI => { | 59 | ClockSrc::LSI => { |
| 88 | // Enable LSI | 60 | // Enable LSI |
| 89 | RCC.csr2().write(|w| w.set_lsion(true)); | 61 | RCC.csr2().write(|w| w.set_lsion(true)); |
| 90 | while !RCC.csr2().read().lsirdy() {} | 62 | while !RCC.csr2().read().lsirdy() {} |
| 91 | (LSI_FREQ.0, Sw::LSI) | 63 | (LSI_FREQ, Sw::LSI) |
| 92 | } | 64 | } |
| 93 | }; | 65 | }; |
| 94 | 66 | ||
| 95 | // Determine the flash latency implied by the target clock speed | 67 | // Determine the flash latency implied by the target clock speed |
| 96 | // RM0454 § 3.3.4: | 68 | // RM0454 § 3.3.4: |
| 97 | let target_flash_latency = if sys_clk <= 24_000_000 { | 69 | let target_flash_latency = if sys_clk <= Hertz(24_000_000) { |
| 98 | Latency::WS0 | 70 | Latency::WS0 |
| 99 | } else { | 71 | } else { |
| 100 | Latency::WS1 | 72 | Latency::WS1 |
| @@ -129,7 +101,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 129 | } | 101 | } |
| 130 | 102 | ||
| 131 | // Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once | 103 | // Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once |
| 132 | let (sw, hpre, ppre) = (sw.into(), config.ahb_pre.into(), config.apb_pre.into()); | 104 | let (sw, hpre, ppre) = (sw.into(), config.ahb_pre, config.apb_pre); |
| 133 | RCC.cfgr().modify(|w| { | 105 | RCC.cfgr().modify(|w| { |
| 134 | w.set_sw(sw); | 106 | w.set_sw(sw); |
| 135 | w.set_hpre(hpre); | 107 | w.set_hpre(hpre); |
| @@ -150,34 +122,20 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 150 | FLASH.acr().modify(|w| w.set_latency(target_flash_latency)); | 122 | FLASH.acr().modify(|w| w.set_latency(target_flash_latency)); |
| 151 | } | 123 | } |
| 152 | 124 | ||
| 153 | let ahb_div = match config.ahb_pre { | 125 | let ahb_freq = sys_clk / config.ahb_pre; |
| 154 | AHBPrescaler::DIV1 => 1, | ||
| 155 | AHBPrescaler::DIV2 => 2, | ||
| 156 | AHBPrescaler::DIV4 => 4, | ||
| 157 | AHBPrescaler::DIV8 => 8, | ||
| 158 | AHBPrescaler::DIV16 => 16, | ||
| 159 | AHBPrescaler::DIV64 => 64, | ||
| 160 | AHBPrescaler::DIV128 => 128, | ||
| 161 | AHBPrescaler::DIV256 => 256, | ||
| 162 | AHBPrescaler::DIV512 => 512, | ||
| 163 | _ => unreachable!(), | ||
| 164 | }; | ||
| 165 | let ahb_freq = sys_clk / ahb_div; | ||
| 166 | 126 | ||
| 167 | let (apb_freq, apb_tim_freq) = match config.apb_pre { | 127 | let (apb_freq, apb_tim_freq) = match config.apb_pre { |
| 168 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | 128 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), |
| 169 | pre => { | 129 | pre => { |
| 170 | let pre: Ppre = pre.into(); | 130 | let freq = ahb_freq / pre; |
| 171 | let pre: u8 = 1 << (pre.to_bits() - 3); | 131 | (freq, freq * 2u32) |
| 172 | let freq = ahb_freq / pre as u32; | ||
| 173 | (freq, freq * 2) | ||
| 174 | } | 132 | } |
| 175 | }; | 133 | }; |
| 176 | 134 | ||
| 177 | set_freqs(Clocks { | 135 | set_freqs(Clocks { |
| 178 | sys: Hertz(sys_clk), | 136 | sys: sys_clk, |
| 179 | ahb1: Hertz(ahb_freq), | 137 | ahb1: ahb_freq, |
| 180 | apb1: Hertz(apb_freq), | 138 | apb1: apb_freq, |
| 181 | apb1_tim: Hertz(apb_tim_freq), | 139 | apb1_tim: apb_tim_freq, |
| 182 | }); | 140 | }); |
| 183 | } | 141 | } |
diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index 07b816bf5..478d8894f 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs | |||
| @@ -301,9 +301,9 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 301 | 301 | ||
| 302 | RCC.cfgr().modify(|w| { | 302 | RCC.cfgr().modify(|w| { |
| 303 | w.set_sw(sw.into()); | 303 | w.set_sw(sw.into()); |
| 304 | w.set_hpre(config.ahb_pre.into()); | 304 | w.set_hpre(config.ahb_pre); |
| 305 | w.set_ppre1(config.apb1_pre.into()); | 305 | w.set_ppre1(config.apb1_pre); |
| 306 | w.set_ppre2(config.apb2_pre.into()); | 306 | w.set_ppre2(config.apb2_pre); |
| 307 | }); | 307 | }); |
| 308 | while RCC.cfgr().read().sws().to_bits() != sw.to_bits() {} | 308 | while RCC.cfgr().read().sws().to_bits() != sw.to_bits() {} |
| 309 | 309 | ||
diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index 630dbd4fe..a11eeee54 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | #[cfg(rcc_f3)] | 1 | #[cfg(rcc_f3)] |
| 2 | use crate::pac::adccommon::vals::Ckmode; | 2 | use crate::pac::adccommon::vals::Ckmode; |
| 3 | use crate::pac::flash::vals::Latency; | 3 | use crate::pac::flash::vals::Latency; |
| 4 | use crate::pac::rcc::vals::{Adcpres, Hpre, Pllmul, Pllsrc, Ppre, Prediv, Sw, Usbpre}; | 4 | pub use crate::pac::rcc::vals::Adcpres; |
| 5 | use crate::pac::rcc::vals::{Hpre, Pllmul, Pllsrc, Ppre, Prediv, Sw, Usbpre}; | ||
| 5 | use crate::pac::{FLASH, RCC}; | 6 | use crate::pac::{FLASH, RCC}; |
| 6 | use crate::rcc::{set_freqs, Clocks}; | 7 | use crate::rcc::{set_freqs, Clocks}; |
| 7 | use crate::time::Hertz; | 8 | use crate::time::Hertz; |
| @@ -12,25 +13,6 @@ pub const HSI_FREQ: Hertz = Hertz(8_000_000); | |||
| 12 | /// LSI speed | 13 | /// LSI speed |
| 13 | pub const LSI_FREQ: Hertz = Hertz(40_000); | 14 | pub const LSI_FREQ: Hertz = Hertz(40_000); |
| 14 | 15 | ||
| 15 | impl From<AdcClockSource> for Adcpres { | ||
| 16 | fn from(value: AdcClockSource) -> Self { | ||
| 17 | match value { | ||
| 18 | AdcClockSource::PllDiv1 => Adcpres::DIV1, | ||
| 19 | AdcClockSource::PllDiv2 => Adcpres::DIV2, | ||
| 20 | AdcClockSource::PllDiv4 => Adcpres::DIV4, | ||
| 21 | AdcClockSource::PllDiv6 => Adcpres::DIV6, | ||
| 22 | AdcClockSource::PllDiv8 => Adcpres::DIV8, | ||
| 23 | AdcClockSource::PllDiv12 => Adcpres::DIV12, | ||
| 24 | AdcClockSource::PllDiv16 => Adcpres::DIV16, | ||
| 25 | AdcClockSource::PllDiv32 => Adcpres::DIV32, | ||
| 26 | AdcClockSource::PllDiv64 => Adcpres::DIV64, | ||
| 27 | AdcClockSource::PllDiv128 => Adcpres::DIV128, | ||
| 28 | AdcClockSource::PllDiv256 => Adcpres::DIV256, | ||
| 29 | _ => unreachable!(), | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | #[cfg(rcc_f3)] | 16 | #[cfg(rcc_f3)] |
| 35 | impl From<AdcClockSource> for Ckmode { | 17 | impl From<AdcClockSource> for Ckmode { |
| 36 | fn from(value: AdcClockSource) -> Self { | 18 | fn from(value: AdcClockSource) -> Self { |
| @@ -45,32 +27,13 @@ impl From<AdcClockSource> for Ckmode { | |||
| 45 | 27 | ||
| 46 | #[derive(Clone, Copy)] | 28 | #[derive(Clone, Copy)] |
| 47 | pub enum AdcClockSource { | 29 | pub enum AdcClockSource { |
| 48 | PllDiv1 = 1, | 30 | Pll(Adcpres), |
| 49 | PllDiv2 = 2, | ||
| 50 | PllDiv4 = 4, | ||
| 51 | PllDiv6 = 6, | ||
| 52 | PllDiv8 = 8, | ||
| 53 | PllDiv12 = 12, | ||
| 54 | PllDiv16 = 16, | ||
| 55 | PllDiv32 = 32, | ||
| 56 | PllDiv64 = 64, | ||
| 57 | PllDiv128 = 128, | ||
| 58 | PllDiv256 = 256, | ||
| 59 | BusDiv1, | 31 | BusDiv1, |
| 60 | BusDiv2, | 32 | BusDiv2, |
| 61 | BusDiv4, | 33 | BusDiv4, |
| 62 | } | 34 | } |
| 63 | 35 | ||
| 64 | impl AdcClockSource { | 36 | impl AdcClockSource { |
| 65 | pub fn is_bus(&self) -> bool { | ||
| 66 | match self { | ||
| 67 | Self::BusDiv1 => true, | ||
| 68 | Self::BusDiv2 => true, | ||
| 69 | Self::BusDiv4 => true, | ||
| 70 | _ => false, | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | pub fn bus_div(&self) -> u32 { | 37 | pub fn bus_div(&self) -> u32 { |
| 75 | match self { | 38 | match self { |
| 76 | Self::BusDiv1 => 1, | 39 | Self::BusDiv1 => 1, |
| @@ -137,67 +100,67 @@ struct PllConfig { | |||
| 137 | /// Initialize and Set the clock frequencies | 100 | /// Initialize and Set the clock frequencies |
| 138 | pub(crate) unsafe fn init(config: Config) { | 101 | pub(crate) unsafe fn init(config: Config) { |
| 139 | // Calculate the real System clock, and PLL configuration if applicable | 102 | // Calculate the real System clock, and PLL configuration if applicable |
| 140 | let (Hertz(sysclk), pll_config) = get_sysclk(&config); | 103 | let (sysclk, pll_config) = get_sysclk(&config); |
| 141 | assert!(sysclk <= 72_000_000); | 104 | assert!(sysclk.0 <= 72_000_000); |
| 142 | 105 | ||
| 143 | // Calculate real AHB clock | 106 | // Calculate real AHB clock |
| 144 | let hclk = config.hclk.map(|h| h.0).unwrap_or(sysclk); | 107 | let hclk = config.hclk.map(|h| h).unwrap_or(sysclk); |
| 145 | let (hpre_bits, hpre_div) = match sysclk / hclk { | 108 | let hpre = match sysclk.0 / hclk.0 { |
| 146 | 0 => unreachable!(), | 109 | 0 => unreachable!(), |
| 147 | 1 => (Hpre::DIV1, 1), | 110 | 1 => Hpre::DIV1, |
| 148 | 2 => (Hpre::DIV2, 2), | 111 | 2 => Hpre::DIV2, |
| 149 | 3..=5 => (Hpre::DIV4, 4), | 112 | 3..=5 => Hpre::DIV4, |
| 150 | 6..=11 => (Hpre::DIV8, 8), | 113 | 6..=11 => Hpre::DIV8, |
| 151 | 12..=39 => (Hpre::DIV16, 16), | 114 | 12..=39 => Hpre::DIV16, |
| 152 | 40..=95 => (Hpre::DIV64, 64), | 115 | 40..=95 => Hpre::DIV64, |
| 153 | 96..=191 => (Hpre::DIV128, 128), | 116 | 96..=191 => Hpre::DIV128, |
| 154 | 192..=383 => (Hpre::DIV256, 256), | 117 | 192..=383 => Hpre::DIV256, |
| 155 | _ => (Hpre::DIV512, 512), | 118 | _ => Hpre::DIV512, |
| 156 | }; | 119 | }; |
| 157 | let hclk = sysclk / hpre_div; | 120 | let hclk = sysclk / hpre; |
| 158 | assert!(hclk <= 72_000_000); | 121 | assert!(hclk <= Hertz(72_000_000)); |
| 159 | 122 | ||
| 160 | // Calculate real APB1 clock | 123 | // Calculate real APB1 clock |
| 161 | let pclk1 = config.pclk1.map(|p| p.0).unwrap_or(hclk); | 124 | let pclk1 = config.pclk1.unwrap_or(hclk); |
| 162 | let (ppre1_bits, ppre1) = match hclk / pclk1 { | 125 | let ppre1 = match hclk / pclk1 { |
| 163 | 0 => unreachable!(), | 126 | 0 => unreachable!(), |
| 164 | 1 => (Ppre::DIV1, 1), | 127 | 1 => Ppre::DIV1, |
| 165 | 2 => (Ppre::DIV2, 2), | 128 | 2 => Ppre::DIV2, |
| 166 | 3..=5 => (Ppre::DIV4, 4), | 129 | 3..=5 => Ppre::DIV4, |
| 167 | 6..=11 => (Ppre::DIV8, 8), | 130 | 6..=11 => Ppre::DIV8, |
| 168 | _ => (Ppre::DIV16, 16), | 131 | _ => Ppre::DIV16, |
| 169 | }; | 132 | }; |
| 170 | let timer_mul1 = if ppre1 == 1 { 1 } else { 2 }; | 133 | let timer_mul1 = if ppre1 == Ppre::DIV1 { 1u32 } else { 2 }; |
| 171 | let pclk1 = hclk / ppre1; | 134 | let pclk1 = hclk / ppre1; |
| 172 | assert!(pclk1 <= 36_000_000); | 135 | assert!(pclk1 <= Hertz(36_000_000)); |
| 173 | 136 | ||
| 174 | // Calculate real APB2 clock | 137 | // Calculate real APB2 clock |
| 175 | let pclk2 = config.pclk2.map(|p| p.0).unwrap_or(hclk); | 138 | let pclk2 = config.pclk2.unwrap_or(hclk); |
| 176 | let (ppre2_bits, ppre2) = match hclk / pclk2 { | 139 | let ppre2 = match hclk / pclk2 { |
| 177 | 0 => unreachable!(), | 140 | 0 => unreachable!(), |
| 178 | 1 => (Ppre::DIV1, 1), | 141 | 1 => Ppre::DIV1, |
| 179 | 2 => (Ppre::DIV2, 2), | 142 | 2 => Ppre::DIV2, |
| 180 | 3..=5 => (Ppre::DIV4, 4), | 143 | 3..=5 => Ppre::DIV4, |
| 181 | 6..=11 => (Ppre::DIV8, 8), | 144 | 6..=11 => Ppre::DIV8, |
| 182 | _ => (Ppre::DIV16, 16), | 145 | _ => Ppre::DIV16, |
| 183 | }; | 146 | }; |
| 184 | let timer_mul2 = if ppre2 == 1 { 1 } else { 2 }; | 147 | let timer_mul2 = if ppre2 == Ppre::DIV1 { 1u32 } else { 2 }; |
| 185 | let pclk2 = hclk / ppre2; | 148 | let pclk2 = hclk / ppre2; |
| 186 | assert!(pclk2 <= 72_000_000); | 149 | assert!(pclk2 <= Hertz(72_000_000)); |
| 187 | 150 | ||
| 188 | // Set latency based on HCLK frquency | 151 | // Set latency based on HCLK frquency |
| 189 | // RM0316: "The prefetch buffer must be kept on when using a prescaler | 152 | // RM0316: "The prefetch buffer must be kept on when using a prescaler |
| 190 | // different from 1 on the AHB clock.", "Half-cycle access cannot be | 153 | // different from 1 on the AHB clock.", "Half-cycle access cannot be |
| 191 | // used when there is a prescaler different from 1 on the AHB clock" | 154 | // used when there is a prescaler different from 1 on the AHB clock" |
| 192 | FLASH.acr().modify(|w| { | 155 | FLASH.acr().modify(|w| { |
| 193 | w.set_latency(if hclk <= 24_000_000 { | 156 | w.set_latency(if hclk <= Hertz(24_000_000) { |
| 194 | Latency::WS0 | 157 | Latency::WS0 |
| 195 | } else if hclk <= 48_000_000 { | 158 | } else if hclk <= Hertz(48_000_000) { |
| 196 | Latency::WS1 | 159 | Latency::WS1 |
| 197 | } else { | 160 | } else { |
| 198 | Latency::WS2 | 161 | Latency::WS2 |
| 199 | }); | 162 | }); |
| 200 | if hpre_div != 1 { | 163 | if hpre != Hpre::DIV1 { |
| 201 | w.set_hlfcya(false); | 164 | w.set_hlfcya(false); |
| 202 | w.set_prftbe(true); | 165 | w.set_prftbe(true); |
| 203 | } | 166 | } |
| @@ -240,9 +203,9 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 240 | // Set prescalers | 203 | // Set prescalers |
| 241 | // CFGR has been written before (PLL, PLL48) don't overwrite these settings | 204 | // CFGR has been written before (PLL, PLL48) don't overwrite these settings |
| 242 | RCC.cfgr().modify(|w| { | 205 | RCC.cfgr().modify(|w| { |
| 243 | w.set_ppre2(ppre2_bits); | 206 | w.set_ppre2(ppre2); |
| 244 | w.set_ppre1(ppre1_bits); | 207 | w.set_ppre1(ppre1); |
| 245 | w.set_hpre(hpre_bits); | 208 | w.set_hpre(hpre); |
| 246 | }); | 209 | }); |
| 247 | 210 | ||
| 248 | // Wait for the new prescalers to kick in | 211 | // Wait for the new prescalers to kick in |
| @@ -260,45 +223,43 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 260 | }); | 223 | }); |
| 261 | 224 | ||
| 262 | #[cfg(rcc_f3)] | 225 | #[cfg(rcc_f3)] |
| 263 | let adc = config.adc.map(|adc| { | 226 | let adc = config.adc.map(|adc| match adc { |
| 264 | if !adc.is_bus() { | 227 | AdcClockSource::Pll(adcpres) => { |
| 265 | RCC.cfgr2().modify(|w| { | 228 | RCC.cfgr2().modify(|w| { |
| 266 | // Make sure that we're using the PLL | 229 | // Make sure that we're using the PLL |
| 267 | pll_config.unwrap(); | 230 | pll_config.unwrap(); |
| 268 | w.set_adc12pres(adc.into()); | 231 | w.set_adc12pres(adcpres); |
| 269 | 232 | ||
| 270 | Hertz(sysclk / adc as u32) | 233 | sysclk / adcpres |
| 271 | }) | 234 | }) |
| 272 | } else { | 235 | } |
| 273 | crate::pac::ADC_COMMON.ccr().modify(|w| { | 236 | _ => crate::pac::ADC_COMMON.ccr().modify(|w| { |
| 274 | assert!(!(adc.bus_div() == 1 && hpre_bits != Hpre::DIV1)); | 237 | assert!(!(adc.bus_div() == 1 && hpre != Hpre::DIV1)); |
| 275 | 238 | ||
| 276 | w.set_ckmode(adc.into()); | 239 | w.set_ckmode(adc.into()); |
| 277 | 240 | ||
| 278 | Hertz(sysclk / adc.bus_div() as u32) | 241 | sysclk / adc.bus_div() |
| 279 | }) | 242 | }), |
| 280 | } | ||
| 281 | }); | 243 | }); |
| 282 | 244 | ||
| 283 | #[cfg(all(rcc_f3, adc3_common))] | 245 | #[cfg(all(rcc_f3, adc3_common))] |
| 284 | let adc34 = config.adc.map(|adc| { | 246 | let adc34 = config.adc34.map(|adc| match adc { |
| 285 | if !adc.is_bus() { | 247 | AdcClockSource::Pll(adcpres) => { |
| 286 | RCC.cfgr2().modify(|w| { | 248 | RCC.cfgr2().modify(|w| { |
| 287 | // Make sure that we're using the PLL | 249 | // Make sure that we're using the PLL |
| 288 | pll_config.unwrap(); | 250 | pll_config.unwrap(); |
| 289 | w.set_adc12pres(adc.into()); | 251 | w.set_adc34pres(adcpres); |
| 290 | 252 | ||
| 291 | Hertz(sysclk / adc as u32) | 253 | sysclk / adcpres |
| 292 | }) | 254 | }) |
| 293 | } else { | 255 | } |
| 294 | crate::pac::ADC3_COMMON.ccr().modify(|w| { | 256 | _ => crate::pac::ADC_COMMON.ccr().modify(|w| { |
| 295 | assert!(!(adc.bus_div() == 1 && hpre_bits != Hpre::DIV1)); | 257 | assert!(!(adc.bus_div() == 1 && hpre != Hpre::DIV1)); |
| 296 | 258 | ||
| 297 | w.set_ckmode(adc.into()); | 259 | w.set_ckmode(adc.into()); |
| 298 | 260 | ||
| 299 | Hertz(sysclk / adc.bus_div() as u32) | 261 | sysclk / adc.bus_div() |
| 300 | }) | 262 | }), |
| 301 | } | ||
| 302 | }); | 263 | }); |
| 303 | 264 | ||
| 304 | #[cfg(stm32f334)] | 265 | #[cfg(stm32f334)] |
| @@ -310,21 +271,21 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 310 | 271 | ||
| 311 | // Make sure that we're using the PLL | 272 | // Make sure that we're using the PLL |
| 312 | pll_config.unwrap(); | 273 | pll_config.unwrap(); |
| 313 | assert!((pclk2 == sysclk) || (pclk2 * 2 == sysclk)); | 274 | assert!((pclk2 == sysclk) || (pclk2 * 2u32 == sysclk)); |
| 314 | 275 | ||
| 315 | RCC.cfgr3().modify(|w| w.set_hrtim1sw(Timsw::PLL)); | 276 | RCC.cfgr3().modify(|w| w.set_hrtim1sw(Timsw::PLL)); |
| 316 | 277 | ||
| 317 | Some(Hertz(sysclk * 2)) | 278 | Some(sysclk * 2u32) |
| 318 | } | 279 | } |
| 319 | }; | 280 | }; |
| 320 | 281 | ||
| 321 | set_freqs(Clocks { | 282 | set_freqs(Clocks { |
| 322 | sys: Hertz(sysclk), | 283 | sys: sysclk, |
| 323 | apb1: Hertz(pclk1), | 284 | apb1: pclk1, |
| 324 | apb2: Hertz(pclk2), | 285 | apb2: pclk2, |
| 325 | apb1_tim: Hertz(pclk1 * timer_mul1), | 286 | apb1_tim: pclk1 * timer_mul1, |
| 326 | apb2_tim: Hertz(pclk2 * timer_mul2), | 287 | apb2_tim: pclk2 * timer_mul2, |
| 327 | ahb1: Hertz(hclk), | 288 | ahb1: hclk, |
| 328 | #[cfg(rcc_f3)] | 289 | #[cfg(rcc_f3)] |
| 329 | adc: adc, | 290 | adc: adc, |
| 330 | #[cfg(all(rcc_f3, adc3_common))] | 291 | #[cfg(all(rcc_f3, adc3_common))] |
| @@ -421,16 +382,16 @@ fn calc_pll(config: &Config, Hertz(sysclk): Hertz) -> (Hertz, PllConfig) { | |||
| 421 | 382 | ||
| 422 | #[inline] | 383 | #[inline] |
| 423 | #[allow(unused_variables)] | 384 | #[allow(unused_variables)] |
| 424 | fn get_usb_pre(config: &Config, sysclk: u32, pclk1: u32, pll_config: &Option<PllConfig>) -> Usbpre { | 385 | fn get_usb_pre(config: &Config, sysclk: Hertz, pclk1: Hertz, pll_config: &Option<PllConfig>) -> Usbpre { |
| 425 | cfg_if::cfg_if! { | 386 | cfg_if::cfg_if! { |
| 426 | // Some chips do not have USB | 387 | // Some chips do not have USB |
| 427 | if #[cfg(any(stm32f301, stm32f318, stm32f334))] { | 388 | if #[cfg(any(stm32f301, stm32f318, stm32f334))] { |
| 428 | panic!("USB clock not supported by the chip"); | 389 | panic!("USB clock not supported by the chip"); |
| 429 | } else { | 390 | } else { |
| 430 | let usb_ok = config.hse.is_some() && pll_config.is_some() && (pclk1 >= 10_000_000); | 391 | let usb_ok = config.hse.is_some() && pll_config.is_some() && (pclk1 >= Hertz(10_000_000)); |
| 431 | match (usb_ok, sysclk) { | 392 | match (usb_ok, sysclk) { |
| 432 | (true, 72_000_000) => Usbpre::DIV1_5, | 393 | (true, Hertz(72_000_000)) => Usbpre::DIV1_5, |
| 433 | (true, 48_000_000) => Usbpre::DIV1, | 394 | (true, Hertz(48_000_000)) => Usbpre::DIV1, |
| 434 | _ => panic!( | 395 | _ => panic!( |
| 435 | "USB clock is only valid if the PLL output frequency is either 48MHz or 72MHz" | 396 | "USB clock is only valid if the PLL output frequency is either 48MHz or 72MHz" |
| 436 | ), | 397 | ), |
diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index 5ac409113..823836af7 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | use crate::pac::flash::vals::Latency; | 1 | use crate::pac::flash::vals::Latency; |
| 2 | use crate::pac::rcc::vals::{self, Hsidiv, Sw}; | 2 | use crate::pac::rcc::vals::{self, Sw}; |
| 3 | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Ppre as APBPrescaler}; | 3 | pub use crate::pac::rcc::vals::{ |
| 4 | Hpre as AHBPrescaler, Hsidiv as HSI16Prescaler, Pllm, Plln, Pllp, Pllq, Pllr, Ppre as APBPrescaler, | ||
| 5 | }; | ||
| 4 | use crate::pac::{FLASH, PWR, RCC}; | 6 | use crate::pac::{FLASH, PWR, RCC}; |
| 5 | use crate::rcc::{set_freqs, Clocks}; | 7 | use crate::rcc::{set_freqs, Clocks}; |
| 6 | use crate::time::Hertz; | 8 | use crate::time::Hertz; |
| @@ -20,33 +22,6 @@ pub enum ClockSrc { | |||
| 20 | LSI, | 22 | LSI, |
| 21 | } | 23 | } |
| 22 | 24 | ||
| 23 | #[derive(Clone, Copy)] | ||
| 24 | pub enum HSI16Prescaler { | ||
| 25 | NotDivided, | ||
| 26 | Div2, | ||
| 27 | Div4, | ||
| 28 | Div8, | ||
| 29 | Div16, | ||
| 30 | Div32, | ||
| 31 | Div64, | ||
| 32 | Div128, | ||
| 33 | } | ||
| 34 | |||
| 35 | impl Into<Hsidiv> for HSI16Prescaler { | ||
| 36 | fn into(self) -> Hsidiv { | ||
| 37 | match self { | ||
| 38 | HSI16Prescaler::NotDivided => Hsidiv::DIV1, | ||
| 39 | HSI16Prescaler::Div2 => Hsidiv::DIV2, | ||
| 40 | HSI16Prescaler::Div4 => Hsidiv::DIV4, | ||
| 41 | HSI16Prescaler::Div8 => Hsidiv::DIV8, | ||
| 42 | HSI16Prescaler::Div16 => Hsidiv::DIV16, | ||
| 43 | HSI16Prescaler::Div32 => Hsidiv::DIV32, | ||
| 44 | HSI16Prescaler::Div64 => Hsidiv::DIV64, | ||
| 45 | HSI16Prescaler::Div128 => Hsidiv::DIV128, | ||
| 46 | } | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | /// The PLL configuration. | 25 | /// The PLL configuration. |
| 51 | /// | 26 | /// |
| 52 | /// * `VCOCLK = source / m * n` | 27 | /// * `VCOCLK = source / m * n` |
| @@ -104,7 +79,7 @@ impl Default for Config { | |||
| 104 | #[inline] | 79 | #[inline] |
| 105 | fn default() -> Config { | 80 | fn default() -> Config { |
| 106 | Config { | 81 | Config { |
| 107 | mux: ClockSrc::HSI16(HSI16Prescaler::NotDivided), | 82 | mux: ClockSrc::HSI16(HSI16Prescaler::DIV1), |
| 108 | ahb_pre: AHBPrescaler::DIV1, | 83 | ahb_pre: AHBPrescaler::DIV1, |
| 109 | apb_pre: APBPrescaler::DIV1, | 84 | apb_pre: APBPrescaler::DIV1, |
| 110 | low_power_run: false, | 85 | low_power_run: false, |
| @@ -195,7 +170,6 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 195 | let (sys_clk, sw) = match config.mux { | 170 | let (sys_clk, sw) = match config.mux { |
| 196 | ClockSrc::HSI16(div) => { | 171 | ClockSrc::HSI16(div) => { |
| 197 | // Enable HSI16 | 172 | // Enable HSI16 |
| 198 | let div: Hsidiv = div.into(); | ||
| 199 | RCC.cr().write(|w| { | 173 | RCC.cr().write(|w| { |
| 200 | w.set_hsidiv(div); | 174 | w.set_hsidiv(div); |
| 201 | w.set_hsion(true) | 175 | w.set_hsion(true) |
| @@ -262,7 +236,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 262 | } | 236 | } |
| 263 | 237 | ||
| 264 | // Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once | 238 | // Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once |
| 265 | let (sw, hpre, ppre) = (sw.into(), config.ahb_pre.into(), config.apb_pre.into()); | 239 | let (sw, hpre, ppre) = (sw.into(), config.ahb_pre, config.apb_pre); |
| 266 | RCC.cfgr().modify(|w| { | 240 | RCC.cfgr().modify(|w| { |
| 267 | w.set_sw(sw); | 241 | w.set_sw(sw); |
| 268 | w.set_hpre(hpre); | 242 | w.set_hpre(hpre); |
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index 08ccc5fe9..43256524d 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs | |||
| @@ -3,7 +3,8 @@ use stm32_metapac::rcc::vals::{Adcsel, Pllsrc, Sw}; | |||
| 3 | use stm32_metapac::FLASH; | 3 | use stm32_metapac::FLASH; |
| 4 | 4 | ||
| 5 | pub use crate::pac::rcc::vals::{ | 5 | pub use crate::pac::rcc::vals::{ |
| 6 | Hpre as AHBPrescaler, Pllm as PllM, Plln as PllN, Pllp as PllP, Pllq as PllQ, Pllr as PllR, Ppre as APBPrescaler, | 6 | Adcsel as AdcClockSource, Hpre as AHBPrescaler, Pllm as PllM, Plln as PllN, Pllp as PllP, Pllq as PllQ, |
| 7 | Pllr as PllR, Ppre as APBPrescaler, | ||
| 7 | }; | 8 | }; |
| 8 | use crate::pac::{PWR, RCC}; | 9 | use crate::pac::{PWR, RCC}; |
| 9 | use crate::rcc::sealed::RccPeripheral; | 10 | use crate::rcc::sealed::RccPeripheral; |
| @@ -16,29 +17,6 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); | |||
| 16 | /// LSI speed | 17 | /// LSI speed |
| 17 | pub const LSI_FREQ: Hertz = Hertz(32_000); | 18 | pub const LSI_FREQ: Hertz = Hertz(32_000); |
| 18 | 19 | ||
| 19 | #[derive(Clone, Copy)] | ||
| 20 | pub enum AdcClockSource { | ||
| 21 | NoClk, | ||
| 22 | SysClk, | ||
| 23 | PllP, | ||
| 24 | } | ||
| 25 | |||
| 26 | impl AdcClockSource { | ||
| 27 | pub fn adcsel(&self) -> Adcsel { | ||
| 28 | match self { | ||
| 29 | AdcClockSource::NoClk => Adcsel::NOCLK, | ||
| 30 | AdcClockSource::SysClk => Adcsel::SYSCLK, | ||
| 31 | AdcClockSource::PllP => Adcsel::PLLP, | ||
| 32 | } | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | impl Default for AdcClockSource { | ||
| 37 | fn default() -> Self { | ||
| 38 | Self::NoClk | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | /// System clock mux source | 20 | /// System clock mux source |
| 43 | #[derive(Clone, Copy)] | 21 | #[derive(Clone, Copy)] |
| 44 | pub enum ClockSrc { | 22 | pub enum ClockSrc { |
| @@ -88,32 +66,6 @@ pub struct Pll { | |||
| 88 | pub div_r: Option<PllR>, | 66 | pub div_r: Option<PllR>, |
| 89 | } | 67 | } |
| 90 | 68 | ||
| 91 | fn ahb_div(ahb: AHBPrescaler) -> u32 { | ||
| 92 | match ahb { | ||
| 93 | AHBPrescaler::DIV1 => 1, | ||
| 94 | AHBPrescaler::DIV2 => 2, | ||
| 95 | AHBPrescaler::DIV4 => 4, | ||
| 96 | AHBPrescaler::DIV8 => 8, | ||
| 97 | AHBPrescaler::DIV16 => 16, | ||
| 98 | AHBPrescaler::DIV64 => 64, | ||
| 99 | AHBPrescaler::DIV128 => 128, | ||
| 100 | AHBPrescaler::DIV256 => 256, | ||
| 101 | AHBPrescaler::DIV512 => 512, | ||
| 102 | _ => unreachable!(), | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | fn apb_div(apb: APBPrescaler) -> u32 { | ||
| 107 | match apb { | ||
| 108 | APBPrescaler::DIV1 => 1, | ||
| 109 | APBPrescaler::DIV2 => 2, | ||
| 110 | APBPrescaler::DIV4 => 4, | ||
| 111 | APBPrescaler::DIV8 => 8, | ||
| 112 | APBPrescaler::DIV16 => 16, | ||
| 113 | _ => unreachable!(), | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | /// Sets the source for the 48MHz clock to the USB and RNG peripherals. | 69 | /// Sets the source for the 48MHz clock to the USB and RNG peripherals. |
| 118 | pub enum Clock48MhzSrc { | 70 | pub enum Clock48MhzSrc { |
| 119 | /// Use the High Speed Internal Oscillator. For USB usage, the CRS must be used to calibrate the | 71 | /// Use the High Speed Internal Oscillator. For USB usage, the CRS must be used to calibrate the |
| @@ -168,8 +120,8 @@ impl Default for Config { | |||
| 168 | low_power_run: false, | 120 | low_power_run: false, |
| 169 | pll: None, | 121 | pll: None, |
| 170 | clock_48mhz_src: None, | 122 | clock_48mhz_src: None, |
| 171 | adc12_clock_source: Default::default(), | 123 | adc12_clock_source: Adcsel::NOCLK, |
| 172 | adc345_clock_source: Default::default(), | 124 | adc345_clock_source: Adcsel::NOCLK, |
| 173 | } | 125 | } |
| 174 | } | 126 | } |
| 175 | } | 127 | } |
| @@ -203,8 +155,8 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 203 | let internal_freq = src_freq / pll_config.prediv_m * pll_config.mul_n; | 155 | let internal_freq = src_freq / pll_config.prediv_m * pll_config.mul_n; |
| 204 | 156 | ||
| 205 | RCC.pllcfgr().write(|w| { | 157 | RCC.pllcfgr().write(|w| { |
| 206 | w.set_plln(pll_config.mul_n.into()); | 158 | w.set_plln(pll_config.mul_n); |
| 207 | w.set_pllm(pll_config.prediv_m.into()); | 159 | w.set_pllm(pll_config.prediv_m); |
| 208 | w.set_pllsrc(pll_config.source.into()); | 160 | w.set_pllsrc(pll_config.source.into()); |
| 209 | }); | 161 | }); |
| 210 | 162 | ||
| @@ -249,14 +201,14 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 249 | RCC.cr().write(|w| w.set_hsion(true)); | 201 | RCC.cr().write(|w| w.set_hsion(true)); |
| 250 | while !RCC.cr().read().hsirdy() {} | 202 | while !RCC.cr().read().hsirdy() {} |
| 251 | 203 | ||
| 252 | (HSI_FREQ.0, Sw::HSI16) | 204 | (HSI_FREQ, Sw::HSI16) |
| 253 | } | 205 | } |
| 254 | ClockSrc::HSE(freq) => { | 206 | ClockSrc::HSE(freq) => { |
| 255 | // Enable HSE | 207 | // Enable HSE |
| 256 | RCC.cr().write(|w| w.set_hseon(true)); | 208 | RCC.cr().write(|w| w.set_hseon(true)); |
| 257 | while !RCC.cr().read().hserdy() {} | 209 | while !RCC.cr().read().hserdy() {} |
| 258 | 210 | ||
| 259 | (freq.0, Sw::HSE) | 211 | (freq, Sw::HSE) |
| 260 | } | 212 | } |
| 261 | ClockSrc::PLL => { | 213 | ClockSrc::PLL => { |
| 262 | assert!(pll_freq.is_some()); | 214 | assert!(pll_freq.is_some()); |
| @@ -297,35 +249,32 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 297 | } | 249 | } |
| 298 | } | 250 | } |
| 299 | 251 | ||
| 300 | (freq, Sw::PLLRCLK) | 252 | (Hertz(freq), Sw::PLLRCLK) |
| 301 | } | 253 | } |
| 302 | }; | 254 | }; |
| 303 | 255 | ||
| 304 | RCC.cfgr().modify(|w| { | 256 | RCC.cfgr().modify(|w| { |
| 305 | w.set_sw(sw); | 257 | w.set_sw(sw); |
| 306 | w.set_hpre(config.ahb_pre.into()); | 258 | w.set_hpre(config.ahb_pre); |
| 307 | w.set_ppre1(config.apb1_pre.into()); | 259 | w.set_ppre1(config.apb1_pre); |
| 308 | w.set_ppre2(config.apb2_pre.into()); | 260 | w.set_ppre2(config.apb2_pre); |
| 309 | }); | 261 | }); |
| 310 | 262 | ||
| 311 | let ahb_freq: u32 = match config.ahb_pre { | 263 | let ahb_freq = sys_clk / config.ahb_pre; |
| 312 | AHBPrescaler::DIV1 => sys_clk, | ||
| 313 | pre => sys_clk / ahb_div(pre), | ||
| 314 | }; | ||
| 315 | 264 | ||
| 316 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { | 265 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { |
| 317 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | 266 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), |
| 318 | pre => { | 267 | pre => { |
| 319 | let freq = ahb_freq / apb_div(pre); | 268 | let freq = ahb_freq / pre; |
| 320 | (freq, freq * 2) | 269 | (freq, freq * 2u32) |
| 321 | } | 270 | } |
| 322 | }; | 271 | }; |
| 323 | 272 | ||
| 324 | let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { | 273 | let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { |
| 325 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | 274 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), |
| 326 | pre => { | 275 | pre => { |
| 327 | let freq = ahb_freq / apb_div(pre); | 276 | let freq = ahb_freq / pre; |
| 328 | (freq, freq * 2) | 277 | (freq, freq * 2u32) |
| 329 | } | 278 | } |
| 330 | }; | 279 | }; |
| 331 | 280 | ||
| @@ -373,42 +322,36 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 373 | RCC.ccipr().modify(|w| w.set_clk48sel(source)); | 322 | RCC.ccipr().modify(|w| w.set_clk48sel(source)); |
| 374 | } | 323 | } |
| 375 | 324 | ||
| 376 | RCC.ccipr() | 325 | RCC.ccipr().modify(|w| w.set_adc12sel(config.adc12_clock_source)); |
| 377 | .modify(|w| w.set_adc12sel(config.adc12_clock_source.adcsel())); | 326 | RCC.ccipr().modify(|w| w.set_adc345sel(config.adc345_clock_source)); |
| 378 | RCC.ccipr() | ||
| 379 | .modify(|w| w.set_adc345sel(config.adc345_clock_source.adcsel())); | ||
| 380 | 327 | ||
| 381 | let adc12_ck = match config.adc12_clock_source { | 328 | let adc12_ck = match config.adc12_clock_source { |
| 382 | AdcClockSource::NoClk => None, | 329 | AdcClockSource::NOCLK => None, |
| 383 | AdcClockSource::PllP => match &pll_freq { | 330 | AdcClockSource::PLLP => pll_freq.as_ref().unwrap().pll_p, |
| 384 | Some(pll) => pll.pll_p, | 331 | AdcClockSource::SYSCLK => Some(sys_clk), |
| 385 | None => None, | 332 | _ => unreachable!(), |
| 386 | }, | ||
| 387 | AdcClockSource::SysClk => Some(Hertz(sys_clk)), | ||
| 388 | }; | 333 | }; |
| 389 | 334 | ||
| 390 | let adc345_ck = match config.adc345_clock_source { | 335 | let adc345_ck = match config.adc345_clock_source { |
| 391 | AdcClockSource::NoClk => None, | 336 | AdcClockSource::NOCLK => None, |
| 392 | AdcClockSource::PllP => match &pll_freq { | 337 | AdcClockSource::PLLP => pll_freq.as_ref().unwrap().pll_p, |
| 393 | Some(pll) => pll.pll_p, | 338 | AdcClockSource::SYSCLK => Some(sys_clk), |
| 394 | None => None, | 339 | _ => unreachable!(), |
| 395 | }, | ||
| 396 | AdcClockSource::SysClk => Some(Hertz(sys_clk)), | ||
| 397 | }; | 340 | }; |
| 398 | 341 | ||
| 399 | if config.low_power_run { | 342 | if config.low_power_run { |
| 400 | assert!(sys_clk <= 2_000_000); | 343 | assert!(sys_clk <= Hertz(2_000_000)); |
| 401 | PWR.cr1().modify(|w| w.set_lpr(true)); | 344 | PWR.cr1().modify(|w| w.set_lpr(true)); |
| 402 | } | 345 | } |
| 403 | 346 | ||
| 404 | set_freqs(Clocks { | 347 | set_freqs(Clocks { |
| 405 | sys: Hertz(sys_clk), | 348 | sys: sys_clk, |
| 406 | ahb1: Hertz(ahb_freq), | 349 | ahb1: ahb_freq, |
| 407 | ahb2: Hertz(ahb_freq), | 350 | ahb2: ahb_freq, |
| 408 | apb1: Hertz(apb1_freq), | 351 | apb1: apb1_freq, |
| 409 | apb1_tim: Hertz(apb1_tim_freq), | 352 | apb1_tim: apb1_tim_freq, |
| 410 | apb2: Hertz(apb2_freq), | 353 | apb2: apb2_freq, |
| 411 | apb2_tim: Hertz(apb2_tim_freq), | 354 | apb2_tim: apb2_tim_freq, |
| 412 | adc: adc12_ck, | 355 | adc: adc12_ck, |
| 413 | adc34: adc345_ck, | 356 | adc34: adc345_ck, |
| 414 | }); | 357 | }); |
diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index a11fd4737..d29064996 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs | |||
| @@ -26,13 +26,13 @@ pub const HSI48_FREQ: Hertz = Hertz(48_000_000); | |||
| 26 | /// LSI speed | 26 | /// LSI speed |
| 27 | pub const LSI_FREQ: Hertz = Hertz(32_000); | 27 | pub const LSI_FREQ: Hertz = Hertz(32_000); |
| 28 | 28 | ||
| 29 | const VCO_RANGE: RangeInclusive<u32> = 150_000_000..=420_000_000; | 29 | const VCO_RANGE: RangeInclusive<Hertz> = Hertz(150_000_000)..=Hertz(420_000_000); |
| 30 | #[cfg(any(stm32h5, pwr_h7rm0455))] | 30 | #[cfg(any(stm32h5, pwr_h7rm0455))] |
| 31 | const VCO_WIDE_RANGE: RangeInclusive<u32> = 128_000_000..=560_000_000; | 31 | const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(128_000_000)..=Hertz(560_000_000); |
| 32 | #[cfg(pwr_h7rm0468)] | 32 | #[cfg(pwr_h7rm0468)] |
| 33 | const VCO_WIDE_RANGE: RangeInclusive<u32> = 192_000_000..=836_000_000; | 33 | const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(192_000_000)..=Hertz(836_000_000); |
| 34 | #[cfg(any(pwr_h7rm0399, pwr_h7rm0433))] | 34 | #[cfg(any(pwr_h7rm0399, pwr_h7rm0433))] |
| 35 | const VCO_WIDE_RANGE: RangeInclusive<u32> = 192_000_000..=960_000_000; | 35 | const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(192_000_000)..=Hertz(960_000_000); |
| 36 | 36 | ||
| 37 | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; | 37 | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; |
| 38 | 38 | ||
| @@ -641,9 +641,9 @@ fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput { | |||
| 641 | let wide_allowed = ref_range != Pllrge::RANGE1; | 641 | let wide_allowed = ref_range != Pllrge::RANGE1; |
| 642 | 642 | ||
| 643 | let vco_clk = ref_clk * config.mul; | 643 | let vco_clk = ref_clk * config.mul; |
| 644 | let vco_range = if VCO_RANGE.contains(&vco_clk.0) { | 644 | let vco_range = if VCO_RANGE.contains(&vco_clk) { |
| 645 | Pllvcosel::MEDIUMVCO | 645 | Pllvcosel::MEDIUMVCO |
| 646 | } else if wide_allowed && VCO_WIDE_RANGE.contains(&vco_clk.0) { | 646 | } else if wide_allowed && VCO_WIDE_RANGE.contains(&vco_clk) { |
| 647 | Pllvcosel::WIDEVCO | 647 | Pllvcosel::WIDEVCO |
| 648 | } else { | 648 | } else { |
| 649 | panic!("pll vco_clk out of range: {} mhz", vco_clk.0) | 649 | panic!("pll vco_clk out of range: {} mhz", vco_clk.0) |
diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0.rs index b42361268..3fd8074d7 100644 --- a/embassy-stm32/src/rcc/l0.rs +++ b/embassy-stm32/src/rcc/l0.rs | |||
| @@ -1,8 +1,10 @@ | |||
| 1 | use super::bd::BackupDomain; | 1 | use super::bd::BackupDomain; |
| 2 | use super::RtcClockSource; | 2 | use super::RtcClockSource; |
| 3 | pub use crate::pac::pwr::vals::Vos as VoltageScale; | 3 | pub use crate::pac::pwr::vals::Vos as VoltageScale; |
| 4 | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; | 4 | pub use crate::pac::rcc::vals::{ |
| 5 | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; | 5 | Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Pllmul as PLLMul, Ppre as APBPrescaler, |
| 6 | }; | ||
| 7 | use crate::pac::rcc::vals::{Pllsrc, Sw}; | ||
| 6 | #[cfg(crs)] | 8 | #[cfg(crs)] |
| 7 | use crate::pac::{crs, CRS, SYSCFG}; | 9 | use crate::pac::{crs, CRS, SYSCFG}; |
| 8 | use crate::pac::{FLASH, PWR, RCC}; | 10 | use crate::pac::{FLASH, PWR, RCC}; |
| @@ -24,56 +26,6 @@ pub enum ClockSrc { | |||
| 24 | HSI16, | 26 | HSI16, |
| 25 | } | 27 | } |
| 26 | 28 | ||
| 27 | /// MSI Clock Range | ||
| 28 | /// | ||
| 29 | /// These ranges control the frequency of the MSI. Internally, these ranges map | ||
| 30 | /// to the `MSIRANGE` bits in the `RCC_ICSCR` register. | ||
| 31 | #[derive(Clone, Copy)] | ||
| 32 | pub enum MSIRange { | ||
| 33 | /// Around 65.536 kHz | ||
| 34 | Range0, | ||
| 35 | /// Around 131.072 kHz | ||
| 36 | Range1, | ||
| 37 | /// Around 262.144 kHz | ||
| 38 | Range2, | ||
| 39 | /// Around 524.288 kHz | ||
| 40 | Range3, | ||
| 41 | /// Around 1.048 MHz | ||
| 42 | Range4, | ||
| 43 | /// Around 2.097 MHz (reset value) | ||
| 44 | Range5, | ||
| 45 | /// Around 4.194 MHz | ||
| 46 | Range6, | ||
| 47 | } | ||
| 48 | |||
| 49 | impl Default for MSIRange { | ||
| 50 | fn default() -> MSIRange { | ||
| 51 | MSIRange::Range5 | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | /// PLL divider | ||
| 56 | #[derive(Clone, Copy)] | ||
| 57 | pub enum PLLDiv { | ||
| 58 | Div2, | ||
| 59 | Div3, | ||
| 60 | Div4, | ||
| 61 | } | ||
| 62 | |||
| 63 | /// PLL multiplier | ||
| 64 | #[derive(Clone, Copy)] | ||
| 65 | pub enum PLLMul { | ||
| 66 | Mul3, | ||
| 67 | Mul4, | ||
| 68 | Mul6, | ||
| 69 | Mul8, | ||
| 70 | Mul12, | ||
| 71 | Mul16, | ||
| 72 | Mul24, | ||
| 73 | Mul32, | ||
| 74 | Mul48, | ||
| 75 | } | ||
| 76 | |||
| 77 | /// PLL clock input source | 29 | /// PLL clock input source |
| 78 | #[derive(Clone, Copy)] | 30 | #[derive(Clone, Copy)] |
| 79 | pub enum PLLSource { | 31 | pub enum PLLSource { |
| @@ -81,32 +33,6 @@ pub enum PLLSource { | |||
| 81 | HSE(Hertz), | 33 | HSE(Hertz), |
| 82 | } | 34 | } |
| 83 | 35 | ||
| 84 | impl From<PLLMul> for Pllmul { | ||
| 85 | fn from(val: PLLMul) -> Pllmul { | ||
| 86 | match val { | ||
| 87 | PLLMul::Mul3 => Pllmul::MUL3, | ||
| 88 | PLLMul::Mul4 => Pllmul::MUL4, | ||
| 89 | PLLMul::Mul6 => Pllmul::MUL6, | ||
| 90 | PLLMul::Mul8 => Pllmul::MUL8, | ||
| 91 | PLLMul::Mul12 => Pllmul::MUL12, | ||
| 92 | PLLMul::Mul16 => Pllmul::MUL16, | ||
| 93 | PLLMul::Mul24 => Pllmul::MUL24, | ||
| 94 | PLLMul::Mul32 => Pllmul::MUL32, | ||
| 95 | PLLMul::Mul48 => Pllmul::MUL48, | ||
| 96 | } | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | impl From<PLLDiv> for Plldiv { | ||
| 101 | fn from(val: PLLDiv) -> Plldiv { | ||
| 102 | match val { | ||
| 103 | PLLDiv::Div2 => Plldiv::DIV2, | ||
| 104 | PLLDiv::Div3 => Plldiv::DIV3, | ||
| 105 | PLLDiv::Div4 => Plldiv::DIV4, | ||
| 106 | } | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | impl From<PLLSource> for Pllsrc { | 36 | impl From<PLLSource> for Pllsrc { |
| 111 | fn from(val: PLLSource) -> Pllsrc { | 37 | fn from(val: PLLSource) -> Pllsrc { |
| 112 | match val { | 38 | match val { |
| @@ -116,20 +42,6 @@ impl From<PLLSource> for Pllsrc { | |||
| 116 | } | 42 | } |
| 117 | } | 43 | } |
| 118 | 44 | ||
| 119 | impl From<MSIRange> for Msirange { | ||
| 120 | fn from(val: MSIRange) -> Msirange { | ||
| 121 | match val { | ||
| 122 | MSIRange::Range0 => Msirange::RANGE0, | ||
| 123 | MSIRange::Range1 => Msirange::RANGE1, | ||
| 124 | MSIRange::Range2 => Msirange::RANGE2, | ||
| 125 | MSIRange::Range3 => Msirange::RANGE3, | ||
| 126 | MSIRange::Range4 => Msirange::RANGE4, | ||
| 127 | MSIRange::Range5 => Msirange::RANGE5, | ||
| 128 | MSIRange::Range6 => Msirange::RANGE6, | ||
| 129 | } | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | /// Clocks configutation | 45 | /// Clocks configutation |
| 134 | pub struct Config { | 46 | pub struct Config { |
| 135 | pub mux: ClockSrc, | 47 | pub mux: ClockSrc, |
| @@ -148,7 +60,7 @@ impl Default for Config { | |||
| 148 | #[inline] | 60 | #[inline] |
| 149 | fn default() -> Config { | 61 | fn default() -> Config { |
| 150 | Config { | 62 | Config { |
| 151 | mux: ClockSrc::MSI(MSIRange::default()), | 63 | mux: ClockSrc::MSI(MSIRange::RANGE5), |
| 152 | ahb_pre: AHBPrescaler::DIV1, | 64 | ahb_pre: AHBPrescaler::DIV1, |
| 153 | apb1_pre: APBPrescaler::DIV1, | 65 | apb1_pre: APBPrescaler::DIV1, |
| 154 | apb2_pre: APBPrescaler::DIV1, | 66 | apb2_pre: APBPrescaler::DIV1, |
| @@ -171,28 +83,28 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 171 | let (sys_clk, sw) = match config.mux { | 83 | let (sys_clk, sw) = match config.mux { |
| 172 | ClockSrc::MSI(range) => { | 84 | ClockSrc::MSI(range) => { |
| 173 | // Set MSI range | 85 | // Set MSI range |
| 174 | RCC.icscr().write(|w| w.set_msirange(range.into())); | 86 | RCC.icscr().write(|w| w.set_msirange(range)); |
| 175 | 87 | ||
| 176 | // Enable MSI | 88 | // Enable MSI |
| 177 | RCC.cr().write(|w| w.set_msion(true)); | 89 | RCC.cr().write(|w| w.set_msion(true)); |
| 178 | while !RCC.cr().read().msirdy() {} | 90 | while !RCC.cr().read().msirdy() {} |
| 179 | 91 | ||
| 180 | let freq = 32_768 * (1 << (range as u8 + 1)); | 92 | let freq = 32_768 * (1 << (range as u8 + 1)); |
| 181 | (freq, Sw::MSI) | 93 | (Hertz(freq), Sw::MSI) |
| 182 | } | 94 | } |
| 183 | ClockSrc::HSI16 => { | 95 | ClockSrc::HSI16 => { |
| 184 | // Enable HSI16 | 96 | // Enable HSI16 |
| 185 | RCC.cr().write(|w| w.set_hsi16on(true)); | 97 | RCC.cr().write(|w| w.set_hsi16on(true)); |
| 186 | while !RCC.cr().read().hsi16rdyf() {} | 98 | while !RCC.cr().read().hsi16rdyf() {} |
| 187 | 99 | ||
| 188 | (HSI_FREQ.0, Sw::HSI16) | 100 | (HSI_FREQ, Sw::HSI16) |
| 189 | } | 101 | } |
| 190 | ClockSrc::HSE(freq) => { | 102 | ClockSrc::HSE(freq) => { |
| 191 | // Enable HSE | 103 | // Enable HSE |
| 192 | RCC.cr().write(|w| w.set_hseon(true)); | 104 | RCC.cr().write(|w| w.set_hseon(true)); |
| 193 | while !RCC.cr().read().hserdy() {} | 105 | while !RCC.cr().read().hserdy() {} |
| 194 | 106 | ||
| 195 | (freq.0, Sw::HSE) | 107 | (freq, Sw::HSE) |
| 196 | } | 108 | } |
| 197 | ClockSrc::PLL(src, mul, div) => { | 109 | ClockSrc::PLL(src, mul, div) => { |
| 198 | let freq = match src { | 110 | let freq = match src { |
| @@ -200,13 +112,13 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 200 | // Enable HSE | 112 | // Enable HSE |
| 201 | RCC.cr().write(|w| w.set_hseon(true)); | 113 | RCC.cr().write(|w| w.set_hseon(true)); |
| 202 | while !RCC.cr().read().hserdy() {} | 114 | while !RCC.cr().read().hserdy() {} |
| 203 | freq.0 | 115 | freq |
| 204 | } | 116 | } |
| 205 | PLLSource::HSI16 => { | 117 | PLLSource::HSI16 => { |
| 206 | // Enable HSI | 118 | // Enable HSI |
| 207 | RCC.cr().write(|w| w.set_hsi16on(true)); | 119 | RCC.cr().write(|w| w.set_hsi16on(true)); |
| 208 | while !RCC.cr().read().hsi16rdyf() {} | 120 | while !RCC.cr().read().hsi16rdyf() {} |
| 209 | HSI_FREQ.0 | 121 | HSI_FREQ |
| 210 | } | 122 | } |
| 211 | }; | 123 | }; |
| 212 | 124 | ||
| @@ -214,28 +126,13 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 214 | RCC.cr().modify(|w| w.set_pllon(false)); | 126 | RCC.cr().modify(|w| w.set_pllon(false)); |
| 215 | while RCC.cr().read().pllrdy() {} | 127 | while RCC.cr().read().pllrdy() {} |
| 216 | 128 | ||
| 217 | let freq = match mul { | 129 | let freq = freq * mul / div; |
| 218 | PLLMul::Mul3 => freq * 3, | ||
| 219 | PLLMul::Mul4 => freq * 4, | ||
| 220 | PLLMul::Mul6 => freq * 6, | ||
| 221 | PLLMul::Mul8 => freq * 8, | ||
| 222 | PLLMul::Mul12 => freq * 12, | ||
| 223 | PLLMul::Mul16 => freq * 16, | ||
| 224 | PLLMul::Mul24 => freq * 24, | ||
| 225 | PLLMul::Mul32 => freq * 32, | ||
| 226 | PLLMul::Mul48 => freq * 48, | ||
| 227 | }; | ||
| 228 | 130 | ||
| 229 | let freq = match div { | 131 | assert!(freq <= Hertz(32_000_000)); |
| 230 | PLLDiv::Div2 => freq / 2, | ||
| 231 | PLLDiv::Div3 => freq / 3, | ||
| 232 | PLLDiv::Div4 => freq / 4, | ||
| 233 | }; | ||
| 234 | assert!(freq <= 32_000_000); | ||
| 235 | 132 | ||
| 236 | RCC.cfgr().write(move |w| { | 133 | RCC.cfgr().write(move |w| { |
| 237 | w.set_pllmul(mul.into()); | 134 | w.set_pllmul(mul); |
| 238 | w.set_plldiv(div.into()); | 135 | w.set_plldiv(div); |
| 239 | w.set_pllsrc(src.into()); | 136 | w.set_pllsrc(src.into()); |
| 240 | }); | 137 | }); |
| 241 | 138 | ||
| @@ -254,11 +151,11 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 254 | ); | 151 | ); |
| 255 | 152 | ||
| 256 | let wait_states = match config.voltage_scale { | 153 | let wait_states = match config.voltage_scale { |
| 257 | VoltageScale::RANGE1 => match sys_clk { | 154 | VoltageScale::RANGE1 => match sys_clk.0 { |
| 258 | ..=16_000_000 => 0, | 155 | ..=16_000_000 => 0, |
| 259 | _ => 1, | 156 | _ => 1, |
| 260 | }, | 157 | }, |
| 261 | VoltageScale::RANGE2 => match sys_clk { | 158 | VoltageScale::RANGE2 => match sys_clk.0 { |
| 262 | ..=8_000_000 => 0, | 159 | ..=8_000_000 => 0, |
| 263 | _ => 1, | 160 | _ => 1, |
| 264 | }, | 161 | }, |
| @@ -271,37 +168,26 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 271 | 168 | ||
| 272 | RCC.cfgr().modify(|w| { | 169 | RCC.cfgr().modify(|w| { |
| 273 | w.set_sw(sw); | 170 | w.set_sw(sw); |
| 274 | w.set_hpre(config.ahb_pre.into()); | 171 | w.set_hpre(config.ahb_pre); |
| 275 | w.set_ppre1(config.apb1_pre.into()); | 172 | w.set_ppre1(config.apb1_pre); |
| 276 | w.set_ppre2(config.apb2_pre.into()); | 173 | w.set_ppre2(config.apb2_pre); |
| 277 | }); | 174 | }); |
| 278 | 175 | ||
| 279 | let ahb_freq: u32 = match config.ahb_pre { | 176 | let ahb_freq = sys_clk / config.ahb_pre; |
| 280 | AHBPrescaler::DIV1 => sys_clk, | ||
| 281 | pre => { | ||
| 282 | let pre: Hpre = pre.into(); | ||
| 283 | let pre = 1 << (pre.to_bits() as u32 - 7); | ||
| 284 | sys_clk / pre | ||
| 285 | } | ||
| 286 | }; | ||
| 287 | 177 | ||
| 288 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { | 178 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { |
| 289 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | 179 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), |
| 290 | pre => { | 180 | pre => { |
| 291 | let pre: Ppre = pre.into(); | 181 | let freq = ahb_freq / pre; |
| 292 | let pre: u8 = 1 << (pre.to_bits() - 3); | 182 | (freq, freq * 2u32) |
| 293 | let freq = ahb_freq / pre as u32; | ||
| 294 | (freq, freq * 2) | ||
| 295 | } | 183 | } |
| 296 | }; | 184 | }; |
| 297 | 185 | ||
| 298 | let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { | 186 | let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { |
| 299 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | 187 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), |
| 300 | pre => { | 188 | pre => { |
| 301 | let pre: Ppre = pre.into(); | 189 | let freq = ahb_freq / pre; |
| 302 | let pre: u8 = 1 << (pre.to_bits() - 3); | 190 | (freq, freq * 2u32) |
| 303 | let freq = ahb_freq / pre as u32; | ||
| 304 | (freq, freq * 2) | ||
| 305 | } | 191 | } |
| 306 | }; | 192 | }; |
| 307 | 193 | ||
| @@ -339,11 +225,11 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 339 | } | 225 | } |
| 340 | 226 | ||
| 341 | set_freqs(Clocks { | 227 | set_freqs(Clocks { |
| 342 | sys: Hertz(sys_clk), | 228 | sys: sys_clk, |
| 343 | ahb1: Hertz(ahb_freq), | 229 | ahb1: ahb_freq, |
| 344 | apb1: Hertz(apb1_freq), | 230 | apb1: apb1_freq, |
| 345 | apb2: Hertz(apb2_freq), | 231 | apb2: apb2_freq, |
| 346 | apb1_tim: Hertz(apb1_tim_freq), | 232 | apb1_tim: apb1_tim_freq, |
| 347 | apb2_tim: Hertz(apb2_tim_freq), | 233 | apb2_tim: apb2_tim_freq, |
| 348 | }); | 234 | }); |
| 349 | } | 235 | } |
diff --git a/embassy-stm32/src/rcc/l1.rs b/embassy-stm32/src/rcc/l1.rs index e445a716e..7c75b888d 100644 --- a/embassy-stm32/src/rcc/l1.rs +++ b/embassy-stm32/src/rcc/l1.rs | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; | 1 | pub use crate::pac::rcc::vals::{ |
| 2 | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; | 2 | Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Pllmul as PLLMul, Ppre as APBPrescaler, |
| 3 | }; | ||
| 4 | use crate::pac::rcc::vals::{Pllsrc, Sw}; | ||
| 3 | use crate::pac::{FLASH, RCC}; | 5 | use crate::pac::{FLASH, RCC}; |
| 4 | use crate::rcc::{set_freqs, Clocks}; | 6 | use crate::rcc::{set_freqs, Clocks}; |
| 5 | use crate::time::Hertz; | 7 | use crate::time::Hertz; |
| @@ -19,56 +21,6 @@ pub enum ClockSrc { | |||
| 19 | HSI, | 21 | HSI, |
| 20 | } | 22 | } |
| 21 | 23 | ||
| 22 | /// MSI Clock Range | ||
| 23 | /// | ||
| 24 | /// These ranges control the frequency of the MSI. Internally, these ranges map | ||
| 25 | /// to the `MSIRANGE` bits in the `RCC_ICSCR` register. | ||
| 26 | #[derive(Clone, Copy)] | ||
| 27 | pub enum MSIRange { | ||
| 28 | /// Around 65.536 kHz | ||
| 29 | Range0, | ||
| 30 | /// Around 131.072 kHz | ||
| 31 | Range1, | ||
| 32 | /// Around 262.144 kHz | ||
| 33 | Range2, | ||
| 34 | /// Around 524.288 kHz | ||
| 35 | Range3, | ||
| 36 | /// Around 1.048 MHz | ||
| 37 | Range4, | ||
| 38 | /// Around 2.097 MHz (reset value) | ||
| 39 | Range5, | ||
| 40 | /// Around 4.194 MHz | ||
| 41 | Range6, | ||
| 42 | } | ||
| 43 | |||
| 44 | impl Default for MSIRange { | ||
| 45 | fn default() -> MSIRange { | ||
| 46 | MSIRange::Range5 | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | /// PLL divider | ||
| 51 | #[derive(Clone, Copy)] | ||
| 52 | pub enum PLLDiv { | ||
| 53 | Div2, | ||
| 54 | Div3, | ||
| 55 | Div4, | ||
| 56 | } | ||
| 57 | |||
| 58 | /// PLL multiplier | ||
| 59 | #[derive(Clone, Copy)] | ||
| 60 | pub enum PLLMul { | ||
| 61 | Mul3, | ||
| 62 | Mul4, | ||
| 63 | Mul6, | ||
| 64 | Mul8, | ||
| 65 | Mul12, | ||
| 66 | Mul16, | ||
| 67 | Mul24, | ||
| 68 | Mul32, | ||
| 69 | Mul48, | ||
| 70 | } | ||
| 71 | |||
| 72 | /// PLL clock input source | 24 | /// PLL clock input source |
| 73 | #[derive(Clone, Copy)] | 25 | #[derive(Clone, Copy)] |
| 74 | pub enum PLLSource { | 26 | pub enum PLLSource { |
| @@ -76,32 +28,6 @@ pub enum PLLSource { | |||
| 76 | HSE(Hertz), | 28 | HSE(Hertz), |
| 77 | } | 29 | } |
| 78 | 30 | ||
| 79 | impl From<PLLMul> for Pllmul { | ||
| 80 | fn from(val: PLLMul) -> Pllmul { | ||
| 81 | match val { | ||
| 82 | PLLMul::Mul3 => Pllmul::MUL3, | ||
| 83 | PLLMul::Mul4 => Pllmul::MUL4, | ||
| 84 | PLLMul::Mul6 => Pllmul::MUL6, | ||
| 85 | PLLMul::Mul8 => Pllmul::MUL8, | ||
| 86 | PLLMul::Mul12 => Pllmul::MUL12, | ||
| 87 | PLLMul::Mul16 => Pllmul::MUL16, | ||
| 88 | PLLMul::Mul24 => Pllmul::MUL24, | ||
| 89 | PLLMul::Mul32 => Pllmul::MUL32, | ||
| 90 | PLLMul::Mul48 => Pllmul::MUL48, | ||
| 91 | } | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | impl From<PLLDiv> for Plldiv { | ||
| 96 | fn from(val: PLLDiv) -> Plldiv { | ||
| 97 | match val { | ||
| 98 | PLLDiv::Div2 => Plldiv::DIV2, | ||
| 99 | PLLDiv::Div3 => Plldiv::DIV3, | ||
| 100 | PLLDiv::Div4 => Plldiv::DIV4, | ||
| 101 | } | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | impl From<PLLSource> for Pllsrc { | 31 | impl From<PLLSource> for Pllsrc { |
| 106 | fn from(val: PLLSource) -> Pllsrc { | 32 | fn from(val: PLLSource) -> Pllsrc { |
| 107 | match val { | 33 | match val { |
| @@ -111,20 +37,6 @@ impl From<PLLSource> for Pllsrc { | |||
| 111 | } | 37 | } |
| 112 | } | 38 | } |
| 113 | 39 | ||
| 114 | impl From<MSIRange> for Msirange { | ||
| 115 | fn from(val: MSIRange) -> Msirange { | ||
| 116 | match val { | ||
| 117 | MSIRange::Range0 => Msirange::RANGE0, | ||
| 118 | MSIRange::Range1 => Msirange::RANGE1, | ||
| 119 | MSIRange::Range2 => Msirange::RANGE2, | ||
| 120 | MSIRange::Range3 => Msirange::RANGE3, | ||
| 121 | MSIRange::Range4 => Msirange::RANGE4, | ||
| 122 | MSIRange::Range5 => Msirange::RANGE5, | ||
| 123 | MSIRange::Range6 => Msirange::RANGE6, | ||
| 124 | } | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | /// Clocks configutation | 40 | /// Clocks configutation |
| 129 | pub struct Config { | 41 | pub struct Config { |
| 130 | pub mux: ClockSrc, | 42 | pub mux: ClockSrc, |
| @@ -137,7 +49,7 @@ impl Default for Config { | |||
| 137 | #[inline] | 49 | #[inline] |
| 138 | fn default() -> Config { | 50 | fn default() -> Config { |
| 139 | Config { | 51 | Config { |
| 140 | mux: ClockSrc::MSI(MSIRange::default()), | 52 | mux: ClockSrc::MSI(MSIRange::RANGE5), |
| 141 | ahb_pre: AHBPrescaler::DIV1, | 53 | ahb_pre: AHBPrescaler::DIV1, |
| 142 | apb1_pre: APBPrescaler::DIV1, | 54 | apb1_pre: APBPrescaler::DIV1, |
| 143 | apb2_pre: APBPrescaler::DIV1, | 55 | apb2_pre: APBPrescaler::DIV1, |
| @@ -149,28 +61,28 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 149 | let (sys_clk, sw) = match config.mux { | 61 | let (sys_clk, sw) = match config.mux { |
| 150 | ClockSrc::MSI(range) => { | 62 | ClockSrc::MSI(range) => { |
| 151 | // Set MSI range | 63 | // Set MSI range |
| 152 | RCC.icscr().write(|w| w.set_msirange(range.into())); | 64 | RCC.icscr().write(|w| w.set_msirange(range)); |
| 153 | 65 | ||
| 154 | // Enable MSI | 66 | // Enable MSI |
| 155 | RCC.cr().write(|w| w.set_msion(true)); | 67 | RCC.cr().write(|w| w.set_msion(true)); |
| 156 | while !RCC.cr().read().msirdy() {} | 68 | while !RCC.cr().read().msirdy() {} |
| 157 | 69 | ||
| 158 | let freq = 32_768 * (1 << (range as u8 + 1)); | 70 | let freq = 32_768 * (1 << (range as u8 + 1)); |
| 159 | (freq, Sw::MSI) | 71 | (Hertz(freq), Sw::MSI) |
| 160 | } | 72 | } |
| 161 | ClockSrc::HSI => { | 73 | ClockSrc::HSI => { |
| 162 | // Enable HSI | 74 | // Enable HSI |
| 163 | RCC.cr().write(|w| w.set_hsion(true)); | 75 | RCC.cr().write(|w| w.set_hsion(true)); |
| 164 | while !RCC.cr().read().hsirdy() {} | 76 | while !RCC.cr().read().hsirdy() {} |
| 165 | 77 | ||
| 166 | (HSI_FREQ.0, Sw::HSI) | 78 | (HSI_FREQ, Sw::HSI) |
| 167 | } | 79 | } |
| 168 | ClockSrc::HSE(freq) => { | 80 | ClockSrc::HSE(freq) => { |
| 169 | // Enable HSE | 81 | // Enable HSE |
| 170 | RCC.cr().write(|w| w.set_hseon(true)); | 82 | RCC.cr().write(|w| w.set_hseon(true)); |
| 171 | while !RCC.cr().read().hserdy() {} | 83 | while !RCC.cr().read().hserdy() {} |
| 172 | 84 | ||
| 173 | (freq.0, Sw::HSE) | 85 | (freq, Sw::HSE) |
| 174 | } | 86 | } |
| 175 | ClockSrc::PLL(src, mul, div) => { | 87 | ClockSrc::PLL(src, mul, div) => { |
| 176 | let freq = match src { | 88 | let freq = match src { |
| @@ -178,13 +90,13 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 178 | // Enable HSE | 90 | // Enable HSE |
| 179 | RCC.cr().write(|w| w.set_hseon(true)); | 91 | RCC.cr().write(|w| w.set_hseon(true)); |
| 180 | while !RCC.cr().read().hserdy() {} | 92 | while !RCC.cr().read().hserdy() {} |
| 181 | freq.0 | 93 | freq |
| 182 | } | 94 | } |
| 183 | PLLSource::HSI => { | 95 | PLLSource::HSI => { |
| 184 | // Enable HSI | 96 | // Enable HSI |
| 185 | RCC.cr().write(|w| w.set_hsion(true)); | 97 | RCC.cr().write(|w| w.set_hsion(true)); |
| 186 | while !RCC.cr().read().hsirdy() {} | 98 | while !RCC.cr().read().hsirdy() {} |
| 187 | HSI_FREQ.0 | 99 | HSI_FREQ |
| 188 | } | 100 | } |
| 189 | }; | 101 | }; |
| 190 | 102 | ||
| @@ -192,28 +104,13 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 192 | RCC.cr().modify(|w| w.set_pllon(false)); | 104 | RCC.cr().modify(|w| w.set_pllon(false)); |
| 193 | while RCC.cr().read().pllrdy() {} | 105 | while RCC.cr().read().pllrdy() {} |
| 194 | 106 | ||
| 195 | let freq = match mul { | 107 | let freq = freq * mul / div; |
| 196 | PLLMul::Mul3 => freq * 3, | ||
| 197 | PLLMul::Mul4 => freq * 4, | ||
| 198 | PLLMul::Mul6 => freq * 6, | ||
| 199 | PLLMul::Mul8 => freq * 8, | ||
| 200 | PLLMul::Mul12 => freq * 12, | ||
| 201 | PLLMul::Mul16 => freq * 16, | ||
| 202 | PLLMul::Mul24 => freq * 24, | ||
| 203 | PLLMul::Mul32 => freq * 32, | ||
| 204 | PLLMul::Mul48 => freq * 48, | ||
| 205 | }; | ||
| 206 | 108 | ||
| 207 | let freq = match div { | 109 | assert!(freq <= Hertz(32_000_000)); |
| 208 | PLLDiv::Div2 => freq / 2, | ||
| 209 | PLLDiv::Div3 => freq / 3, | ||
| 210 | PLLDiv::Div4 => freq / 4, | ||
| 211 | }; | ||
| 212 | assert!(freq <= 32_000_000); | ||
| 213 | 110 | ||
| 214 | RCC.cfgr().write(move |w| { | 111 | RCC.cfgr().write(move |w| { |
| 215 | w.set_pllmul(mul.into()); | 112 | w.set_pllmul(mul); |
| 216 | w.set_plldiv(div.into()); | 113 | w.set_plldiv(div); |
| 217 | w.set_pllsrc(src.into()); | 114 | w.set_pllsrc(src.into()); |
| 218 | }); | 115 | }); |
| 219 | 116 | ||
| @@ -226,7 +123,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 226 | }; | 123 | }; |
| 227 | 124 | ||
| 228 | // Set flash 64-bit access, prefetch and wait states | 125 | // Set flash 64-bit access, prefetch and wait states |
| 229 | if sys_clk >= 16_000_000 { | 126 | if sys_clk >= Hertz(16_000_000) { |
| 230 | FLASH.acr().write(|w| w.set_acc64(true)); | 127 | FLASH.acr().write(|w| w.set_acc64(true)); |
| 231 | FLASH.acr().modify(|w| w.set_prften(true)); | 128 | FLASH.acr().modify(|w| w.set_prften(true)); |
| 232 | FLASH.acr().modify(|w| w.set_latency(true)); | 129 | FLASH.acr().modify(|w| w.set_latency(true)); |
| @@ -234,46 +131,68 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 234 | 131 | ||
| 235 | RCC.cfgr().modify(|w| { | 132 | RCC.cfgr().modify(|w| { |
| 236 | w.set_sw(sw); | 133 | w.set_sw(sw); |
| 237 | w.set_hpre(config.ahb_pre.into()); | 134 | w.set_hpre(config.ahb_pre); |
| 238 | w.set_ppre1(config.apb1_pre.into()); | 135 | w.set_ppre1(config.apb1_pre); |
| 239 | w.set_ppre2(config.apb2_pre.into()); | 136 | w.set_ppre2(config.apb2_pre); |
| 240 | }); | 137 | }); |
| 241 | 138 | ||
| 242 | let ahb_freq: u32 = match config.ahb_pre { | 139 | let ahb_freq = sys_clk / config.ahb_pre; |
| 243 | AHBPrescaler::DIV1 => sys_clk, | ||
| 244 | pre => { | ||
| 245 | let pre: Hpre = pre.into(); | ||
| 246 | let pre = 1 << (pre.to_bits() as u32 - 7); | ||
| 247 | sys_clk / pre | ||
| 248 | } | ||
| 249 | }; | ||
| 250 | 140 | ||
| 251 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { | 141 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { |
| 252 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | 142 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), |
| 253 | pre => { | 143 | pre => { |
| 254 | let pre: Ppre = pre.into(); | 144 | let freq = ahb_freq / pre; |
| 255 | let pre: u8 = 1 << (pre.to_bits() - 3); | 145 | (freq, freq * 2u32) |
| 256 | let freq = ahb_freq / pre as u32; | ||
| 257 | (freq, freq * 2) | ||
| 258 | } | 146 | } |
| 259 | }; | 147 | }; |
| 260 | 148 | ||
| 261 | let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { | 149 | let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { |
| 262 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | 150 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), |
| 263 | pre => { | 151 | pre => { |
| 264 | let pre: Ppre = pre.into(); | 152 | let freq = ahb_freq / pre; |
| 265 | let pre: u8 = 1 << (pre.to_bits() - 3); | 153 | (freq, freq * 2u32) |
| 266 | let freq = ahb_freq / pre as u32; | ||
| 267 | (freq, freq * 2) | ||
| 268 | } | 154 | } |
| 269 | }; | 155 | }; |
| 270 | 156 | ||
| 157 | #[cfg(crs)] | ||
| 158 | if config.enable_hsi48 { | ||
| 159 | // Reset CRS peripheral | ||
| 160 | RCC.apb1rstr().modify(|w| w.set_crsrst(true)); | ||
| 161 | RCC.apb1rstr().modify(|w| w.set_crsrst(false)); | ||
| 162 | |||
| 163 | // Enable CRS peripheral | ||
| 164 | RCC.apb1enr().modify(|w| w.set_crsen(true)); | ||
| 165 | |||
| 166 | // Initialize CRS | ||
| 167 | CRS.cfgr().write(|w| | ||
| 168 | |||
| 169 | // Select LSE as synchronization source | ||
| 170 | w.set_syncsrc(crs::vals::Syncsrc::LSE)); | ||
| 171 | CRS.cr().modify(|w| { | ||
| 172 | w.set_autotrimen(true); | ||
| 173 | w.set_cen(true); | ||
| 174 | }); | ||
| 175 | |||
| 176 | // Enable VREFINT reference for HSI48 oscillator | ||
| 177 | SYSCFG.cfgr3().modify(|w| { | ||
| 178 | w.set_enref_hsi48(true); | ||
| 179 | w.set_en_vrefint(true); | ||
| 180 | }); | ||
| 181 | |||
| 182 | // Select HSI48 as USB clock | ||
| 183 | RCC.ccipr().modify(|w| w.set_hsi48msel(true)); | ||
| 184 | |||
| 185 | // Enable dedicated USB clock | ||
| 186 | RCC.crrcr().modify(|w| w.set_hsi48on(true)); | ||
| 187 | while !RCC.crrcr().read().hsi48rdy() {} | ||
| 188 | } | ||
| 189 | |||
| 271 | set_freqs(Clocks { | 190 | set_freqs(Clocks { |
| 272 | sys: Hertz(sys_clk), | 191 | sys: sys_clk, |
| 273 | ahb1: Hertz(ahb_freq), | 192 | ahb1: ahb_freq, |
| 274 | apb1: Hertz(apb1_freq), | 193 | apb1: apb1_freq, |
| 275 | apb2: Hertz(apb2_freq), | 194 | apb2: apb2_freq, |
| 276 | apb1_tim: Hertz(apb1_tim_freq), | 195 | apb1_tim: apb1_tim_freq, |
| 277 | apb2_tim: Hertz(apb2_tim_freq), | 196 | apb2_tim: apb2_tim_freq, |
| 278 | }); | 197 | }); |
| 279 | } | 198 | } |
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 0e35b42e8..686bbd4ee 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs | |||
| @@ -101,8 +101,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 101 | ClockSrc::MSI(range) => { | 101 | ClockSrc::MSI(range) => { |
| 102 | // Enable MSI | 102 | // Enable MSI |
| 103 | RCC.cr().write(|w| { | 103 | RCC.cr().write(|w| { |
| 104 | let bits: Msirange = range.into(); | 104 | w.set_msirange(range); |
| 105 | w.set_msirange(bits); | ||
| 106 | w.set_msirgsel(true); | 105 | w.set_msirgsel(true); |
| 107 | w.set_msion(true); | 106 | w.set_msion(true); |
| 108 | 107 | ||
| @@ -154,8 +153,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 154 | PLLSource::MSI(range) => { | 153 | PLLSource::MSI(range) => { |
| 155 | // Enable MSI | 154 | // Enable MSI |
| 156 | RCC.cr().write(|w| { | 155 | RCC.cr().write(|w| { |
| 157 | let bits: Msirange = range.into(); | 156 | w.set_msirange(range); |
| 158 | w.set_msirange(bits); | ||
| 159 | w.set_msipllen(false); // should be turned on if LSE is started | 157 | w.set_msipllen(false); // should be turned on if LSE is started |
| 160 | w.set_msirgsel(true); | 158 | w.set_msirgsel(true); |
| 161 | w.set_msion(true); | 159 | w.set_msion(true); |
| @@ -255,9 +253,9 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 255 | 253 | ||
| 256 | RCC.cfgr().modify(|w| { | 254 | RCC.cfgr().modify(|w| { |
| 257 | w.set_sw(sw); | 255 | w.set_sw(sw); |
| 258 | w.set_hpre(config.ahb_pre.into()); | 256 | w.set_hpre(config.ahb_pre); |
| 259 | w.set_ppre1(config.apb1_pre.into()); | 257 | w.set_ppre1(config.apb1_pre); |
| 260 | w.set_ppre2(config.apb2_pre.into()); | 258 | w.set_ppre2(config.apb2_pre); |
| 261 | }); | 259 | }); |
| 262 | 260 | ||
| 263 | let ahb_freq = sys_clk / config.ahb_pre; | 261 | let ahb_freq = sys_clk / config.ahb_pre; |
diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs index d9b3ee282..ac4804d4f 100644 --- a/embassy-stm32/src/rcc/l5.rs +++ b/embassy-stm32/src/rcc/l5.rs | |||
| @@ -100,8 +100,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 100 | ClockSrc::MSI(range) => { | 100 | ClockSrc::MSI(range) => { |
| 101 | // Enable MSI | 101 | // Enable MSI |
| 102 | RCC.cr().write(|w| { | 102 | RCC.cr().write(|w| { |
| 103 | let bits: Msirange = range.into(); | 103 | w.set_msirange(range); |
| 104 | w.set_msirange(bits); | ||
| 105 | w.set_msirgsel(true); | 104 | w.set_msirgsel(true); |
| 106 | w.set_msion(true); | 105 | w.set_msion(true); |
| 107 | 106 | ||
| @@ -153,8 +152,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 153 | PLLSource::MSI(range) => { | 152 | PLLSource::MSI(range) => { |
| 154 | // Enable MSI | 153 | // Enable MSI |
| 155 | RCC.cr().write(|w| { | 154 | RCC.cr().write(|w| { |
| 156 | let bits: Msirange = range.into(); | 155 | w.set_msirange(range); |
| 157 | w.set_msirange(bits); | ||
| 158 | w.set_msipllen(false); // should be turned on if LSE is started | 156 | w.set_msipllen(false); // should be turned on if LSE is started |
| 159 | w.set_msirgsel(true); | 157 | w.set_msirgsel(true); |
| 160 | w.set_msion(true); | 158 | w.set_msion(true); |
| @@ -250,9 +248,9 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 250 | 248 | ||
| 251 | RCC.cfgr().modify(|w| { | 249 | RCC.cfgr().modify(|w| { |
| 252 | w.set_sw(sw); | 250 | w.set_sw(sw); |
| 253 | w.set_hpre(config.ahb_pre.into()); | 251 | w.set_hpre(config.ahb_pre); |
| 254 | w.set_ppre1(config.apb1_pre.into()); | 252 | w.set_ppre1(config.apb1_pre); |
| 255 | w.set_ppre2(config.apb2_pre.into()); | 253 | w.set_ppre2(config.apb2_pre); |
| 256 | }); | 254 | }); |
| 257 | 255 | ||
| 258 | let ahb_freq = sys_clk / config.ahb_pre; | 256 | let ahb_freq = sys_clk / config.ahb_pre; |
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index ee2a8ae10..f8eeaa953 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs | |||
| @@ -1,107 +1,42 @@ | |||
| 1 | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; | 1 | pub use crate::pac::rcc::vals::{ |
| 2 | Hpre as AHBPrescaler, Hsepre as HsePrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Pllsrc as PllSource, | ||
| 3 | Ppre as APBPrescaler, Sw as Sysclk, | ||
| 4 | }; | ||
| 2 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; | 5 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; |
| 3 | use crate::rcc::Clocks; | 6 | use crate::rcc::Clocks; |
| 4 | use crate::time::{khz, mhz, Hertz}; | 7 | use crate::time::{khz, mhz, Hertz}; |
| 5 | 8 | ||
| 6 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, | ||
| 7 | /// and with the addition of the init function to configure a system clock. | ||
| 8 | |||
| 9 | /// Only the basic setup using the HSE and HSI clocks are supported as of now. | ||
| 10 | |||
| 11 | /// HSI speed | 9 | /// HSI speed |
| 12 | pub const HSI_FREQ: Hertz = Hertz(16_000_000); | 10 | pub const HSI_FREQ: Hertz = Hertz(16_000_000); |
| 13 | 11 | ||
| 14 | /// LSI speed | 12 | /// LSI speed |
| 15 | pub const LSI_FREQ: Hertz = Hertz(32_000); | 13 | pub const LSI_FREQ: Hertz = Hertz(32_000); |
| 16 | 14 | ||
| 17 | #[derive(Clone, Copy)] | ||
| 18 | pub enum HsePrescaler { | ||
| 19 | NotDivided, | ||
| 20 | Div2, | ||
| 21 | } | ||
| 22 | |||
| 23 | impl From<HsePrescaler> for bool { | ||
| 24 | fn from(value: HsePrescaler) -> Self { | ||
| 25 | match value { | ||
| 26 | HsePrescaler::NotDivided => false, | ||
| 27 | HsePrescaler::Div2 => true, | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | pub struct Hse { | 15 | pub struct Hse { |
| 33 | pub prediv: HsePrescaler, | 16 | pub prediv: HsePrescaler, |
| 34 | 17 | ||
| 35 | pub frequency: Hertz, | 18 | pub frequency: Hertz, |
| 36 | } | 19 | } |
| 37 | 20 | ||
| 38 | /// System clock mux source | ||
| 39 | #[derive(Clone, Copy, PartialEq)] | ||
| 40 | pub enum Sysclk { | ||
| 41 | /// MSI selected as sysclk | ||
| 42 | MSI, | ||
| 43 | /// HSI selected as sysclk | ||
| 44 | HSI, | ||
| 45 | /// HSE selected as sysclk | ||
| 46 | HSE, | ||
| 47 | /// PLL selected as sysclk | ||
| 48 | Pll, | ||
| 49 | } | ||
| 50 | |||
| 51 | impl From<Sysclk> for u8 { | ||
| 52 | fn from(value: Sysclk) -> Self { | ||
| 53 | match value { | ||
| 54 | Sysclk::MSI => 0b00, | ||
| 55 | Sysclk::HSI => 0b01, | ||
| 56 | Sysclk::HSE => 0b10, | ||
| 57 | Sysclk::Pll => 0b11, | ||
| 58 | } | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | #[derive(Clone, Copy, PartialEq)] | ||
| 63 | pub enum PllSource { | ||
| 64 | Hsi, | ||
| 65 | Msi, | ||
| 66 | Hse, | ||
| 67 | } | ||
| 68 | |||
| 69 | impl From<PllSource> for u8 { | ||
| 70 | fn from(value: PllSource) -> Self { | ||
| 71 | match value { | ||
| 72 | PllSource::Msi => 0b01, | ||
| 73 | PllSource::Hsi => 0b10, | ||
| 74 | PllSource::Hse => 0b11, | ||
| 75 | } | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | pub enum Pll48Source { | ||
| 80 | PllSai, | ||
| 81 | Pll, | ||
| 82 | Msi, | ||
| 83 | Hsi48, | ||
| 84 | } | ||
| 85 | |||
| 86 | pub struct PllMux { | 21 | pub struct PllMux { |
| 87 | /// Source clock selection. | 22 | /// Source clock selection. |
| 88 | pub source: PllSource, | 23 | pub source: PllSource, |
| 89 | 24 | ||
| 90 | /// PLL pre-divider (DIVM). Must be between 1 and 63. | 25 | /// PLL pre-divider (DIVM). Must be between 1 and 63. |
| 91 | pub prediv: u8, | 26 | pub prediv: Pllm, |
| 92 | } | 27 | } |
| 93 | 28 | ||
| 94 | pub struct Pll { | 29 | pub struct Pll { |
| 95 | /// PLL multiplication factor. Must be between 4 and 512. | 30 | /// PLL multiplication factor. Must be between 4 and 512. |
| 96 | pub mul: u16, | 31 | pub mul: Plln, |
| 97 | 32 | ||
| 98 | /// PLL P division factor. If None, PLL P output is disabled. Must be between 1 and 128. | 33 | /// PLL P division factor. If None, PLL P output is disabled. Must be between 1 and 128. |
| 99 | /// On PLL1, it must be even (in particular, it cannot be 1.) | 34 | /// On PLL1, it must be even (in particular, it cannot be 1.) |
| 100 | pub divp: Option<u16>, | 35 | pub divp: Option<Pllp>, |
| 101 | /// PLL Q division factor. If None, PLL Q output is disabled. Must be between 1 and 128. | 36 | /// PLL Q division factor. If None, PLL Q output is disabled. Must be between 1 and 128. |
| 102 | pub divq: Option<u16>, | 37 | pub divq: Option<Pllq>, |
| 103 | /// PLL R division factor. If None, PLL R output is disabled. Must be between 1 and 128. | 38 | /// PLL R division factor. If None, PLL R output is disabled. Must be between 1 and 128. |
| 104 | pub divr: Option<u16>, | 39 | pub divr: Option<Pllr>, |
| 105 | } | 40 | } |
| 106 | 41 | ||
| 107 | /// Clocks configutation | 42 | /// Clocks configutation |
| @@ -111,7 +46,6 @@ pub struct Config { | |||
| 111 | pub lsi: bool, | 46 | pub lsi: bool, |
| 112 | pub sys: Sysclk, | 47 | pub sys: Sysclk, |
| 113 | pub mux: Option<PllMux>, | 48 | pub mux: Option<PllMux>, |
| 114 | pub pll48: Option<Pll48Source>, | ||
| 115 | pub rtc: Option<RtcClockSource>, | 49 | pub rtc: Option<RtcClockSource>, |
| 116 | 50 | ||
| 117 | pub pll: Option<Pll>, | 51 | pub pll: Option<Pll>, |
| @@ -127,23 +61,22 @@ pub struct Config { | |||
| 127 | pub const WPAN_DEFAULT: Config = Config { | 61 | pub const WPAN_DEFAULT: Config = Config { |
| 128 | hse: Some(Hse { | 62 | hse: Some(Hse { |
| 129 | frequency: mhz(32), | 63 | frequency: mhz(32), |
| 130 | prediv: HsePrescaler::NotDivided, | 64 | prediv: HsePrescaler::DIV1, |
| 131 | }), | 65 | }), |
| 132 | lse: Some(khz(32)), | 66 | lse: Some(khz(32)), |
| 133 | sys: Sysclk::Pll, | 67 | sys: Sysclk::PLL, |
| 134 | mux: Some(PllMux { | 68 | mux: Some(PllMux { |
| 135 | source: PllSource::Hse, | 69 | source: PllSource::HSE, |
| 136 | prediv: 2, | 70 | prediv: Pllm::DIV2, |
| 137 | }), | 71 | }), |
| 138 | pll48: None, | ||
| 139 | rtc: Some(RtcClockSource::LSE), | 72 | rtc: Some(RtcClockSource::LSE), |
| 140 | lsi: false, | 73 | lsi: false, |
| 141 | 74 | ||
| 142 | pll: Some(Pll { | 75 | pll: Some(Pll { |
| 143 | mul: 12, | 76 | mul: Plln::MUL12, |
| 144 | divp: Some(3), | 77 | divp: Some(Pllp::DIV3), |
| 145 | divq: Some(4), | 78 | divq: Some(Pllq::DIV4), |
| 146 | divr: Some(3), | 79 | divr: Some(Pllr::DIV3), |
| 147 | }), | 80 | }), |
| 148 | pllsai: None, | 81 | pllsai: None, |
| 149 | 82 | ||
| @@ -160,9 +93,8 @@ impl Default for Config { | |||
| 160 | Config { | 93 | Config { |
| 161 | hse: None, | 94 | hse: None, |
| 162 | lse: None, | 95 | lse: None, |
| 163 | sys: Sysclk::HSI, | 96 | sys: Sysclk::HSI16, |
| 164 | mux: None, | 97 | mux: None, |
| 165 | pll48: None, | ||
| 166 | pll: None, | 98 | pll: None, |
| 167 | pllsai: None, | 99 | pllsai: None, |
| 168 | rtc: None, | 100 | rtc: None, |
| @@ -178,15 +110,12 @@ impl Default for Config { | |||
| 178 | } | 110 | } |
| 179 | 111 | ||
| 180 | pub(crate) fn compute_clocks(config: &Config) -> Clocks { | 112 | pub(crate) fn compute_clocks(config: &Config) -> Clocks { |
| 181 | let hse_clk = config.hse.as_ref().map(|hse| match hse.prediv { | 113 | let hse_clk = config.hse.as_ref().map(|hse| hse.frequency / hse.prediv); |
| 182 | HsePrescaler::NotDivided => hse.frequency, | ||
| 183 | HsePrescaler::Div2 => hse.frequency / 2u32, | ||
| 184 | }); | ||
| 185 | 114 | ||
| 186 | let mux_clk = config.mux.as_ref().map(|pll_mux| { | 115 | let mux_clk = config.mux.as_ref().map(|pll_mux| { |
| 187 | (match pll_mux.source { | 116 | (match pll_mux.source { |
| 188 | PllSource::Hse => hse_clk.unwrap(), | 117 | PllSource::HSE => hse_clk.unwrap(), |
| 189 | PllSource::Hsi => HSI_FREQ, | 118 | PllSource::HSI16 => HSI_FREQ, |
| 190 | _ => unreachable!(), | 119 | _ => unreachable!(), |
| 191 | } / pll_mux.prediv) | 120 | } / pll_mux.prediv) |
| 192 | }); | 121 | }); |
| @@ -206,44 +135,19 @@ pub(crate) fn compute_clocks(config: &Config) -> Clocks { | |||
| 206 | 135 | ||
| 207 | let sys_clk = match config.sys { | 136 | let sys_clk = match config.sys { |
| 208 | Sysclk::HSE => hse_clk.unwrap(), | 137 | Sysclk::HSE => hse_clk.unwrap(), |
| 209 | Sysclk::HSI => HSI_FREQ, | 138 | Sysclk::HSI16 => HSI_FREQ, |
| 210 | Sysclk::Pll => pll_r.unwrap(), | 139 | Sysclk::PLL => pll_r.unwrap(), |
| 211 | _ => unreachable!(), | 140 | _ => unreachable!(), |
| 212 | }; | 141 | }; |
| 213 | 142 | ||
| 214 | let ahb1_clk = match config.ahb1_pre { | 143 | let ahb1_clk = sys_clk / config.ahb1_pre; |
| 215 | AHBPrescaler::DIV1 => sys_clk, | 144 | let ahb2_clk = sys_clk / config.ahb2_pre; |
| 216 | pre => { | 145 | let ahb3_clk = sys_clk / config.ahb3_pre; |
| 217 | let pre: u8 = pre.into(); | ||
| 218 | let pre = 1u32 << (pre as u32 - 7); | ||
| 219 | sys_clk / pre | ||
| 220 | } | ||
| 221 | }; | ||
| 222 | |||
| 223 | let ahb2_clk = match config.ahb2_pre { | ||
| 224 | AHBPrescaler::DIV1 => sys_clk, | ||
| 225 | pre => { | ||
| 226 | let pre: u8 = pre.into(); | ||
| 227 | let pre = 1u32 << (pre as u32 - 7); | ||
| 228 | sys_clk / pre | ||
| 229 | } | ||
| 230 | }; | ||
| 231 | |||
| 232 | let ahb3_clk = match config.ahb3_pre { | ||
| 233 | AHBPrescaler::DIV1 => sys_clk, | ||
| 234 | pre => { | ||
| 235 | let pre: u8 = pre.into(); | ||
| 236 | let pre = 1u32 << (pre as u32 - 7); | ||
| 237 | sys_clk / pre | ||
| 238 | } | ||
| 239 | }; | ||
| 240 | 146 | ||
| 241 | let (apb1_clk, apb1_tim_clk) = match config.apb1_pre { | 147 | let (apb1_clk, apb1_tim_clk) = match config.apb1_pre { |
| 242 | APBPrescaler::DIV1 => (ahb1_clk, ahb1_clk), | 148 | APBPrescaler::DIV1 => (ahb1_clk, ahb1_clk), |
| 243 | pre => { | 149 | pre => { |
| 244 | let pre: u8 = pre.into(); | 150 | let freq = ahb1_clk / pre; |
| 245 | let pre: u8 = 1 << (pre - 3); | ||
| 246 | let freq = ahb1_clk / pre as u32; | ||
| 247 | (freq, freq * 2u32) | 151 | (freq, freq * 2u32) |
| 248 | } | 152 | } |
| 249 | }; | 153 | }; |
| @@ -251,9 +155,7 @@ pub(crate) fn compute_clocks(config: &Config) -> Clocks { | |||
| 251 | let (apb2_clk, apb2_tim_clk) = match config.apb2_pre { | 155 | let (apb2_clk, apb2_tim_clk) = match config.apb2_pre { |
| 252 | APBPrescaler::DIV1 => (ahb1_clk, ahb1_clk), | 156 | APBPrescaler::DIV1 => (ahb1_clk, ahb1_clk), |
| 253 | pre => { | 157 | pre => { |
| 254 | let pre: u8 = pre.into(); | 158 | let freq = ahb1_clk / pre; |
| 255 | let pre: u8 = 1 << (pre - 3); | ||
| 256 | let freq = ahb1_clk / pre as u32; | ||
| 257 | (freq, freq * 2u32) | 159 | (freq, freq * 2u32) |
| 258 | } | 160 | } |
| 259 | }; | 161 | }; |
| @@ -282,12 +184,12 @@ pub(crate) fn configure_clocks(config: &Config) { | |||
| 282 | let rcc = crate::pac::RCC; | 184 | let rcc = crate::pac::RCC; |
| 283 | 185 | ||
| 284 | let needs_hsi = if let Some(pll_mux) = &config.mux { | 186 | let needs_hsi = if let Some(pll_mux) = &config.mux { |
| 285 | pll_mux.source == PllSource::Hsi | 187 | pll_mux.source == PllSource::HSI16 |
| 286 | } else { | 188 | } else { |
| 287 | false | 189 | false |
| 288 | }; | 190 | }; |
| 289 | 191 | ||
| 290 | if needs_hsi || config.sys == Sysclk::HSI { | 192 | if needs_hsi || config.sys == Sysclk::HSI16 { |
| 291 | rcc.cr().modify(|w| { | 193 | rcc.cr().modify(|w| { |
| 292 | w.set_hsion(true); | 194 | w.set_hsion(true); |
| 293 | }); | 195 | }); |
| @@ -306,7 +208,7 @@ pub(crate) fn configure_clocks(config: &Config) { | |||
| 306 | match &config.hse { | 208 | match &config.hse { |
| 307 | Some(hse) => { | 209 | Some(hse) => { |
| 308 | rcc.cr().modify(|w| { | 210 | rcc.cr().modify(|w| { |
| 309 | w.set_hsepre(hse.prediv.into()); | 211 | w.set_hsepre(hse.prediv); |
| 310 | w.set_hseon(true); | 212 | w.set_hseon(true); |
| 311 | }); | 213 | }); |
| 312 | 214 | ||
| @@ -328,18 +230,18 @@ pub(crate) fn configure_clocks(config: &Config) { | |||
| 328 | match &config.pll { | 230 | match &config.pll { |
| 329 | Some(pll) => { | 231 | Some(pll) => { |
| 330 | rcc.pllcfgr().modify(|w| { | 232 | rcc.pllcfgr().modify(|w| { |
| 331 | w.set_plln(pll.mul as u8); | 233 | w.set_plln(pll.mul); |
| 332 | pll.divp.map(|divp| { | 234 | pll.divp.map(|divp| { |
| 333 | w.set_pllpen(true); | 235 | w.set_pllpen(true); |
| 334 | w.set_pllp((divp - 1) as u8) | 236 | w.set_pllp(divp) |
| 335 | }); | 237 | }); |
| 336 | pll.divq.map(|divq| { | 238 | pll.divq.map(|divq| { |
| 337 | w.set_pllqen(true); | 239 | w.set_pllqen(true); |
| 338 | w.set_pllq((divq - 1) as u8) | 240 | w.set_pllq(divq) |
| 339 | }); | 241 | }); |
| 340 | pll.divr.map(|divr| { | 242 | pll.divr.map(|divr| { |
| 341 | // w.set_pllren(true); | 243 | w.set_pllren(true); |
| 342 | w.set_pllr((divr - 1) as u8); | 244 | w.set_pllr(divr); |
| 343 | }); | 245 | }); |
| 344 | }); | 246 | }); |
| 345 | 247 | ||
| @@ -352,13 +254,13 @@ pub(crate) fn configure_clocks(config: &Config) { | |||
| 352 | 254 | ||
| 353 | rcc.cfgr().modify(|w| { | 255 | rcc.cfgr().modify(|w| { |
| 354 | w.set_sw(config.sys.into()); | 256 | w.set_sw(config.sys.into()); |
| 355 | w.set_hpre(config.ahb1_pre.into()); | 257 | w.set_hpre(config.ahb1_pre); |
| 356 | w.set_ppre1(config.apb1_pre.into()); | 258 | w.set_ppre1(config.apb1_pre); |
| 357 | w.set_ppre2(config.apb2_pre.into()); | 259 | w.set_ppre2(config.apb2_pre); |
| 358 | }); | 260 | }); |
| 359 | 261 | ||
| 360 | rcc.extcfgr().modify(|w| { | 262 | rcc.extcfgr().modify(|w| { |
| 361 | w.set_c2hpre(config.ahb2_pre.into()); | 263 | w.set_c2hpre(config.ahb2_pre); |
| 362 | w.set_shdhpre(config.ahb3_pre.into()); | 264 | w.set_shdhpre(config.ahb3_pre); |
| 363 | }); | 265 | }); |
| 364 | } | 266 | } |
diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs index c5d7ab62f..9ade369f5 100644 --- a/embassy-stm32/src/rcc/wba.rs +++ b/embassy-stm32/src/rcc/wba.rs | |||
| @@ -108,13 +108,13 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 108 | }); | 108 | }); |
| 109 | 109 | ||
| 110 | RCC.cfgr2().modify(|w| { | 110 | RCC.cfgr2().modify(|w| { |
| 111 | w.set_hpre(config.ahb_pre.into()); | 111 | w.set_hpre(config.ahb_pre); |
| 112 | w.set_ppre1(config.apb1_pre.into()); | 112 | w.set_ppre1(config.apb1_pre); |
| 113 | w.set_ppre2(config.apb2_pre.into()); | 113 | w.set_ppre2(config.apb2_pre); |
| 114 | }); | 114 | }); |
| 115 | 115 | ||
| 116 | RCC.cfgr3().modify(|w| { | 116 | RCC.cfgr3().modify(|w| { |
| 117 | w.set_ppre7(config.apb7_pre.into()); | 117 | w.set_ppre7(config.apb7_pre); |
| 118 | }); | 118 | }); |
| 119 | 119 | ||
| 120 | let ahb_freq = sys_clk / config.ahb_pre; | 120 | let ahb_freq = sys_clk / config.ahb_pre; |
diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 7baedfcdb..f12588a59 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs | |||
| @@ -1,16 +1,14 @@ | |||
| 1 | pub use crate::pac::pwr::vals::Vos as VoltageScale; | 1 | pub use crate::pac::pwr::vals::Vos as VoltageScale; |
| 2 | use crate::pac::rcc::vals::Adcsel; | 2 | use crate::pac::rcc::vals::Sw; |
| 3 | pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; | 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 | }; | ||
| 4 | use crate::pac::{FLASH, RCC}; | 7 | use crate::pac::{FLASH, RCC}; |
| 5 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; | 8 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; |
| 6 | use crate::rcc::{set_freqs, Clocks}; | 9 | use crate::rcc::{set_freqs, Clocks}; |
| 7 | use crate::time::Hertz; | 10 | use crate::time::Hertz; |
| 8 | 11 | ||
| 9 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, | ||
| 10 | /// and with the addition of the init function to configure a system clock. | ||
| 11 | |||
| 12 | /// Only the basic setup using the HSE and HSI clocks are supported as of now. | ||
| 13 | |||
| 14 | /// HSI speed | 12 | /// HSI speed |
| 15 | pub const HSI_FREQ: Hertz = Hertz(16_000_000); | 13 | pub const HSI_FREQ: Hertz = Hertz(16_000_000); |
| 16 | 14 | ||
| @@ -28,109 +26,6 @@ pub enum ClockSrc { | |||
| 28 | HSI16, | 26 | HSI16, |
| 29 | } | 27 | } |
| 30 | 28 | ||
| 31 | #[derive(Clone, Copy, PartialOrd, PartialEq)] | ||
| 32 | pub enum MSIRange { | ||
| 33 | /// Around 100 kHz | ||
| 34 | Range0, | ||
| 35 | /// Around 200 kHz | ||
| 36 | Range1, | ||
| 37 | /// Around 400 kHz | ||
| 38 | Range2, | ||
| 39 | /// Around 800 kHz | ||
| 40 | Range3, | ||
| 41 | /// Around 1 MHz | ||
| 42 | Range4, | ||
| 43 | /// Around 2 MHz | ||
| 44 | Range5, | ||
| 45 | /// Around 4 MHz (reset value) | ||
| 46 | Range6, | ||
| 47 | /// Around 8 MHz | ||
| 48 | Range7, | ||
| 49 | /// Around 16 MHz | ||
| 50 | Range8, | ||
| 51 | /// Around 24 MHz | ||
| 52 | Range9, | ||
| 53 | /// Around 32 MHz | ||
| 54 | Range10, | ||
| 55 | /// Around 48 MHz | ||
| 56 | Range11, | ||
| 57 | } | ||
| 58 | |||
| 59 | impl MSIRange { | ||
| 60 | fn freq(&self) -> u32 { | ||
| 61 | match self { | ||
| 62 | MSIRange::Range0 => 100_000, | ||
| 63 | MSIRange::Range1 => 200_000, | ||
| 64 | MSIRange::Range2 => 400_000, | ||
| 65 | MSIRange::Range3 => 800_000, | ||
| 66 | MSIRange::Range4 => 1_000_000, | ||
| 67 | MSIRange::Range5 => 2_000_000, | ||
| 68 | MSIRange::Range6 => 4_000_000, | ||
| 69 | MSIRange::Range7 => 8_000_000, | ||
| 70 | MSIRange::Range8 => 16_000_000, | ||
| 71 | MSIRange::Range9 => 24_000_000, | ||
| 72 | MSIRange::Range10 => 32_000_000, | ||
| 73 | MSIRange::Range11 => 48_000_000, | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | fn vos(&self) -> VoltageScale { | ||
| 78 | if self > &MSIRange::Range8 { | ||
| 79 | VoltageScale::RANGE1 | ||
| 80 | } else { | ||
| 81 | VoltageScale::RANGE2 | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | impl Default for MSIRange { | ||
| 87 | fn default() -> MSIRange { | ||
| 88 | MSIRange::Range6 | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | impl Into<u8> for MSIRange { | ||
| 93 | fn into(self) -> u8 { | ||
| 94 | match self { | ||
| 95 | MSIRange::Range0 => 0b0000, | ||
| 96 | MSIRange::Range1 => 0b0001, | ||
| 97 | MSIRange::Range2 => 0b0010, | ||
| 98 | MSIRange::Range3 => 0b0011, | ||
| 99 | MSIRange::Range4 => 0b0100, | ||
| 100 | MSIRange::Range5 => 0b0101, | ||
| 101 | MSIRange::Range6 => 0b0110, | ||
| 102 | MSIRange::Range7 => 0b0111, | ||
| 103 | MSIRange::Range8 => 0b1000, | ||
| 104 | MSIRange::Range9 => 0b1001, | ||
| 105 | MSIRange::Range10 => 0b1010, | ||
| 106 | MSIRange::Range11 => 0b1011, | ||
| 107 | } | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | #[derive(Clone, Copy)] | ||
| 112 | pub enum AdcClockSource { | ||
| 113 | HSI16, | ||
| 114 | PLLPCLK, | ||
| 115 | SYSCLK, | ||
| 116 | } | ||
| 117 | |||
| 118 | impl AdcClockSource { | ||
| 119 | pub fn adcsel(&self) -> Adcsel { | ||
| 120 | match self { | ||
| 121 | AdcClockSource::HSI16 => Adcsel::HSI16, | ||
| 122 | AdcClockSource::PLLPCLK => Adcsel::PLLPCLK, | ||
| 123 | AdcClockSource::SYSCLK => Adcsel::SYSCLK, | ||
| 124 | } | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | impl Default for AdcClockSource { | ||
| 129 | fn default() -> Self { | ||
| 130 | Self::HSI16 | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | /// Clocks configutation | 29 | /// Clocks configutation |
| 135 | pub struct Config { | 30 | pub struct Config { |
| 136 | pub mux: ClockSrc, | 31 | pub mux: ClockSrc, |
| @@ -148,7 +43,7 @@ impl Default for Config { | |||
| 148 | #[inline] | 43 | #[inline] |
| 149 | fn default() -> Config { | 44 | fn default() -> Config { |
| 150 | Config { | 45 | Config { |
| 151 | mux: ClockSrc::MSI(MSIRange::default()), | 46 | mux: ClockSrc::MSI(MSIRange::RANGE4M), |
| 152 | ahb_pre: AHBPrescaler::DIV1, | 47 | ahb_pre: AHBPrescaler::DIV1, |
| 153 | shd_ahb_pre: AHBPrescaler::DIV1, | 48 | shd_ahb_pre: AHBPrescaler::DIV1, |
| 154 | apb1_pre: APBPrescaler::DIV1, | 49 | apb1_pre: APBPrescaler::DIV1, |
| @@ -156,73 +51,46 @@ impl Default for Config { | |||
| 156 | rtc_mux: RtcClockSource::LSI, | 51 | rtc_mux: RtcClockSource::LSI, |
| 157 | lsi: true, | 52 | lsi: true, |
| 158 | lse: None, | 53 | lse: None, |
| 159 | adc_clock_source: AdcClockSource::default(), | 54 | adc_clock_source: AdcClockSource::HSI16, |
| 160 | } | 55 | } |
| 161 | } | 56 | } |
| 162 | } | 57 | } |
| 163 | 58 | ||
| 164 | #[repr(u8)] | ||
| 165 | pub enum Lsedrv { | ||
| 166 | Low = 0, | ||
| 167 | MediumLow = 1, | ||
| 168 | MediumHigh = 2, | ||
| 169 | High = 3, | ||
| 170 | } | ||
| 171 | |||
| 172 | pub(crate) unsafe fn init(config: Config) { | 59 | pub(crate) unsafe fn init(config: Config) { |
| 173 | let (sys_clk, sw, vos) = match config.mux { | 60 | let (sys_clk, sw, vos) = match config.mux { |
| 174 | ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::RANGE2), | 61 | ClockSrc::HSI16 => (HSI_FREQ, Sw::HSI16, VoltageScale::RANGE2), |
| 175 | ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::RANGE1), | 62 | ClockSrc::HSE32 => (HSE32_FREQ, Sw::HSE32, VoltageScale::RANGE1), |
| 176 | ClockSrc::MSI(range) => (range.freq(), 0x00, range.vos()), | 63 | ClockSrc::MSI(range) => (msirange_to_hertz(range), Sw::MSI, msirange_to_vos(range)), |
| 177 | }; | 64 | }; |
| 178 | 65 | ||
| 179 | let ahb_freq: u32 = match config.ahb_pre { | 66 | let ahb_freq = sys_clk / config.ahb_pre; |
| 180 | AHBPrescaler::DIV1 => sys_clk, | 67 | let shd_ahb_freq = sys_clk / config.shd_ahb_pre; |
| 181 | pre => { | ||
| 182 | let pre: u8 = pre.into(); | ||
| 183 | let pre = 1 << (pre as u32 - 7); | ||
| 184 | sys_clk / pre | ||
| 185 | } | ||
| 186 | }; | ||
| 187 | |||
| 188 | let shd_ahb_freq: u32 = match config.shd_ahb_pre { | ||
| 189 | AHBPrescaler::DIV1 => sys_clk, | ||
| 190 | pre => { | ||
| 191 | let pre: u8 = pre.into(); | ||
| 192 | let pre = 1 << (pre as u32 - 7); | ||
| 193 | sys_clk / pre | ||
| 194 | } | ||
| 195 | }; | ||
| 196 | 68 | ||
| 197 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { | 69 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { |
| 198 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | 70 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), |
| 199 | pre => { | 71 | pre => { |
| 200 | let pre: u8 = pre.into(); | 72 | let freq = ahb_freq / pre; |
| 201 | let pre: u8 = 1 << (pre - 3); | 73 | (freq, freq * 2u32) |
| 202 | let freq = ahb_freq / pre as u32; | ||
| 203 | (freq, freq * 2) | ||
| 204 | } | 74 | } |
| 205 | }; | 75 | }; |
| 206 | 76 | ||
| 207 | let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { | 77 | let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { |
| 208 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | 78 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), |
| 209 | pre => { | 79 | pre => { |
| 210 | let pre: u8 = pre.into(); | 80 | let freq = ahb_freq / pre; |
| 211 | let pre: u8 = 1 << (pre - 3); | 81 | (freq, freq * 2u32) |
| 212 | let freq = ahb_freq / pre as u32; | ||
| 213 | (freq, freq * 2) | ||
| 214 | } | 82 | } |
| 215 | }; | 83 | }; |
| 216 | 84 | ||
| 217 | // Adjust flash latency | 85 | // Adjust flash latency |
| 218 | let flash_clk_src_freq: u32 = shd_ahb_freq; | 86 | let flash_clk_src_freq = shd_ahb_freq; |
| 219 | let ws = match vos { | 87 | let ws = match vos { |
| 220 | VoltageScale::RANGE1 => match flash_clk_src_freq { | 88 | VoltageScale::RANGE1 => match flash_clk_src_freq.0 { |
| 221 | 0..=18_000_000 => 0b000, | 89 | 0..=18_000_000 => 0b000, |
| 222 | 18_000_001..=36_000_000 => 0b001, | 90 | 18_000_001..=36_000_000 => 0b001, |
| 223 | _ => 0b010, | 91 | _ => 0b010, |
| 224 | }, | 92 | }, |
| 225 | VoltageScale::RANGE2 => match flash_clk_src_freq { | 93 | VoltageScale::RANGE2 => match flash_clk_src_freq.0 { |
| 226 | 0..=6_000_000 => 0b000, | 94 | 0..=6_000_000 => 0b000, |
| 227 | 6_000_001..=12_000_000 => 0b001, | 95 | 6_000_001..=12_000_000 => 0b001, |
| 228 | _ => 0b010, | 96 | _ => 0b010, |
| @@ -258,7 +126,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 258 | assert!(!cr.msion() || cr.msirdy()); | 126 | assert!(!cr.msion() || cr.msirdy()); |
| 259 | RCC.cr().write(|w| { | 127 | RCC.cr().write(|w| { |
| 260 | w.set_msirgsel(true); | 128 | w.set_msirgsel(true); |
| 261 | w.set_msirange(range.into()); | 129 | w.set_msirange(range); |
| 262 | w.set_msion(true); | 130 | w.set_msion(true); |
| 263 | 131 | ||
| 264 | if config.rtc_mux == RtcClockSource::LSE { | 132 | if config.rtc_mux == RtcClockSource::LSE { |
| @@ -273,34 +141,56 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 273 | } | 141 | } |
| 274 | 142 | ||
| 275 | RCC.extcfgr().modify(|w| { | 143 | RCC.extcfgr().modify(|w| { |
| 276 | if config.shd_ahb_pre == AHBPrescaler::DIV1 { | 144 | w.set_shdhpre(config.shd_ahb_pre); |
| 277 | w.set_shdhpre(0); | ||
| 278 | } else { | ||
| 279 | w.set_shdhpre(config.shd_ahb_pre.into()); | ||
| 280 | } | ||
| 281 | }); | 145 | }); |
| 282 | 146 | ||
| 283 | RCC.cfgr().modify(|w| { | 147 | RCC.cfgr().modify(|w| { |
| 284 | w.set_sw(sw.into()); | 148 | w.set_sw(sw.into()); |
| 285 | w.set_hpre(config.ahb_pre); | 149 | w.set_hpre(config.ahb_pre); |
| 286 | w.set_ppre1(config.apb1_pre.into()); | 150 | w.set_ppre1(config.apb1_pre); |
| 287 | w.set_ppre2(config.apb2_pre.into()); | 151 | w.set_ppre2(config.apb2_pre); |
| 288 | }); | 152 | }); |
| 289 | 153 | ||
| 290 | // ADC clock MUX | 154 | // ADC clock MUX |
| 291 | RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source.adcsel())); | 155 | RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source)); |
| 292 | 156 | ||
| 293 | // TODO: switch voltage range | 157 | // TODO: switch voltage range |
| 294 | 158 | ||
| 295 | set_freqs(Clocks { | 159 | set_freqs(Clocks { |
| 296 | sys: Hertz(sys_clk), | 160 | sys: sys_clk, |
| 297 | ahb1: Hertz(ahb_freq), | 161 | ahb1: ahb_freq, |
| 298 | ahb2: Hertz(ahb_freq), | 162 | ahb2: ahb_freq, |
| 299 | ahb3: Hertz(shd_ahb_freq), | 163 | ahb3: shd_ahb_freq, |
| 300 | apb1: Hertz(apb1_freq), | 164 | apb1: apb1_freq, |
| 301 | apb2: Hertz(apb2_freq), | 165 | apb2: apb2_freq, |
| 302 | apb3: Hertz(shd_ahb_freq), | 166 | apb3: shd_ahb_freq, |
| 303 | apb1_tim: Hertz(apb1_tim_freq), | 167 | apb1_tim: apb1_tim_freq, |
| 304 | apb2_tim: Hertz(apb2_tim_freq), | 168 | apb2_tim: apb2_tim_freq, |
| 305 | }); | 169 | }); |
| 306 | } | 170 | } |
| 171 | |||
| 172 | fn msirange_to_hertz(range: MSIRange) -> Hertz { | ||
| 173 | match range { | ||
| 174 | MSIRange::RANGE100K => Hertz(100_000), | ||
| 175 | MSIRange::RANGE200K => Hertz(200_000), | ||
| 176 | MSIRange::RANGE400K => Hertz(400_000), | ||
| 177 | MSIRange::RANGE800K => Hertz(800_000), | ||
| 178 | MSIRange::RANGE1M => Hertz(1_000_000), | ||
| 179 | MSIRange::RANGE2M => Hertz(2_000_000), | ||
| 180 | MSIRange::RANGE4M => Hertz(4_000_000), | ||
| 181 | MSIRange::RANGE8M => Hertz(8_000_000), | ||
| 182 | MSIRange::RANGE16M => Hertz(16_000_000), | ||
| 183 | MSIRange::RANGE24M => Hertz(24_000_000), | ||
| 184 | MSIRange::RANGE32M => Hertz(32_000_000), | ||
| 185 | MSIRange::RANGE48M => Hertz(48_000_000), | ||
| 186 | _ => unreachable!(), | ||
| 187 | } | ||
| 188 | } | ||
| 189 | |||
| 190 | fn msirange_to_vos(range: MSIRange) -> VoltageScale { | ||
| 191 | if range.to_bits() > MSIRange::RANGE16M.to_bits() { | ||
| 192 | VoltageScale::RANGE1 | ||
| 193 | } else { | ||
| 194 | VoltageScale::RANGE2 | ||
| 195 | } | ||
| 196 | } | ||
diff --git a/embassy-stm32/src/time.rs b/embassy-stm32/src/time.rs index 604503e61..a0bc33944 100644 --- a/embassy-stm32/src/time.rs +++ b/embassy-stm32/src/time.rs | |||
| @@ -77,3 +77,10 @@ impl Div<u8> for Hertz { | |||
| 77 | self / (rhs as u32) | 77 | self / (rhs as u32) |
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | |||
| 81 | impl Div<Hertz> for Hertz { | ||
| 82 | type Output = u32; | ||
| 83 | fn div(self, rhs: Hertz) -> Self::Output { | ||
| 84 | self.0 / rhs.0 | ||
| 85 | } | ||
| 86 | } | ||
diff --git a/examples/stm32f334/src/bin/adc.rs b/examples/stm32f334/src/bin/adc.rs index ed246a7db..a9286c44c 100644 --- a/examples/stm32f334/src/bin/adc.rs +++ b/examples/stm32f334/src/bin/adc.rs | |||
| @@ -6,7 +6,7 @@ use defmt::info; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::adc::{Adc, SampleTime}; | 7 | use embassy_stm32::adc::{Adc, SampleTime}; |
| 8 | use embassy_stm32::peripherals::ADC1; | 8 | use embassy_stm32::peripherals::ADC1; |
| 9 | use embassy_stm32::rcc::AdcClockSource; | 9 | use embassy_stm32::rcc::{AdcClockSource, Adcpres}; |
| 10 | use embassy_stm32::time::mhz; | 10 | use embassy_stm32::time::mhz; |
| 11 | use embassy_stm32::{adc, bind_interrupts, Config}; | 11 | use embassy_stm32::{adc, bind_interrupts, Config}; |
| 12 | use embassy_time::{Delay, Duration, Timer}; | 12 | use embassy_time::{Delay, Duration, Timer}; |
| @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) -> ! { | |||
| 23 | config.rcc.hclk = Some(mhz(64)); | 23 | config.rcc.hclk = Some(mhz(64)); |
| 24 | config.rcc.pclk1 = Some(mhz(32)); | 24 | config.rcc.pclk1 = Some(mhz(32)); |
| 25 | config.rcc.pclk2 = Some(mhz(64)); | 25 | config.rcc.pclk2 = Some(mhz(64)); |
| 26 | config.rcc.adc = Some(AdcClockSource::PllDiv1); | 26 | config.rcc.adc = Some(AdcClockSource::Pll(Adcpres::DIV1)); |
| 27 | 27 | ||
| 28 | let mut p = embassy_stm32::init(config); | 28 | let mut p = embassy_stm32::init(config); |
| 29 | 29 | ||
diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs index 3fffcfb1f..fb5a85bcb 100644 --- a/examples/stm32f334/src/bin/opamp.rs +++ b/examples/stm32f334/src/bin/opamp.rs | |||
| @@ -7,7 +7,7 @@ use embassy_executor::Spawner; | |||
| 7 | use embassy_stm32::adc::{Adc, SampleTime}; | 7 | use embassy_stm32::adc::{Adc, SampleTime}; |
| 8 | use embassy_stm32::opamp::{OpAmp, OpAmpGain}; | 8 | use embassy_stm32::opamp::{OpAmp, OpAmpGain}; |
| 9 | use embassy_stm32::peripherals::ADC2; | 9 | use embassy_stm32::peripherals::ADC2; |
| 10 | use embassy_stm32::rcc::AdcClockSource; | 10 | use embassy_stm32::rcc::{AdcClockSource, Adcpres}; |
| 11 | use embassy_stm32::time::mhz; | 11 | use embassy_stm32::time::mhz; |
| 12 | use embassy_stm32::{adc, bind_interrupts, Config}; | 12 | use embassy_stm32::{adc, bind_interrupts, Config}; |
| 13 | use embassy_time::{Delay, Duration, Timer}; | 13 | use embassy_time::{Delay, Duration, Timer}; |
| @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) -> ! { | |||
| 24 | config.rcc.hclk = Some(mhz(64)); | 24 | config.rcc.hclk = Some(mhz(64)); |
| 25 | config.rcc.pclk1 = Some(mhz(32)); | 25 | config.rcc.pclk1 = Some(mhz(32)); |
| 26 | config.rcc.pclk2 = Some(mhz(64)); | 26 | config.rcc.pclk2 = Some(mhz(64)); |
| 27 | config.rcc.adc = Some(AdcClockSource::PllDiv1); | 27 | config.rcc.adc = Some(AdcClockSource::Pll(Adcpres::DIV1)); |
| 28 | 28 | ||
| 29 | let mut p = embassy_stm32::init(config); | 29 | let mut p = embassy_stm32::init(config); |
| 30 | 30 | ||
diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs index da9b18a0e..30a112b7e 100644 --- a/examples/stm32g4/src/bin/adc.rs +++ b/examples/stm32g4/src/bin/adc.rs | |||
| @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { | |||
| 24 | div_r: Some(PllR::DIV2), | 24 | div_r: Some(PllR::DIV2), |
| 25 | }); | 25 | }); |
| 26 | 26 | ||
| 27 | config.rcc.adc12_clock_source = AdcClockSource::SysClk; | 27 | config.rcc.adc12_clock_source = AdcClockSource::SYSCLK; |
| 28 | config.rcc.mux = ClockSrc::PLL; | 28 | config.rcc.mux = ClockSrc::PLL; |
| 29 | 29 | ||
| 30 | let mut p = embassy_stm32::init(config); | 30 | let mut p = embassy_stm32::init(config); |
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 79a9b5e86..f2ba5f7fc 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs | |||
| @@ -322,8 +322,8 @@ pub fn config() -> Config { | |||
| 322 | config.rcc.mux = ClockSrc::PLL( | 322 | config.rcc.mux = ClockSrc::PLL( |
| 323 | // 32Mhz clock (16 * 4 / 2) | 323 | // 32Mhz clock (16 * 4 / 2) |
| 324 | PLLSource::HSI16, | 324 | PLLSource::HSI16, |
| 325 | PLLMul::Mul4, | 325 | PLLMul::MUL4, |
| 326 | PLLDiv::Div2, | 326 | PLLDiv::DIV2, |
| 327 | ); | 327 | ); |
| 328 | } | 328 | } |
| 329 | 329 | ||
| @@ -333,8 +333,8 @@ pub fn config() -> Config { | |||
| 333 | config.rcc.mux = ClockSrc::PLL( | 333 | config.rcc.mux = ClockSrc::PLL( |
| 334 | // 32Mhz clock (16 * 4 / 2) | 334 | // 32Mhz clock (16 * 4 / 2) |
| 335 | PLLSource::HSI, | 335 | PLLSource::HSI, |
| 336 | PLLMul::Mul4, | 336 | PLLMul::MUL4, |
| 337 | PLLDiv::Div2, | 337 | PLLDiv::DIV2, |
| 338 | ); | 338 | ); |
| 339 | } | 339 | } |
| 340 | 340 | ||
