diff options
| author | xoviat <[email protected]> | 2023-07-23 17:01:34 -0500 |
|---|---|---|
| committer | xoviat <[email protected]> | 2023-07-23 17:01:34 -0500 |
| commit | bd60f003e0ef367e1678d549973ba9b4ae753652 (patch) | |
| tree | 16488e78c9380e082833546dd0b100e2e29a0170 | |
| parent | 4db63677f6e56c52ea3d432542513967f5d93c69 (diff) | |
stm32/rcc: move rcc logic from ipcc
| -rw-r--r-- | embassy-stm32/src/ipcc.rs | 56 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/wb.rs | 326 |
3 files changed, 287 insertions, 103 deletions
diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index a24cba9f0..e100ca5cc 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs | |||
| @@ -265,63 +265,9 @@ pub(crate) mod sealed { | |||
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | fn _configure_pwr() { | 267 | fn _configure_pwr() { |
| 268 | // TODO: move this to RCC | 268 | // TODO: move the rest of this to rcc |
| 269 | |||
| 270 | let pwr = crate::pac::PWR; | ||
| 271 | let rcc = crate::pac::RCC; | 269 | let rcc = crate::pac::RCC; |
| 272 | 270 | ||
| 273 | rcc.cfgr().modify(|w| w.set_stopwuck(true)); | ||
| 274 | |||
| 275 | pwr.cr1().modify(|w| w.set_dbp(true)); | ||
| 276 | pwr.cr1().modify(|w| w.set_dbp(true)); | ||
| 277 | |||
| 278 | // configure LSE | ||
| 279 | rcc.bdcr().modify(|w| w.set_lseon(true)); | ||
| 280 | |||
| 281 | // select system clock source = PLL | ||
| 282 | // set PLL coefficients | ||
| 283 | // m: 2, | ||
| 284 | // n: 12, | ||
| 285 | // r: 3, | ||
| 286 | // q: 4, | ||
| 287 | // p: 3, | ||
| 288 | let src_bits = 0b11; | ||
| 289 | let pllp = (3 - 1) & 0b11111; | ||
| 290 | let pllq = (4 - 1) & 0b111; | ||
| 291 | let pllr = (3 - 1) & 0b111; | ||
| 292 | let plln = 12 & 0b1111111; | ||
| 293 | let pllm = (2 - 1) & 0b111; | ||
| 294 | rcc.pllcfgr().modify(|w| { | ||
| 295 | w.set_pllsrc(src_bits); | ||
| 296 | w.set_pllm(pllm); | ||
| 297 | w.set_plln(plln); | ||
| 298 | w.set_pllr(pllr); | ||
| 299 | w.set_pllp(pllp); | ||
| 300 | w.set_pllpen(true); | ||
| 301 | w.set_pllq(pllq); | ||
| 302 | w.set_pllqen(true); | ||
| 303 | }); | ||
| 304 | // enable PLL | ||
| 305 | rcc.cr().modify(|w| w.set_pllon(true)); | ||
| 306 | rcc.cr().write(|w| w.set_hsion(false)); | ||
| 307 | // while !rcc.cr().read().pllrdy() {} | ||
| 308 | |||
| 309 | // configure SYSCLK mux to use PLL clocl | ||
| 310 | rcc.cfgr().modify(|w| w.set_sw(0b11)); | ||
| 311 | |||
| 312 | // configure CPU1 & CPU2 dividers | ||
| 313 | rcc.cfgr().modify(|w| w.set_hpre(0)); // not divided | ||
| 314 | rcc.extcfgr().modify(|w| { | ||
| 315 | w.set_c2hpre(0b1000); // div2 | ||
| 316 | w.set_shdhpre(0); // not divided | ||
| 317 | }); | ||
| 318 | |||
| 319 | // apply APB1 / APB2 values | ||
| 320 | rcc.cfgr().modify(|w| { | ||
| 321 | w.set_ppre1(0b000); // not divided | ||
| 322 | w.set_ppre2(0b000); // not divided | ||
| 323 | }); | ||
| 324 | |||
| 325 | // TODO: required | 271 | // TODO: required |
| 326 | // set RF wake-up clock = LSE | 272 | // set RF wake-up clock = LSE |
| 327 | rcc.csr().modify(|w| w.set_rfwkpsel(0b01)); | 273 | rcc.csr().modify(|w| w.set_rfwkpsel(0b01)); |
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 886fc0b93..4ae65d3e6 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -78,6 +78,14 @@ pub struct Clocks { | |||
| 78 | /// The existence of this value indicates that the clock configuration can no longer be changed | 78 | /// The existence of this value indicates that the clock configuration can no longer be changed |
| 79 | static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit(); | 79 | static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit(); |
| 80 | 80 | ||
| 81 | #[cfg(stm32wb)] | ||
| 82 | /// RCC initialization function | ||
| 83 | pub(crate) unsafe fn init(config: Config) { | ||
| 84 | set_freqs(compute_clocks(&config)); | ||
| 85 | |||
| 86 | configure_clocks(&config); | ||
| 87 | } | ||
| 88 | |||
| 81 | /// Sets the clock frequencies | 89 | /// Sets the clock frequencies |
| 82 | /// | 90 | /// |
| 83 | /// Safety: Sets a mutable global. | 91 | /// Safety: Sets a mutable global. |
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index e6123821a..41f602c02 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | use crate::pac::RCC; | 1 | use crate::rcc::Clocks; |
| 2 | use crate::rcc::{set_freqs, Clocks}; | 2 | use crate::time::{khz, mhz, Hertz}; |
| 3 | use crate::time::Hertz; | ||
| 4 | 3 | ||
| 5 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, | 4 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, |
| 6 | /// and with the addition of the init function to configure a system clock. | 5 | /// and with the addition of the init function to configure a system clock. |
| @@ -13,11 +12,94 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); | |||
| 13 | /// LSI speed | 12 | /// LSI speed |
| 14 | pub const LSI_FREQ: Hertz = Hertz(32_000); | 13 | pub const LSI_FREQ: Hertz = Hertz(32_000); |
| 15 | 14 | ||
| 16 | /// System clock mux source | ||
| 17 | #[derive(Clone, Copy)] | 15 | #[derive(Clone, Copy)] |
| 18 | pub enum ClockSrc { | 16 | pub enum HsePrescaler { |
| 19 | HSE(Hertz), | 17 | NotDivided, |
| 20 | HSI16, | 18 | Div2, |
| 19 | } | ||
| 20 | |||
| 21 | impl From<HsePrescaler> for bool { | ||
| 22 | fn from(value: HsePrescaler) -> Self { | ||
| 23 | match value { | ||
| 24 | HsePrescaler::NotDivided => false, | ||
| 25 | HsePrescaler::Div2 => true, | ||
| 26 | } | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | pub struct Hse { | ||
| 31 | pub prediv: HsePrescaler, | ||
| 32 | |||
| 33 | pub frequency: Hertz, | ||
| 34 | } | ||
| 35 | |||
| 36 | /// System clock mux source | ||
| 37 | #[derive(Clone, Copy, PartialEq)] | ||
| 38 | pub enum Sysclk { | ||
| 39 | /// MSI selected as sysclk | ||
| 40 | MSI, | ||
| 41 | /// HSI selected as sysclk | ||
| 42 | HSI, | ||
| 43 | /// HSE selected as sysclk | ||
| 44 | HSE, | ||
| 45 | /// PLL selected as sysclk | ||
| 46 | Pll, | ||
| 47 | } | ||
| 48 | |||
| 49 | impl From<Sysclk> for u8 { | ||
| 50 | fn from(value: Sysclk) -> Self { | ||
| 51 | match value { | ||
| 52 | Sysclk::MSI => 0b00, | ||
| 53 | Sysclk::HSI => 0b01, | ||
| 54 | Sysclk::HSE => 0b10, | ||
| 55 | Sysclk::Pll => 0b11, | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | #[derive(Clone, Copy, PartialEq)] | ||
| 61 | pub enum PllSource { | ||
| 62 | Hsi, | ||
| 63 | Msi, | ||
| 64 | Hse, | ||
| 65 | } | ||
| 66 | |||
| 67 | impl From<PllSource> for u8 { | ||
| 68 | fn from(value: PllSource) -> Self { | ||
| 69 | match value { | ||
| 70 | PllSource::Msi => 0b01, | ||
| 71 | PllSource::Hsi => 0b10, | ||
| 72 | PllSource::Hse => 0b11, | ||
| 73 | } | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | pub enum Pll48Source { | ||
| 78 | PllSai, | ||
| 79 | Pll, | ||
| 80 | Msi, | ||
| 81 | Hsi48, | ||
| 82 | } | ||
| 83 | |||
| 84 | pub struct PllMux { | ||
| 85 | /// Source clock selection. | ||
| 86 | pub source: PllSource, | ||
| 87 | |||
| 88 | /// PLL pre-divider (DIVM). Must be between 1 and 63. | ||
| 89 | pub prediv: u8, | ||
| 90 | } | ||
| 91 | |||
| 92 | pub struct Pll { | ||
| 93 | /// PLL multiplication factor. Must be between 4 and 512. | ||
| 94 | pub mul: u16, | ||
| 95 | |||
| 96 | /// PLL P division factor. If None, PLL P output is disabled. Must be between 1 and 128. | ||
| 97 | /// On PLL1, it must be even (in particular, it cannot be 1.) | ||
| 98 | pub divp: Option<u16>, | ||
| 99 | /// PLL Q division factor. If None, PLL Q output is disabled. Must be between 1 and 128. | ||
| 100 | pub divq: Option<u16>, | ||
| 101 | /// PLL R division factor. If None, PLL R output is disabled. Must be between 1 and 128. | ||
| 102 | pub divr: Option<u16>, | ||
| 21 | } | 103 | } |
| 22 | 104 | ||
| 23 | /// AHB prescaler | 105 | /// AHB prescaler |
| @@ -84,8 +166,18 @@ impl Into<u8> for AHBPrescaler { | |||
| 84 | 166 | ||
| 85 | /// Clocks configutation | 167 | /// Clocks configutation |
| 86 | pub struct Config { | 168 | pub struct Config { |
| 87 | pub mux: ClockSrc, | 169 | pub hse: Option<Hse>, |
| 88 | pub ahb_pre: AHBPrescaler, | 170 | pub lse: Option<Hertz>, |
| 171 | pub sys: Sysclk, | ||
| 172 | pub mux: Option<PllMux>, | ||
| 173 | pub pll48: Option<Pll48Source>, | ||
| 174 | |||
| 175 | pub pll: Option<Pll>, | ||
| 176 | pub pllsai: Option<Pll>, | ||
| 177 | |||
| 178 | pub ahb1_pre: AHBPrescaler, | ||
| 179 | pub ahb2_pre: AHBPrescaler, | ||
| 180 | pub ahb3_pre: AHBPrescaler, | ||
| 89 | pub apb1_pre: APBPrescaler, | 181 | pub apb1_pre: APBPrescaler, |
| 90 | pub apb2_pre: APBPrescaler, | 182 | pub apb2_pre: APBPrescaler, |
| 91 | } | 183 | } |
| @@ -94,76 +186,214 @@ impl Default for Config { | |||
| 94 | #[inline] | 186 | #[inline] |
| 95 | fn default() -> Config { | 187 | fn default() -> Config { |
| 96 | Config { | 188 | Config { |
| 97 | mux: ClockSrc::HSI16, | 189 | hse: Some(Hse { |
| 98 | ahb_pre: AHBPrescaler::NotDivided, | 190 | frequency: mhz(32), |
| 191 | prediv: HsePrescaler::NotDivided, | ||
| 192 | }), | ||
| 193 | lse: Some(khz(32)), | ||
| 194 | sys: Sysclk::HSI, | ||
| 195 | mux: Some(PllMux { | ||
| 196 | source: PllSource::Hse, | ||
| 197 | prediv: 2, | ||
| 198 | }), | ||
| 199 | pll48: None, | ||
| 200 | |||
| 201 | pll: Some(Pll { | ||
| 202 | mul: 12, | ||
| 203 | divp: Some(3), | ||
| 204 | divq: Some(4), | ||
| 205 | divr: Some(3), | ||
| 206 | }), | ||
| 207 | pllsai: None, | ||
| 208 | |||
| 209 | ahb1_pre: AHBPrescaler::NotDivided, | ||
| 210 | ahb2_pre: AHBPrescaler::Div2, | ||
| 211 | ahb3_pre: AHBPrescaler::NotDivided, | ||
| 99 | apb1_pre: APBPrescaler::NotDivided, | 212 | apb1_pre: APBPrescaler::NotDivided, |
| 100 | apb2_pre: APBPrescaler::NotDivided, | 213 | apb2_pre: APBPrescaler::NotDivided, |
| 101 | } | 214 | } |
| 102 | } | 215 | } |
| 103 | } | 216 | } |
| 104 | 217 | ||
| 105 | pub(crate) unsafe fn init(config: Config) { | 218 | pub(crate) fn compute_clocks(config: &Config) -> Clocks { |
| 106 | let (sys_clk, sw) = match config.mux { | 219 | let hse_clk = config.hse.as_ref().map(|hse| match hse.prediv { |
| 107 | ClockSrc::HSI16 => { | 220 | HsePrescaler::NotDivided => hse.frequency, |
| 108 | // Enable HSI16 | 221 | HsePrescaler::Div2 => hse.frequency / 2u32, |
| 109 | RCC.cr().write(|w| w.set_hsion(true)); | 222 | }); |
| 110 | while !RCC.cr().read().hsirdy() {} | 223 | |
| 224 | let mux_clk = config.mux.as_ref().map(|pll_mux| { | ||
| 225 | (match pll_mux.source { | ||
| 226 | PllSource::Hse => hse_clk.unwrap(), | ||
| 227 | PllSource::Hsi => HSI_FREQ, | ||
| 228 | _ => unreachable!(), | ||
| 229 | } / pll_mux.prediv) | ||
| 230 | }); | ||
| 111 | 231 | ||
| 112 | (HSI_FREQ.0, 0x01) | 232 | let (pll_r, _pll_q, _pll_p) = match &config.pll { |
| 233 | Some(pll) => { | ||
| 234 | let pll_vco = mux_clk.unwrap() * pll.mul as u32; | ||
| 235 | |||
| 236 | ( | ||
| 237 | pll.divr.map(|divr| pll_vco / divr), | ||
| 238 | pll.divq.map(|divq| pll_vco / divq), | ||
| 239 | pll.divp.map(|divp| pll_vco / divp), | ||
| 240 | ) | ||
| 113 | } | 241 | } |
| 114 | ClockSrc::HSE(freq) => { | 242 | None => (None, None, None), |
| 115 | // Enable HSE | 243 | }; |
| 116 | RCC.cr().write(|w| w.set_hseon(true)); | ||
| 117 | while !RCC.cr().read().hserdy() {} | ||
| 118 | 244 | ||
| 119 | (freq.0, 0x02) | 245 | let sys_clk = match config.sys { |
| 246 | Sysclk::HSE => hse_clk.unwrap(), | ||
| 247 | Sysclk::HSI => HSI_FREQ, | ||
| 248 | Sysclk::Pll => pll_r.unwrap(), | ||
| 249 | _ => unreachable!(), | ||
| 250 | }; | ||
| 251 | |||
| 252 | let ahb1_clk = match config.ahb1_pre { | ||
| 253 | AHBPrescaler::NotDivided => sys_clk, | ||
| 254 | pre => { | ||
| 255 | let pre: u8 = pre.into(); | ||
| 256 | let pre = 1u32 << (pre as u32 - 7); | ||
| 257 | sys_clk / pre | ||
| 120 | } | 258 | } |
| 121 | }; | 259 | }; |
| 122 | 260 | ||
| 123 | RCC.cfgr().modify(|w| { | 261 | let ahb2_clk = match config.ahb2_pre { |
| 124 | w.set_sw(sw.into()); | 262 | AHBPrescaler::NotDivided => sys_clk, |
| 125 | w.set_hpre(config.ahb_pre.into()); | 263 | pre => { |
| 126 | w.set_ppre1(config.apb1_pre.into()); | 264 | let pre: u8 = pre.into(); |
| 127 | w.set_ppre2(config.apb2_pre.into()); | 265 | let pre = 1u32 << (pre as u32 - 7); |
| 128 | }); | 266 | sys_clk / pre |
| 267 | } | ||
| 268 | }; | ||
| 129 | 269 | ||
| 130 | let ahb_freq: u32 = match config.ahb_pre { | 270 | let ahb3_clk = match config.ahb3_pre { |
| 131 | AHBPrescaler::NotDivided => sys_clk, | 271 | AHBPrescaler::NotDivided => sys_clk, |
| 132 | pre => { | 272 | pre => { |
| 133 | let pre: u8 = pre.into(); | 273 | let pre: u8 = pre.into(); |
| 134 | let pre = 1 << (pre as u32 - 7); | 274 | let pre = 1u32 << (pre as u32 - 7); |
| 135 | sys_clk / pre | 275 | sys_clk / pre |
| 136 | } | 276 | } |
| 137 | }; | 277 | }; |
| 138 | 278 | ||
| 139 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { | 279 | let (apb1_clk, apb1_tim_clk) = match config.apb1_pre { |
| 140 | APBPrescaler::NotDivided => (ahb_freq, ahb_freq), | 280 | APBPrescaler::NotDivided => (ahb1_clk, ahb1_clk), |
| 141 | pre => { | 281 | pre => { |
| 142 | let pre: u8 = pre.into(); | 282 | let pre: u8 = pre.into(); |
| 143 | let pre: u8 = 1 << (pre - 3); | 283 | let pre: u8 = 1 << (pre - 3); |
| 144 | let freq = ahb_freq / pre as u32; | 284 | let freq = ahb1_clk / pre as u32; |
| 145 | (freq, freq * 2) | 285 | (freq, freq * 2u32) |
| 146 | } | 286 | } |
| 147 | }; | 287 | }; |
| 148 | 288 | ||
| 149 | let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { | 289 | let (apb2_clk, apb2_tim_clk) = match config.apb2_pre { |
| 150 | APBPrescaler::NotDivided => (ahb_freq, ahb_freq), | 290 | APBPrescaler::NotDivided => (ahb1_clk, ahb1_clk), |
| 151 | pre => { | 291 | pre => { |
| 152 | let pre: u8 = pre.into(); | 292 | let pre: u8 = pre.into(); |
| 153 | let pre: u8 = 1 << (pre - 3); | 293 | let pre: u8 = 1 << (pre - 3); |
| 154 | let freq = ahb_freq / pre as u32; | 294 | let freq = ahb1_clk / pre as u32; |
| 155 | (freq, freq * 2) | 295 | (freq, freq * 2u32) |
| 156 | } | 296 | } |
| 157 | }; | 297 | }; |
| 158 | 298 | ||
| 159 | set_freqs(Clocks { | 299 | Clocks { |
| 160 | sys: Hertz(sys_clk), | 300 | sys: sys_clk, |
| 161 | ahb1: Hertz(ahb_freq), | 301 | ahb1: ahb1_clk, |
| 162 | ahb2: Hertz(ahb_freq), | 302 | ahb2: ahb2_clk, |
| 163 | ahb3: Hertz(ahb_freq), | 303 | ahb3: ahb3_clk, |
| 164 | apb1: Hertz(apb1_freq), | 304 | apb1: apb1_clk, |
| 165 | apb2: Hertz(apb2_freq), | 305 | apb2: apb2_clk, |
| 166 | apb1_tim: Hertz(apb1_tim_freq), | 306 | apb1_tim: apb1_tim_clk, |
| 167 | apb2_tim: Hertz(apb2_tim_freq), | 307 | apb2_tim: apb2_tim_clk, |
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 311 | pub(crate) fn configure_clocks(config: &Config) { | ||
| 312 | let pwr = crate::pac::PWR; | ||
| 313 | let rcc = crate::pac::RCC; | ||
| 314 | |||
| 315 | let needs_hsi = if let Some(pll_mux) = &config.mux { | ||
| 316 | pll_mux.source == PllSource::Hsi | ||
| 317 | } else { | ||
| 318 | false | ||
| 319 | }; | ||
| 320 | |||
| 321 | if needs_hsi || config.sys == Sysclk::HSI { | ||
| 322 | rcc.cr().modify(|w| { | ||
| 323 | w.set_hsion(true); | ||
| 324 | }); | ||
| 325 | |||
| 326 | while !rcc.cr().read().hsirdy() {} | ||
| 327 | } | ||
| 328 | |||
| 329 | match &config.lse { | ||
| 330 | Some(_) => { | ||
| 331 | rcc.cfgr().modify(|w| w.set_stopwuck(true)); | ||
| 332 | |||
| 333 | pwr.cr1().modify(|w| w.set_dbp(true)); | ||
| 334 | pwr.cr1().modify(|w| w.set_dbp(true)); | ||
| 335 | |||
| 336 | rcc.bdcr().modify(|w| w.set_lseon(true)); | ||
| 337 | } | ||
| 338 | _ => {} | ||
| 339 | } | ||
| 340 | |||
| 341 | match &config.hse { | ||
| 342 | Some(hse) => { | ||
| 343 | rcc.cr().modify(|w| { | ||
| 344 | w.set_hsepre(hse.prediv.into()); | ||
| 345 | w.set_hseon(true); | ||
| 346 | }); | ||
| 347 | |||
| 348 | while !rcc.cr().read().hserdy() {} | ||
| 349 | } | ||
| 350 | _ => {} | ||
| 351 | } | ||
| 352 | |||
| 353 | match &config.mux { | ||
| 354 | Some(pll_mux) => { | ||
| 355 | rcc.pllcfgr().modify(|w| { | ||
| 356 | w.set_pllm(pll_mux.prediv); | ||
| 357 | w.set_pllsrc(pll_mux.source.into()); | ||
| 358 | }); | ||
| 359 | } | ||
| 360 | _ => {} | ||
| 361 | }; | ||
| 362 | |||
| 363 | match &config.pll { | ||
| 364 | Some(pll) => { | ||
| 365 | rcc.pllcfgr().modify(|w| { | ||
| 366 | w.set_plln((pll.mul - 1) as u8); | ||
| 367 | pll.divp.map(|divp| { | ||
| 368 | w.set_pllpen(true); | ||
| 369 | w.set_pllp((divp - 1) as u8) | ||
| 370 | }); | ||
| 371 | pll.divq.map(|divq| { | ||
| 372 | w.set_pllqen(true); | ||
| 373 | w.set_pllq((divq - 1) as u8) | ||
| 374 | }); | ||
| 375 | pll.divr.map(|divr| w.set_pllr((divr - 1) as u8)); | ||
| 376 | }); | ||
| 377 | |||
| 378 | rcc.cr().modify(|w| w.set_pllon(true)); | ||
| 379 | |||
| 380 | while !rcc.cr().read().pllrdy() {} | ||
| 381 | } | ||
| 382 | _ => {} | ||
| 383 | } | ||
| 384 | |||
| 385 | rcc.cfgr().modify(|w| { | ||
| 386 | w.set_sw(config.sys.into()); | ||
| 387 | w.set_hpre(config.ahb1_pre.into()); | ||
| 388 | w.set_ppre1(config.apb1_pre.into()); | ||
| 389 | w.set_ppre2(config.apb2_pre.into()); | ||
| 390 | |||
| 391 | w.set_ppre1(config.apb1_pre.into()); | ||
| 392 | w.set_ppre2(config.apb2_pre.into()); | ||
| 393 | }); | ||
| 394 | |||
| 395 | rcc.extcfgr().modify(|w| { | ||
| 396 | w.set_c2hpre(config.ahb2_pre.into()); | ||
| 397 | w.set_shdhpre(config.ahb3_pre.into()); | ||
| 168 | }); | 398 | }); |
| 169 | } | 399 | } |
