diff options
Diffstat (limited to 'embassy-mspm0/src')
| -rw-r--r-- | embassy-mspm0/src/uart.rs | 32 |
1 files changed, 29 insertions, 3 deletions
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 | |||
| 869 | // maximum speed is limited to UARTclk/16." | 869 | // maximum speed is limited to UARTclk/16." |
| 870 | // | 870 | // |
| 871 | // Based on these requirements, prioritize higher oversampling first to increase tolerance to clock | 871 | // Based on these requirements, prioritize higher oversampling first to increase tolerance to clock |
| 872 | // deviation. If no valid BRD valud can be found satisifying the highest sample rate, then reduce | 872 | // deviation. If no valid BRD value can be found satisifying the highest sample rate, then reduce |
| 873 | // sample rate until valid parameters are found. | 873 | // sample rate until valid parameters are found. |
| 874 | const OVS: [(u8, vals::Hse); 3] = [(16, vals::Hse::OVS16), (8, vals::Hse::OVS8), (3, vals::Hse::OVS3)]; | 874 | const OVS: [(u8, vals::Hse); 3] = [(16, vals::Hse::OVS16), (8, vals::Hse::OVS8), (3, vals::Hse::OVS3)]; |
| 875 | 875 | ||
| @@ -882,21 +882,47 @@ fn set_baudrate_inner(regs: Regs, clock: u32, baudrate: u32) -> Result<(), Confi | |||
| 882 | }; | 882 | }; |
| 883 | let mut found = None; | 883 | let mut found = None; |
| 884 | 884 | ||
| 885 | for &(oversampling, hse_value) in &OVS { | 885 | 'outer: for &(oversampling, hse_value) in &OVS { |
| 886 | if matches!(hse_value, vals::Hse::OVS3) && !x3_invalid { | 886 | if matches!(hse_value, vals::Hse::OVS3) && x3_invalid { |
| 887 | continue; | ||
| 888 | } | ||
| 889 | |||
| 890 | // Verify that the selected oversampling does not require a clock faster than what the hardware | ||
| 891 | // is provided. | ||
| 892 | let Some(min_clock) = baudrate.checked_mul(oversampling as u32) else { | ||
| 893 | trace!( | ||
| 894 | "{}x oversampling would cause overflow for clock: {} Hz", | ||
| 895 | oversampling, | ||
| 896 | clock | ||
| 897 | ); | ||
| 898 | continue; | ||
| 899 | }; | ||
| 900 | |||
| 901 | if min_clock > clock { | ||
| 902 | trace!("{} oversampling is too high for clock: {} Hz", oversampling, clock); | ||
| 887 | continue; | 903 | continue; |
| 888 | } | 904 | } |
| 889 | 905 | ||
| 890 | for &(div, div_value) in &DIVS { | 906 | for &(div, div_value) in &DIVS { |
| 907 | trace!( | ||
| 908 | "Trying div: {}, oversampling {} for {} baud", | ||
| 909 | div, | ||
| 910 | oversampling, | ||
| 911 | baudrate | ||
| 912 | ); | ||
| 913 | |||
| 891 | let Some((ibrd, fbrd)) = calculate_brd(clock, div, baudrate, oversampling) else { | 914 | let Some((ibrd, fbrd)) = calculate_brd(clock, div, baudrate, oversampling) else { |
| 915 | trace!("Calculating BRD overflowed: trying another divider"); | ||
| 892 | continue; | 916 | continue; |
| 893 | }; | 917 | }; |
| 894 | 918 | ||
| 895 | if ibrd < MIN_IBRD || fbrd > MAX_FBRD { | 919 | if ibrd < MIN_IBRD || fbrd > MAX_FBRD { |
| 920 | trace!("BRD was invalid: trying another divider"); | ||
| 896 | continue; | 921 | continue; |
| 897 | } | 922 | } |
| 898 | 923 | ||
| 899 | found = Some((hse_value, div_value, ibrd, fbrd)); | 924 | found = Some((hse_value, div_value, ibrd, fbrd)); |
| 925 | break 'outer; | ||
| 900 | } | 926 | } |
| 901 | } | 927 | } |
| 902 | 928 | ||
