diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-10-11 01:08:01 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-10-11 01:22:27 +0200 |
| commit | 21915a9a3fed5390c9f505fff29f49ee32d55e78 (patch) | |
| tree | 26c8cb8e04229a9012bfe21c76a5910fe5972ba9 | |
| parent | d0d0ceec6acc0bae8a16f0ebdffaf24b40a018cd (diff) | |
stm32/rcc: unify L0 and L1.
| -rw-r--r-- | embassy-stm32/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/bd.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l0l1.rs (renamed from embassy-stm32/src/rcc/l0.rs) | 28 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l1.rs | 198 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 3 | ||||
| -rw-r--r-- | tests/stm32/src/common.rs | 2 |
6 files changed, 17 insertions, 220 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index b6641d71d..6137e3c02 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-ff45aa382efb704dd2275dd69e71af73343f149d" } | 62 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9f45b0c48cc3de71ec6a66fe7e871b21aef0940c" } |
| 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-ff45aa382efb704dd2275dd69e71af73343f149d", default-features = false, features = ["metadata"]} | 80 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9f45b0c48cc3de71ec6a66fe7e871b21aef0940c", default-features = false, features = ["metadata"]} |
| 81 | 81 | ||
| 82 | 82 | ||
| 83 | [features] | 83 | [features] |
diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index 9c784c3a3..c18e92bc8 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs | |||
| @@ -163,7 +163,7 @@ impl BackupDomain { | |||
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | // If not OK, reset backup domain and configure it. | 165 | // If not OK, reset backup domain and configure it. |
| 166 | #[cfg(not(any(rcc_l0, rcc_l1)))] | 166 | #[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1)))] |
| 167 | { | 167 | { |
| 168 | Self::modify(|w| w.set_bdrst(true)); | 168 | Self::modify(|w| w.set_bdrst(true)); |
| 169 | Self::modify(|w| w.set_bdrst(false)); | 169 | Self::modify(|w| w.set_bdrst(false)); |
diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0l1.rs index 3fd8074d7..4b1acae5d 100644 --- a/embassy-stm32/src/rcc/l0.rs +++ b/embassy-stm32/src/rcc/l0l1.rs | |||
| @@ -95,7 +95,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 95 | ClockSrc::HSI16 => { | 95 | ClockSrc::HSI16 => { |
| 96 | // Enable HSI16 | 96 | // Enable HSI16 |
| 97 | RCC.cr().write(|w| w.set_hsi16on(true)); | 97 | RCC.cr().write(|w| w.set_hsi16on(true)); |
| 98 | while !RCC.cr().read().hsi16rdyf() {} | 98 | while !RCC.cr().read().hsi16rdy() {} |
| 99 | 99 | ||
| 100 | (HSI_FREQ, Sw::HSI16) | 100 | (HSI_FREQ, Sw::HSI16) |
| 101 | } | 101 | } |
| @@ -117,7 +117,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 117 | PLLSource::HSI16 => { | 117 | PLLSource::HSI16 => { |
| 118 | // Enable HSI | 118 | // Enable HSI |
| 119 | RCC.cr().write(|w| w.set_hsi16on(true)); | 119 | RCC.cr().write(|w| w.set_hsi16on(true)); |
| 120 | while !RCC.cr().read().hsi16rdyf() {} | 120 | while !RCC.cr().read().hsi16rdy() {} |
| 121 | HSI_FREQ | 121 | HSI_FREQ |
| 122 | } | 122 | } |
| 123 | }; | 123 | }; |
| @@ -150,21 +150,17 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 150 | config.lse.map(|_| Default::default()), | 150 | config.lse.map(|_| Default::default()), |
| 151 | ); | 151 | ); |
| 152 | 152 | ||
| 153 | let wait_states = match config.voltage_scale { | 153 | let wait_states = match (config.voltage_scale, sys_clk.0) { |
| 154 | VoltageScale::RANGE1 => match sys_clk.0 { | 154 | (VoltageScale::RANGE1, ..=16_000_000) => 0, |
| 155 | ..=16_000_000 => 0, | 155 | (VoltageScale::RANGE2, ..=8_000_000) => 0, |
| 156 | _ => 1, | 156 | (VoltageScale::RANGE3, ..=4_200_000) => 0, |
| 157 | }, | 157 | _ => 1, |
| 158 | VoltageScale::RANGE2 => match sys_clk.0 { | ||
| 159 | ..=8_000_000 => 0, | ||
| 160 | _ => 1, | ||
| 161 | }, | ||
| 162 | VoltageScale::RANGE3 => 0, | ||
| 163 | _ => unreachable!(), | ||
| 164 | }; | 158 | }; |
| 165 | FLASH.acr().modify(|w| { | 159 | |
| 166 | w.set_latency(wait_states != 0); | 160 | #[cfg(stm32l1)] |
| 167 | }); | 161 | FLASH.acr().write(|w| w.set_acc64(true)); |
| 162 | FLASH.acr().modify(|w| w.set_prften(true)); | ||
| 163 | FLASH.acr().modify(|w| w.set_latency(wait_states != 0)); | ||
| 168 | 164 | ||
| 169 | RCC.cfgr().modify(|w| { | 165 | RCC.cfgr().modify(|w| { |
| 170 | w.set_sw(sw); | 166 | w.set_sw(sw); |
diff --git a/embassy-stm32/src/rcc/l1.rs b/embassy-stm32/src/rcc/l1.rs deleted file mode 100644 index 7c75b888d..000000000 --- a/embassy-stm32/src/rcc/l1.rs +++ /dev/null | |||
| @@ -1,198 +0,0 @@ | |||
| 1 | pub use crate::pac::rcc::vals::{ | ||
| 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}; | ||
| 5 | use crate::pac::{FLASH, RCC}; | ||
| 6 | use crate::rcc::{set_freqs, Clocks}; | ||
| 7 | use crate::time::Hertz; | ||
| 8 | |||
| 9 | /// HSI speed | ||
| 10 | pub const HSI_FREQ: Hertz = Hertz(16_000_000); | ||
| 11 | |||
| 12 | /// LSI speed | ||
| 13 | pub const LSI_FREQ: Hertz = Hertz(32_000); | ||
| 14 | |||
| 15 | /// System clock mux source | ||
| 16 | #[derive(Clone, Copy)] | ||
| 17 | pub enum ClockSrc { | ||
| 18 | MSI(MSIRange), | ||
| 19 | PLL(PLLSource, PLLMul, PLLDiv), | ||
| 20 | HSE(Hertz), | ||
| 21 | HSI, | ||
| 22 | } | ||
| 23 | |||
| 24 | /// PLL clock input source | ||
| 25 | #[derive(Clone, Copy)] | ||
| 26 | pub enum PLLSource { | ||
| 27 | HSI, | ||
| 28 | HSE(Hertz), | ||
| 29 | } | ||
| 30 | |||
| 31 | impl From<PLLSource> for Pllsrc { | ||
| 32 | fn from(val: PLLSource) -> Pllsrc { | ||
| 33 | match val { | ||
| 34 | PLLSource::HSI => Pllsrc::HSI, | ||
| 35 | PLLSource::HSE(_) => Pllsrc::HSE, | ||
| 36 | } | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | /// Clocks configutation | ||
| 41 | pub struct Config { | ||
| 42 | pub mux: ClockSrc, | ||
| 43 | pub ahb_pre: AHBPrescaler, | ||
| 44 | pub apb1_pre: APBPrescaler, | ||
| 45 | pub apb2_pre: APBPrescaler, | ||
| 46 | } | ||
| 47 | |||
| 48 | impl Default for Config { | ||
| 49 | #[inline] | ||
| 50 | fn default() -> Config { | ||
| 51 | Config { | ||
| 52 | mux: ClockSrc::MSI(MSIRange::RANGE5), | ||
| 53 | ahb_pre: AHBPrescaler::DIV1, | ||
| 54 | apb1_pre: APBPrescaler::DIV1, | ||
| 55 | apb2_pre: APBPrescaler::DIV1, | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | pub(crate) unsafe fn init(config: Config) { | ||
| 61 | let (sys_clk, sw) = match config.mux { | ||
| 62 | ClockSrc::MSI(range) => { | ||
| 63 | // Set MSI range | ||
| 64 | RCC.icscr().write(|w| w.set_msirange(range)); | ||
| 65 | |||
| 66 | // Enable MSI | ||
| 67 | RCC.cr().write(|w| w.set_msion(true)); | ||
| 68 | while !RCC.cr().read().msirdy() {} | ||
| 69 | |||
| 70 | let freq = 32_768 * (1 << (range as u8 + 1)); | ||
| 71 | (Hertz(freq), Sw::MSI) | ||
| 72 | } | ||
| 73 | ClockSrc::HSI => { | ||
| 74 | // Enable HSI | ||
| 75 | RCC.cr().write(|w| w.set_hsion(true)); | ||
| 76 | while !RCC.cr().read().hsirdy() {} | ||
| 77 | |||
| 78 | (HSI_FREQ, Sw::HSI) | ||
| 79 | } | ||
| 80 | ClockSrc::HSE(freq) => { | ||
| 81 | // Enable HSE | ||
| 82 | RCC.cr().write(|w| w.set_hseon(true)); | ||
| 83 | while !RCC.cr().read().hserdy() {} | ||
| 84 | |||
| 85 | (freq, Sw::HSE) | ||
| 86 | } | ||
| 87 | ClockSrc::PLL(src, mul, div) => { | ||
| 88 | let freq = match src { | ||
| 89 | PLLSource::HSE(freq) => { | ||
| 90 | // Enable HSE | ||
| 91 | RCC.cr().write(|w| w.set_hseon(true)); | ||
| 92 | while !RCC.cr().read().hserdy() {} | ||
| 93 | freq | ||
| 94 | } | ||
| 95 | PLLSource::HSI => { | ||
| 96 | // Enable HSI | ||
| 97 | RCC.cr().write(|w| w.set_hsion(true)); | ||
| 98 | while !RCC.cr().read().hsirdy() {} | ||
| 99 | HSI_FREQ | ||
| 100 | } | ||
| 101 | }; | ||
| 102 | |||
| 103 | // Disable PLL | ||
| 104 | RCC.cr().modify(|w| w.set_pllon(false)); | ||
| 105 | while RCC.cr().read().pllrdy() {} | ||
| 106 | |||
| 107 | let freq = freq * mul / div; | ||
| 108 | |||
| 109 | assert!(freq <= Hertz(32_000_000)); | ||
| 110 | |||
| 111 | RCC.cfgr().write(move |w| { | ||
| 112 | w.set_pllmul(mul); | ||
| 113 | w.set_plldiv(div); | ||
| 114 | w.set_pllsrc(src.into()); | ||
| 115 | }); | ||
| 116 | |||
| 117 | // Enable PLL | ||
| 118 | RCC.cr().modify(|w| w.set_pllon(true)); | ||
| 119 | while !RCC.cr().read().pllrdy() {} | ||
| 120 | |||
| 121 | (freq, Sw::PLL) | ||
| 122 | } | ||
| 123 | }; | ||
| 124 | |||
| 125 | // Set flash 64-bit access, prefetch and wait states | ||
| 126 | if sys_clk >= Hertz(16_000_000) { | ||
| 127 | FLASH.acr().write(|w| w.set_acc64(true)); | ||
| 128 | FLASH.acr().modify(|w| w.set_prften(true)); | ||
| 129 | FLASH.acr().modify(|w| w.set_latency(true)); | ||
| 130 | } | ||
| 131 | |||
| 132 | RCC.cfgr().modify(|w| { | ||
| 133 | w.set_sw(sw); | ||
| 134 | w.set_hpre(config.ahb_pre); | ||
| 135 | w.set_ppre1(config.apb1_pre); | ||
| 136 | w.set_ppre2(config.apb2_pre); | ||
| 137 | }); | ||
| 138 | |||
| 139 | let ahb_freq = sys_clk / config.ahb_pre; | ||
| 140 | |||
| 141 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { | ||
| 142 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | ||
| 143 | pre => { | ||
| 144 | let freq = ahb_freq / pre; | ||
| 145 | (freq, freq * 2u32) | ||
| 146 | } | ||
| 147 | }; | ||
| 148 | |||
| 149 | let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { | ||
| 150 | APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | ||
| 151 | pre => { | ||
| 152 | let freq = ahb_freq / pre; | ||
| 153 | (freq, freq * 2u32) | ||
| 154 | } | ||
| 155 | }; | ||
| 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 | |||
| 190 | set_freqs(Clocks { | ||
| 191 | sys: sys_clk, | ||
| 192 | ahb1: ahb_freq, | ||
| 193 | apb1: apb1_freq, | ||
| 194 | apb2: apb2_freq, | ||
| 195 | apb1_tim: apb1_tim_freq, | ||
| 196 | apb2_tim: apb2_tim_freq, | ||
| 197 | }); | ||
| 198 | } | ||
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 52dc386b4..3d4de0e6e 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -19,8 +19,7 @@ pub use mco::*; | |||
| 19 | #[cfg_attr(rcc_g0, path = "g0.rs")] | 19 | #[cfg_attr(rcc_g0, path = "g0.rs")] |
| 20 | #[cfg_attr(rcc_g4, path = "g4.rs")] | 20 | #[cfg_attr(rcc_g4, path = "g4.rs")] |
| 21 | #[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")] | 21 | #[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")] |
| 22 | #[cfg_attr(rcc_l0, path = "l0.rs")] | 22 | #[cfg_attr(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")] |
| 23 | #[cfg_attr(rcc_l1, path = "l1.rs")] | ||
| 24 | #[cfg_attr(rcc_l4, path = "l4.rs")] | 23 | #[cfg_attr(rcc_l4, path = "l4.rs")] |
| 25 | #[cfg_attr(rcc_l5, path = "l5.rs")] | 24 | #[cfg_attr(rcc_l5, path = "l5.rs")] |
| 26 | #[cfg_attr(rcc_u5, path = "u5.rs")] | 25 | #[cfg_attr(rcc_u5, path = "u5.rs")] |
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index f2ba5f7fc..2bf500798 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs | |||
| @@ -332,7 +332,7 @@ pub fn config() -> Config { | |||
| 332 | use embassy_stm32::rcc::*; | 332 | use embassy_stm32::rcc::*; |
| 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::HSI16, |
| 336 | PLLMul::MUL4, | 336 | PLLMul::MUL4, |
| 337 | PLLDiv::DIV2, | 337 | PLLDiv::DIV2, |
| 338 | ); | 338 | ); |
