diff options
| author | Piotr Esden-Tempski <[email protected]> | 2025-10-05 15:49:05 -0700 |
|---|---|---|
| committer | Piotr Esden-Tempski <[email protected]> | 2025-10-05 16:16:05 -0700 |
| commit | a9727a17b593f7328f721e8905b7fc8dab9ae7ff (patch) | |
| tree | cf3bf4069e41ce9ca6108be5368a05f212acf6d6 /embassy-stm32/src | |
| parent | e2a2bd3c573928208a4c85e7fcd6ad630f23f47d (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.rs | 3 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/c0.rs | 3 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/g4.rs | 3 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/v2.rs | 3 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/v4.rs | 3 |
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 | ||
| 129 | impl Prescaler { | 129 | impl 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 | ||
| 67 | impl Prescaler { | 67 | impl 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 | ||
| 73 | impl Prescaler { | 73 | impl 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 | ||
| 94 | impl Prescaler { | 94 | impl 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, |
