diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 0f3e9412..061c859a 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -120,6 +120,12 @@ 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. + #[cfg(not(usart_v1))] + pub assume_noise_free: bool, } impl Default for Config { @@ -131,6 +137,8 @@ impl Default for Config { parity: Parity::ParityNone, // historical behavior detect_previous_overrun: false, + #[cfg(not(usart_v1))] + assume_noise_free: false, } } } @@ -828,11 +836,17 @@ 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; - 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))] @@ -844,24 +858,36 @@ 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"); + + #[cfg(not(usart_v1))] + let oversampling = if over8 { "8 bit" } else { "16 bit" }; + #[cfg(usart_v1)] + let oversampling = "default"; + trace!( + "Using {} oversampling, desired baudrate: {}, actual baudrate: {}", + oversampling, + config.baudrate, + pclk_freq.0 / div + ); unsafe { r.cr2().write(|w| { @@ -895,6 +921,11 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: #[cfg(not(usart_v1))] w.set_over8(vals::Over8(over8 as _)); }); + + #[cfg(not(usart_v1))] + r.cr3().modify(|w| { + w.set_onebit(config.assume_noise_free); + }); } }