stm32/rcc: Modify only relevant CFGR bits and keep the settings previously done.

PLL settings remained intact because these bits are not writable when PLL is enabled,
but prescaler settings were overwritten by selecting PLL as sysclk (CFGR.SW[1:0]).
This commit is contained in:
Ralf 2022-05-11 20:56:57 +02:00
parent 1a216958ac
commit c90968bb70

View file

@ -111,8 +111,9 @@ pub(crate) unsafe fn init(config: Config) {
}); });
// Enable HSE // Enable HSE
// RM0316: "Bits 31:26 Reserved, must be kept at reset value."
if config.hse.is_some() { if config.hse.is_some() {
RCC.cr().write(|w| { RCC.cr().modify(|w| {
w.set_hsebyp(config.bypass_hse); w.set_hsebyp(config.bypass_hse);
// We turn on clock security to switch to HSI when HSE fails // We turn on clock security to switch to HSI when HSE fails
w.set_csson(true); w.set_csson(true);
@ -122,27 +123,30 @@ pub(crate) unsafe fn init(config: Config) {
} }
// Enable PLL // Enable PLL
// RM0316: "Reserved, must be kept at reset value."
if let Some(ref pll_config) = pll_config { if let Some(ref pll_config) = pll_config {
RCC.cfgr().write(|w| { RCC.cfgr().modify(|w| {
w.set_pllmul(pll_config.pll_mul); w.set_pllmul(pll_config.pll_mul);
w.set_pllsrc(pll_config.pll_src); w.set_pllsrc(pll_config.pll_src);
}); });
if let Some(pll_div) = pll_config.pll_div { if let Some(pll_div) = pll_config.pll_div {
RCC.cfgr2().write(|w| w.set_prediv(pll_div)); RCC.cfgr2().modify(|w| w.set_prediv(pll_div));
} }
RCC.cr().modify(|w| w.set_pllon(true)); RCC.cr().modify(|w| w.set_pllon(true));
while !RCC.cr().read().pllrdy() {} while !RCC.cr().read().pllrdy() {}
} }
// CFGR has been written before (PLL) don't overwrite these settings
if config.pll48 { if config.pll48 {
let usb_pre = get_usb_pre(&config, sysclk, pclk1, &pll_config); let usb_pre = get_usb_pre(&config, sysclk, pclk1, &pll_config);
RCC.cfgr().write(|w| { RCC.cfgr().modify(|w| {
w.set_usbpre(usb_pre); w.set_usbpre(usb_pre);
}); });
} }
// Set prescalers // Set prescalers
RCC.cfgr().write(|w| { // CFGR has been written before (PLL, PLL48) don't overwrite these settings
RCC.cfgr().modify(|w| {
w.set_ppre2(ppre2_bits); w.set_ppre2(ppre2_bits);
w.set_ppre1(ppre1_bits); w.set_ppre1(ppre1_bits);
w.set_hpre(hpre_bits); w.set_hpre(hpre_bits);
@ -153,7 +157,8 @@ pub(crate) unsafe fn init(config: Config) {
// 1 to 16 AHB cycles after write" // 1 to 16 AHB cycles after write"
cortex_m::asm::delay(16); cortex_m::asm::delay(16);
RCC.cfgr().write(|w| { // CFGR has been written before (PLL, PLL48, clock divider) don't overwrite these settings
RCC.cfgr().modify(|w| {
w.set_sw(match (pll_config, config.hse) { w.set_sw(match (pll_config, config.hse) {
(Some(_), _) => Sw::PLL, (Some(_), _) => Sw::PLL,
(None, Some(_)) => Sw::HSE, (None, Some(_)) => Sw::HSE,