From cd6256a924c58ffb645b32f26d60168ca08d2d24 Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Fri, 19 May 2023 15:22:32 +0200 Subject: [PATCH 1/5] Add assume_noise_free to usart configuration Effectively setting cr3.onebit --- embassy-stm32/src/usart/mod.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 0f3e9412e..cacbced2c 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -120,6 +120,11 @@ pub struct Config { /// read will abort, the error reported and cleared /// if false, the error is ignored and cleared pub detect_previous_overrun: bool, + + /// Set this to true if the line is considered noise free. + /// This will increase the receivers tolerance to clock deviations, + /// but will effectively disable noise detection. + pub assume_noise_free: bool, } impl Default for Config { @@ -131,6 +136,7 @@ impl Default for Config { parity: Parity::ParityNone, // historical behavior detect_previous_overrun: false, + assume_noise_free: false, } } } @@ -832,7 +838,13 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: for &(presc, _presc_val) in &DIVS { let denom = (config.baudrate * presc as u32) as u64; let div = (pclk_freq.0 as u64 * mul + (denom / 2)) / denom; - trace!("USART: presc={} div={:08x}", presc, div); + trace!( + "USART: presc={}, div=0x{:08x} (mantissa = {}, fraction = {})", + presc, + div, + div >> 4, + div & 0x0F + ); if div < brr_min { #[cfg(not(usart_v1))] @@ -863,6 +875,14 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: assert!(found, "USART: baudrate too low"); + let brr = unsafe { r.brr().read().brr() as u32 }; + trace!( + "Using {}, desired baudrate: {}, actual baudrate: {}", + if over8 { "OVER8" } else { "OVER16" }, + config.baudrate, + pclk_freq.0 / brr + ); + unsafe { r.cr2().write(|w| { w.set_stop(match config.stop_bits { @@ -895,6 +915,10 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: #[cfg(not(usart_v1))] w.set_over8(vals::Over8(over8 as _)); }); + + r.cr3().modify(|w| { + w.set_onebit(config.assume_noise_free); + }); } } From 387a4fcb8ec1f18b0a40cb8b0d758084814d943b Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Fri, 19 May 2023 16:20:12 +0200 Subject: [PATCH 2/5] Exclude usart_v1 --- embassy-stm32/src/usart/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index cacbced2c..dd20109f1 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -124,6 +124,7 @@ pub struct Config { /// Set this to true if the line is considered noise free. /// This will increase the receivers tolerance to clock deviations, /// but will effectively disable noise detection. + #[cfg(not(usart_v1))] pub assume_noise_free: bool, } @@ -136,6 +137,7 @@ impl Default for Config { parity: Parity::ParityNone, // historical behavior detect_previous_overrun: false, + #[cfg(not(usart_v1))] assume_noise_free: false, } } @@ -917,6 +919,7 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: }); r.cr3().modify(|w| { + #[cfg(not(usart_v1))] w.set_onebit(config.assume_noise_free); }); } From c5bf36eebf663419200fcd61f3f4f5884f65008d Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Thu, 25 May 2023 17:56:52 +0200 Subject: [PATCH 3/5] Fix oversampling message for usart v1 --- embassy-stm32/src/usart/mod.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index dd20109f1..4488bd77b 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -878,9 +878,13 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: assert!(found, "USART: baudrate too low"); let brr = unsafe { r.brr().read().brr() as u32 }; + #[cfg(not(usart_v1))] + let oversampling = if over8 { "8 bit" } else { "16 bit" }; + #[cfg(usart_v1)] + let oversampling = "default"; trace!( - "Using {}, desired baudrate: {}, actual baudrate: {}", - if over8 { "OVER8" } else { "OVER16" }, + "Using {} oversampling, desired baudrate: {}, actual baudrate: {}", + oversampling, config.baudrate, pclk_freq.0 / brr ); From f616b2215912dca6fd76523d390d0602dfa27bcd Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Thu, 25 May 2023 18:16:46 +0200 Subject: [PATCH 4/5] Fix yet another v1 error --- embassy-stm32/src/usart/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 4488bd77b..565416c72 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -922,8 +922,8 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: w.set_over8(vals::Over8(over8 as _)); }); + #[cfg(not(usart_v1))] r.cr3().modify(|w| { - #[cfg(not(usart_v1))] w.set_onebit(config.assume_noise_free); }); } From cb5df138d6048878a4311ecec63a632c7e20e34a Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Fri, 26 May 2023 23:48:49 +0200 Subject: [PATCH 5/5] Use found divider instead of re-reading brr --- embassy-stm32/src/usart/mod.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 565416c72..061c859a8 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -836,7 +836,7 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: #[cfg(not(usart_v1))] let mut over8 = false; - let mut found = false; + let mut found = None; for &(presc, _presc_val) in &DIVS { let denom = (config.baudrate * presc as u32) as u64; let div = (pclk_freq.0 as u64 * mul + (denom / 2)) / denom; @@ -858,26 +858,26 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: #[cfg(usart_v4)] r.presc().write(|w| w.set_prescaler(_presc_val)); } - found = true; + found = Some(div); break; } panic!("USART: baudrate too high"); } if div < brr_max { + let div = div as u32; unsafe { - r.brr().write_value(regs::Brr(div as u32)); + r.brr().write_value(regs::Brr(div)); #[cfg(usart_v4)] r.presc().write(|w| w.set_prescaler(_presc_val)); } - found = true; + found = Some(div); break; } } - assert!(found, "USART: baudrate too low"); + let div = found.expect("USART: baudrate too low"); - let brr = unsafe { r.brr().read().brr() as u32 }; #[cfg(not(usart_v1))] let oversampling = if over8 { "8 bit" } else { "16 bit" }; #[cfg(usart_v1)] @@ -886,7 +886,7 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: "Using {} oversampling, desired baudrate: {}, actual baudrate: {}", oversampling, config.baudrate, - pclk_freq.0 / brr + pclk_freq.0 / div ); unsafe {