767: Stm32 fixes r=lulf a=jr-oss

Using embassy on STM32 Discovery board showed problems with
- USART with parity
- Clock settings (CFGR) when using PLL and prescaler
- Flash ACR settings

This PR attempts to fix these


Co-authored-by: Ralf <jr-oss@gmx.net>
This commit is contained in:
bors[bot] 2022-05-12 07:15:53 +00:00 committed by GitHub
commit 3f9fdc0dd3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 8 deletions

View file

@ -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,

View file

@ -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,