Merge pull request #1468 from rmja/assume-noise-free

Add assume_noise_free to usart configuration
This commit is contained in:
Dario Nieuwenhuis 2023-05-27 00:23:56 +02:00 committed by GitHub
commit bea42a78a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -120,6 +120,12 @@ pub struct Config {
/// read will abort, the error reported and cleared /// read will abort, the error reported and cleared
/// if false, the error is ignored and cleared /// if false, the error is ignored and cleared
pub detect_previous_overrun: bool, 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 { impl Default for Config {
@ -131,6 +137,8 @@ impl Default for Config {
parity: Parity::ParityNone, parity: Parity::ParityNone,
// historical behavior // historical behavior
detect_previous_overrun: false, 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))] #[cfg(not(usart_v1))]
let mut over8 = false; let mut over8 = false;
let mut found = false; let mut found = None;
for &(presc, _presc_val) in &DIVS { for &(presc, _presc_val) in &DIVS {
let denom = (config.baudrate * presc as u32) as u64; let denom = (config.baudrate * presc as u32) as u64;
let div = (pclk_freq.0 as u64 * mul + (denom / 2)) / denom; 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 { if div < brr_min {
#[cfg(not(usart_v1))] #[cfg(not(usart_v1))]
@ -844,24 +858,36 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx:
#[cfg(usart_v4)] #[cfg(usart_v4)]
r.presc().write(|w| w.set_prescaler(_presc_val)); r.presc().write(|w| w.set_prescaler(_presc_val));
} }
found = true; found = Some(div);
break; break;
} }
panic!("USART: baudrate too high"); panic!("USART: baudrate too high");
} }
if div < brr_max { if div < brr_max {
let div = div as u32;
unsafe { unsafe {
r.brr().write_value(regs::Brr(div as u32)); r.brr().write_value(regs::Brr(div));
#[cfg(usart_v4)] #[cfg(usart_v4)]
r.presc().write(|w| w.set_prescaler(_presc_val)); r.presc().write(|w| w.set_prescaler(_presc_val));
} }
found = true; found = Some(div);
break; 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 { unsafe {
r.cr2().write(|w| { 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))] #[cfg(not(usart_v1))]
w.set_over8(vals::Over8(over8 as _)); w.set_over8(vals::Over8(over8 as _));
}); });
#[cfg(not(usart_v1))]
r.cr3().modify(|w| {
w.set_onebit(config.assume_noise_free);
});
} }
} }