diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index ababc4f9..c2aec04c 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs @@ -93,7 +93,10 @@ pub(crate) unsafe fn init(config: Config) { assert!(pclk2 <= 72_000_000); // Set latency based on HCLK frquency - FLASH.acr().write(|w| { + // RM0316: "The prefetch buffer must be kept on when using a prescaler + // different from 1 on the AHB clock.", "Half-cycle access cannot be + // used when there is a prescaler different from 1 on the AHB clock" + FLASH.acr().modify(|w| { w.set_latency(if hclk <= 24_000_000 { Latency::WS0 } else if hclk <= 48_000_000 { @@ -101,11 +104,16 @@ pub(crate) unsafe fn init(config: Config) { } else { Latency::WS2 }); + if hpre_div != 1 { + w.set_hlfcya(false); + w.set_prftbe(true); + } }); // Enable HSE + // RM0316: "Bits 31:26 Reserved, must be kept at reset value." if config.hse.is_some() { - RCC.cr().write(|w| { + RCC.cr().modify(|w| { w.set_hsebyp(config.bypass_hse); // We turn on clock security to switch to HSI when HSE fails w.set_csson(true); @@ -115,27 +123,30 @@ pub(crate) unsafe fn init(config: Config) { } // Enable PLL + // RM0316: "Reserved, must be kept at reset value." 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_pllsrc(pll_config.pll_src); }); 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)); while !RCC.cr().read().pllrdy() {} } + // CFGR has been written before (PLL) don't overwrite these settings if config.pll48 { let usb_pre = get_usb_pre(&config, sysclk, pclk1, &pll_config); - RCC.cfgr().write(|w| { + RCC.cfgr().modify(|w| { w.set_usbpre(usb_pre); }); } // 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_ppre1(ppre1_bits); w.set_hpre(hpre_bits); @@ -146,7 +157,8 @@ pub(crate) unsafe fn init(config: Config) { // 1 to 16 AHB cycles after write" 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) { (Some(_), _) => Sw::PLL, (None, Some(_)) => Sw::HSE, diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 6feecd18..47268011 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -219,7 +219,11 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { w.set_ue(true); w.set_te(true); w.set_re(true); - w.set_m0(vals::M0::BIT8); + w.set_m0(if config.parity != Parity::ParityNone { + vals::M0::BIT9 + } else { + vals::M0::BIT8 + }); w.set_pce(config.parity != Parity::ParityNone); w.set_ps(match config.parity { Parity::ParityOdd => vals::Ps::ODD,