aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorPiotr Esden-Tempski <[email protected]>2025-10-05 15:49:05 -0700
committerPiotr Esden-Tempski <[email protected]>2025-10-05 16:16:05 -0700
commita9727a17b593f7328f721e8905b7fc8dab9ae7ff (patch)
treecf3bf4069e41ce9ca6108be5368a05f212acf6d6 /embassy-stm32/src
parente2a2bd3c573928208a4c85e7fcd6ad630f23f47d (diff)
stm32/ADC: Fix prescaler calculation to include max frequency.
Due to the integer rounding rules one has to subtract 1 from the numerator. For example: Let max clock be 55 and supplied clock be 110 110/55 = 2 which results in the divider being set to 4 and the clock after division ends up being 27 instead of 55 Subtracting 1 to the numerator get around the rounding issue 109/55 = 1 which results in the divider being set to 2 and the clock after division ends up being 55 which is exactly max clock
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/adc/adc4.rs3
-rw-r--r--embassy-stm32/src/adc/c0.rs3
-rw-r--r--embassy-stm32/src/adc/g4.rs3
-rw-r--r--embassy-stm32/src/adc/v2.rs3
-rw-r--r--embassy-stm32/src/adc/v4.rs3
5 files changed, 10 insertions, 5 deletions
diff --git a/embassy-stm32/src/adc/adc4.rs b/embassy-stm32/src/adc/adc4.rs
index 255dc7956..1302dffb8 100644
--- a/embassy-stm32/src/adc/adc4.rs
+++ b/embassy-stm32/src/adc/adc4.rs
@@ -128,7 +128,8 @@ enum Prescaler {
128 128
129impl Prescaler { 129impl Prescaler {
130 fn from_ker_ck(frequency: Hertz) -> Self { 130 fn from_ker_ck(frequency: Hertz) -> Self {
131 let raw_prescaler = frequency.0 / MAX_ADC_CLK_FREQ.0; 131 // Calculate prescaler in a way where the clock can hit MAX CLK
132 let raw_prescaler = frequency.0.saturating_sub(1) / MAX_ADC_CLK_FREQ.0;
132 match raw_prescaler { 133 match raw_prescaler {
133 0 => Self::NotDivided, 134 0 => Self::NotDivided,
134 1 => Self::DividedBy2, 135 1 => Self::DividedBy2,
diff --git a/embassy-stm32/src/adc/c0.rs b/embassy-stm32/src/adc/c0.rs
index f2837a8f1..bd9a3e2c6 100644
--- a/embassy-stm32/src/adc/c0.rs
+++ b/embassy-stm32/src/adc/c0.rs
@@ -66,7 +66,8 @@ pub enum Prescaler {
66 66
67impl Prescaler { 67impl Prescaler {
68 fn from_ker_ck(frequency: Hertz) -> Self { 68 fn from_ker_ck(frequency: Hertz) -> Self {
69 let raw_prescaler = frequency.0 / MAX_ADC_CLK_FREQ.0; 69 // Calculate prescaler in a way where the clock can hit MAX CLK
70 let raw_prescaler = frequency.0.saturating_sub(1) / MAX_ADC_CLK_FREQ.0;
70 match raw_prescaler { 71 match raw_prescaler {
71 0 => Self::NotDivided, 72 0 => Self::NotDivided,
72 1 => Self::DividedBy2, 73 1 => Self::DividedBy2,
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index 43498966f..ac0a6196f 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -72,7 +72,8 @@ enum Prescaler {
72 72
73impl Prescaler { 73impl Prescaler {
74 fn from_ker_ck(frequency: Hertz) -> Self { 74 fn from_ker_ck(frequency: Hertz) -> Self {
75 let raw_prescaler = frequency.0 / MAX_ADC_CLK_FREQ.0; 75 // Calculate prescaler in a way where the clock can hit MAX CLK
76 let raw_prescaler = frequency.0.saturating_sub(1) / MAX_ADC_CLK_FREQ.0;
76 match raw_prescaler { 77 match raw_prescaler {
77 0 => Self::NotDivided, 78 0 => Self::NotDivided,
78 1 => Self::DividedBy2, 79 1 => Self::DividedBy2,
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index e94a25b24..57f252e13 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -71,7 +71,8 @@ impl Prescaler {
71 // Datasheet for both F4 and F7 specifies min frequency 0.6 MHz, typ freq. 30 MHz and max 36 MHz. 71 // Datasheet for both F4 and F7 specifies min frequency 0.6 MHz, typ freq. 30 MHz and max 36 MHz.
72 #[cfg(not(stm32f2))] 72 #[cfg(not(stm32f2))]
73 const MAX_FREQUENCY: Hertz = Hertz(36_000_000); 73 const MAX_FREQUENCY: Hertz = Hertz(36_000_000);
74 let raw_div = freq.0 / MAX_FREQUENCY.0; 74 // Calculate prescaler divider including MAX_FREQ
75 let raw_div = freq.0.saturating_sub(1) / MAX_FREQUENCY.0;
75 match raw_div { 76 match raw_div {
76 0..=1 => Self::Div2, 77 0..=1 => Self::Div2,
77 2..=3 => Self::Div4, 78 2..=3 => Self::Div4,
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index b66437e6e..c68684cb2 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -93,7 +93,8 @@ enum Prescaler {
93 93
94impl Prescaler { 94impl Prescaler {
95 fn from_ker_ck(frequency: Hertz) -> Self { 95 fn from_ker_ck(frequency: Hertz) -> Self {
96 let raw_prescaler = frequency.0 / MAX_ADC_CLK_FREQ.0; 96 // Calculate prescaler in a way where the clock can hit MAX CLK
97 let raw_prescaler = frequency.0.saturating_sub(1) / MAX_ADC_CLK_FREQ.0;
97 match raw_prescaler { 98 match raw_prescaler {
98 0 => Self::NotDivided, 99 0 => Self::NotDivided,
99 1 => Self::DividedBy2, 100 1 => Self::DividedBy2,