From f4677469f9e9fc7bdc24577d9111636b4de2df46 Mon Sep 17 00:00:00 2001 From: Ralf Date: Wed, 11 May 2022 19:57:56 +0200 Subject: [PATCH 1/3] stm32/usart: Data length is including parity. To get e.g. 8E1 you need to choose 9 data bits --- embassy-stm32/src/usart/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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, From 1a216958ac121befa7da6912db307516d1ddcb07 Mon Sep 17 00:00:00 2001 From: Ralf Date: Wed, 11 May 2022 20:54:09 +0200 Subject: [PATCH 2/3] stm32/rcc: Set flash prefetch buffer and half cycle access according to AHB clock prescaler --- embassy-stm32/src/rcc/f3.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index ababc4f9..5a735144 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,6 +104,10 @@ pub(crate) unsafe fn init(config: Config) { } else { Latency::WS2 }); + if hpre_div != 1 { + w.set_hlfcya(false); + w.set_prftbe(true); + } }); // Enable HSE From c90968bb70e626c5d2c375befbbf19423f48ba5e Mon Sep 17 00:00:00 2001 From: Ralf Date: Wed, 11 May 2022 20:56:57 +0200 Subject: [PATCH 3/3] 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]). --- embassy-stm32/src/rcc/f3.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index 5a735144..c2aec04c 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs @@ -111,8 +111,9 @@ pub(crate) unsafe fn init(config: Config) { }); // 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); @@ -122,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); @@ -153,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,