From 1e23b8114bb1f4b9e092bc50b3cfe4bd2f7ebdb6 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Sun, 6 Apr 2025 21:13:49 -0500 Subject: mspm0: add uart tests This also fixes a bug in the uart clock calculation where it could select an oversampling faster than what the hardware is providing. --- embassy-mspm0/src/uart.rs | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'embassy-mspm0/src/uart.rs') diff --git a/embassy-mspm0/src/uart.rs b/embassy-mspm0/src/uart.rs index 45094a000..bc1d2e343 100644 --- a/embassy-mspm0/src/uart.rs +++ b/embassy-mspm0/src/uart.rs @@ -869,7 +869,7 @@ fn set_baudrate_inner(regs: Regs, clock: u32, baudrate: u32) -> Result<(), Confi // maximum speed is limited to UARTclk/16." // // Based on these requirements, prioritize higher oversampling first to increase tolerance to clock - // deviation. If no valid BRD valud can be found satisifying the highest sample rate, then reduce + // deviation. If no valid BRD value can be found satisifying the highest sample rate, then reduce // sample rate until valid parameters are found. const OVS: [(u8, vals::Hse); 3] = [(16, vals::Hse::OVS16), (8, vals::Hse::OVS8), (3, vals::Hse::OVS3)]; @@ -882,21 +882,47 @@ fn set_baudrate_inner(regs: Regs, clock: u32, baudrate: u32) -> Result<(), Confi }; let mut found = None; - for &(oversampling, hse_value) in &OVS { - if matches!(hse_value, vals::Hse::OVS3) && !x3_invalid { + 'outer: for &(oversampling, hse_value) in &OVS { + if matches!(hse_value, vals::Hse::OVS3) && x3_invalid { + continue; + } + + // Verify that the selected oversampling does not require a clock faster than what the hardware + // is provided. + let Some(min_clock) = baudrate.checked_mul(oversampling as u32) else { + trace!( + "{}x oversampling would cause overflow for clock: {} Hz", + oversampling, + clock + ); + continue; + }; + + if min_clock > clock { + trace!("{} oversampling is too high for clock: {} Hz", oversampling, clock); continue; } for &(div, div_value) in &DIVS { + trace!( + "Trying div: {}, oversampling {} for {} baud", + div, + oversampling, + baudrate + ); + let Some((ibrd, fbrd)) = calculate_brd(clock, div, baudrate, oversampling) else { + trace!("Calculating BRD overflowed: trying another divider"); continue; }; if ibrd < MIN_IBRD || fbrd > MAX_FBRD { + trace!("BRD was invalid: trying another divider"); continue; } found = Some((hse_value, div_value, ibrd, fbrd)); + break 'outer; } } -- cgit