aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/usart/mod.rs43
1 files changed, 37 insertions, 6 deletions
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index 0f3e9412e..061c859a8 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -120,6 +120,12 @@ pub struct Config {
120 /// read will abort, the error reported and cleared 120 /// read will abort, the error reported and cleared
121 /// if false, the error is ignored and cleared 121 /// if false, the error is ignored and cleared
122 pub detect_previous_overrun: bool, 122 pub detect_previous_overrun: bool,
123
124 /// Set this to true if the line is considered noise free.
125 /// This will increase the receivers tolerance to clock deviations,
126 /// but will effectively disable noise detection.
127 #[cfg(not(usart_v1))]
128 pub assume_noise_free: bool,
123} 129}
124 130
125impl Default for Config { 131impl Default for Config {
@@ -131,6 +137,8 @@ impl Default for Config {
131 parity: Parity::ParityNone, 137 parity: Parity::ParityNone,
132 // historical behavior 138 // historical behavior
133 detect_previous_overrun: false, 139 detect_previous_overrun: false,
140 #[cfg(not(usart_v1))]
141 assume_noise_free: false,
134 } 142 }
135 } 143 }
136} 144}
@@ -828,11 +836,17 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx:
828 836
829 #[cfg(not(usart_v1))] 837 #[cfg(not(usart_v1))]
830 let mut over8 = false; 838 let mut over8 = false;
831 let mut found = false; 839 let mut found = None;
832 for &(presc, _presc_val) in &DIVS { 840 for &(presc, _presc_val) in &DIVS {
833 let denom = (config.baudrate * presc as u32) as u64; 841 let denom = (config.baudrate * presc as u32) as u64;
834 let div = (pclk_freq.0 as u64 * mul + (denom / 2)) / denom; 842 let div = (pclk_freq.0 as u64 * mul + (denom / 2)) / denom;
835 trace!("USART: presc={} div={:08x}", presc, div); 843 trace!(
844 "USART: presc={}, div=0x{:08x} (mantissa = {}, fraction = {})",
845 presc,
846 div,
847 div >> 4,
848 div & 0x0F
849 );
836 850
837 if div < brr_min { 851 if div < brr_min {
838 #[cfg(not(usart_v1))] 852 #[cfg(not(usart_v1))]
@@ -844,24 +858,36 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx:
844 #[cfg(usart_v4)] 858 #[cfg(usart_v4)]
845 r.presc().write(|w| w.set_prescaler(_presc_val)); 859 r.presc().write(|w| w.set_prescaler(_presc_val));
846 } 860 }
847 found = true; 861 found = Some(div);
848 break; 862 break;
849 } 863 }
850 panic!("USART: baudrate too high"); 864 panic!("USART: baudrate too high");
851 } 865 }
852 866
853 if div < brr_max { 867 if div < brr_max {
868 let div = div as u32;
854 unsafe { 869 unsafe {
855 r.brr().write_value(regs::Brr(div as u32)); 870 r.brr().write_value(regs::Brr(div));
856 #[cfg(usart_v4)] 871 #[cfg(usart_v4)]
857 r.presc().write(|w| w.set_prescaler(_presc_val)); 872 r.presc().write(|w| w.set_prescaler(_presc_val));
858 } 873 }
859 found = true; 874 found = Some(div);
860 break; 875 break;
861 } 876 }
862 } 877 }
863 878
864 assert!(found, "USART: baudrate too low"); 879 let div = found.expect("USART: baudrate too low");
880
881 #[cfg(not(usart_v1))]
882 let oversampling = if over8 { "8 bit" } else { "16 bit" };
883 #[cfg(usart_v1)]
884 let oversampling = "default";
885 trace!(
886 "Using {} oversampling, desired baudrate: {}, actual baudrate: {}",
887 oversampling,
888 config.baudrate,
889 pclk_freq.0 / div
890 );
865 891
866 unsafe { 892 unsafe {
867 r.cr2().write(|w| { 893 r.cr2().write(|w| {
@@ -895,6 +921,11 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx:
895 #[cfg(not(usart_v1))] 921 #[cfg(not(usart_v1))]
896 w.set_over8(vals::Over8(over8 as _)); 922 w.set_over8(vals::Over8(over8 as _));
897 }); 923 });
924
925 #[cfg(not(usart_v1))]
926 r.cr3().modify(|w| {
927 w.set_onebit(config.assume_noise_free);
928 });
898 } 929 }
899} 930}
900 931