aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/CHANGELOG.md1
-rw-r--r--embassy-stm32/src/adc/adc4.rs2
-rw-r--r--embassy-stm32/src/adc/c0.rs2
-rw-r--r--embassy-stm32/src/adc/g4.rs2
-rw-r--r--embassy-stm32/src/adc/v2.rs2
-rw-r--r--embassy-stm32/src/adc/v4.rs2
-rw-r--r--embassy-stm32/src/rcc/mod.rs30
7 files changed, 36 insertions, 5 deletions
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md
index 2c3dfb3d3..da0d14e4f 100644
--- a/embassy-stm32/CHANGELOG.md
+++ b/embassy-stm32/CHANGELOG.md
@@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
41- feat: stm32/usart: add `eager_reads` option to control if buffered readers return as soon as possible or after more data is available ([#4668](https://github.com/embassy-rs/embassy/pull/4668)) 41- feat: stm32/usart: add `eager_reads` option to control if buffered readers return as soon as possible or after more data is available ([#4668](https://github.com/embassy-rs/embassy/pull/4668))
42- feat: stm32/usart: add `de_assertion_time` and `de_deassertion_time` config options 42- feat: stm32/usart: add `de_assertion_time` and `de_deassertion_time` config options
43- change: stm32/uart: BufferedUartRx now returns all available bytes from the internal buffer 43- change: stm32/uart: BufferedUartRx now returns all available bytes from the internal buffer
44- fix: stm32/adc: Calculate the ADC prescaler in a way that it allows for the max frequency to be reached
44- fix: Prevent a HardFault crash on STM32H5 devices by changing `uid()` to return `[u8; 12]` by value instead of a reference. (Fixes #2696) 45- fix: Prevent a HardFault crash on STM32H5 devices by changing `uid()` to return `[u8; 12]` by value instead of a reference. (Fixes #2696)
45- change: timer: added output compare values 46- change: timer: added output compare values
46- feat: timer: add ability to set master mode 47- feat: timer: add ability to set master mode
diff --git a/embassy-stm32/src/adc/adc4.rs b/embassy-stm32/src/adc/adc4.rs
index babdebfdb..499fc2093 100644
--- a/embassy-stm32/src/adc/adc4.rs
+++ b/embassy-stm32/src/adc/adc4.rs
@@ -77,7 +77,7 @@ pub const fn resolution_to_max_count(res: Resolution) -> u32 {
77} 77}
78 78
79fn from_ker_ck(frequency: Hertz) -> Presc { 79fn from_ker_ck(frequency: Hertz) -> Presc {
80 let raw_prescaler = frequency.0 / MAX_ADC_CLK_FREQ.0; 80 let raw_prescaler = rcc::raw_prescaler(frequency.0, MAX_ADC_CLK_FREQ.0);
81 match raw_prescaler { 81 match raw_prescaler {
82 0 => Presc::DIV1, 82 0 => Presc::DIV1,
83 1 => Presc::DIV2, 83 1 => Presc::DIV2,
diff --git a/embassy-stm32/src/adc/c0.rs b/embassy-stm32/src/adc/c0.rs
index d87bd1ed4..3e109e429 100644
--- a/embassy-stm32/src/adc/c0.rs
+++ b/embassy-stm32/src/adc/c0.rs
@@ -30,7 +30,7 @@ impl<T: Instance> super::SealedSpecialConverter<super::Temperature> for T {
30} 30}
31 31
32fn from_ker_ck(frequency: Hertz) -> Presc { 32fn from_ker_ck(frequency: Hertz) -> Presc {
33 let raw_prescaler = frequency.0 / MAX_ADC_CLK_FREQ.0; 33 let raw_prescaler = rcc::raw_prescaler(frequency.0, MAX_ADC_CLK_FREQ.0);
34 match raw_prescaler { 34 match raw_prescaler {
35 0 => Presc::DIV1, 35 0 => Presc::DIV1,
36 1 => Presc::DIV2, 36 1 => Presc::DIV2,
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index 4957123a1..1767a3bb3 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -33,7 +33,7 @@ const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(60);
33const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(50); 33const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(50);
34 34
35fn from_ker_ck(frequency: Hertz) -> Presc { 35fn from_ker_ck(frequency: Hertz) -> Presc {
36 let raw_prescaler = frequency.0 / MAX_ADC_CLK_FREQ.0; 36 let raw_prescaler = rcc::raw_prescaler(frequency.0, MAX_ADC_CLK_FREQ.0);
37 match raw_prescaler { 37 match raw_prescaler {
38 0 => Presc::DIV1, 38 0 => Presc::DIV1,
39 1 => Presc::DIV2, 39 1 => Presc::DIV2,
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 07eaebf7c..341b15674 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -58,7 +58,7 @@ fn from_pclk2(freq: Hertz) -> Adcpre {
58 // Datasheet for both F4 and F7 specifies min frequency 0.6 MHz, typ freq. 30 MHz and max 36 MHz. 58 // Datasheet for both F4 and F7 specifies min frequency 0.6 MHz, typ freq. 30 MHz and max 36 MHz.
59 #[cfg(not(stm32f2))] 59 #[cfg(not(stm32f2))]
60 const MAX_FREQUENCY: Hertz = Hertz(36_000_000); 60 const MAX_FREQUENCY: Hertz = Hertz(36_000_000);
61 let raw_div = freq.0 / MAX_FREQUENCY.0; 61 let raw_div = rcc::raw_prescaler(freq.0, MAX_FREQUENCY.0);
62 match raw_div { 62 match raw_div {
63 0..=1 => Adcpre::DIV2, 63 0..=1 => Adcpre::DIV2,
64 2..=3 => Adcpre::DIV4, 64 2..=3 => Adcpre::DIV4,
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index 804e63db6..a3d9e6176 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -60,7 +60,7 @@ impl<T: Instance> super::SealedSpecialConverter<super::Vbat> for T {
60} 60}
61 61
62fn from_ker_ck(frequency: Hertz) -> Presc { 62fn from_ker_ck(frequency: Hertz) -> Presc {
63 let raw_prescaler = frequency.0 / MAX_ADC_CLK_FREQ.0; 63 let raw_prescaler = rcc::raw_prescaler(frequency.0, MAX_ADC_CLK_FREQ.0);
64 match raw_prescaler { 64 match raw_prescaler {
65 0 => Presc::DIV1, 65 0 => Presc::DIV1,
66 1 => Presc::DIV2, 66 1 => Presc::DIV2,
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 592890777..ca7c28cbc 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -413,3 +413,33 @@ pub(crate) fn init_rcc(_cs: CriticalSection, config: Config) {
413 } 413 }
414 } 414 }
415} 415}
416
417/// Calculate intermediate prescaler number used to calculate peripheral prescalers
418///
419/// This function is intended to calculate a number indicating a minimum division
420/// necessary to result in a frequency lower than the provided `freq_max`.
421///
422/// The returned value indicates the `val + 1` divider is necessary to result in
423/// the output frequency that is below the maximum provided.
424///
425/// For example:
426/// 0 = divider of 1 => no division necessary as the input frequency is below max
427/// 1 = divider of 2 => division by 2 necessary
428/// ...
429///
430/// The provided max frequency is inclusive. So if `freq_in == freq_max` the result
431/// will be 0, indicating that no division is necessary. To accomplish that we subtract
432/// 1 from the input frequency so that the integer rounding plays in our favor.
433///
434/// For example:
435/// Let the input frequency be 110 and the max frequency be 55.
436/// If we naiively do `110/55 = 2` the renult will indicate that we need a divider by 3
437/// which in reality will be rounded up to 4 as usually a 3 division is not available.
438/// In either case the resulting frequency will be either 36 or 27 which is lower than
439/// what we would want. The result should be 1.
440/// If we do the following instead `109/55 = 1` indicating that we need a divide by 2
441/// which will result in the correct 55.
442#[allow(unused)]
443pub(crate) fn raw_prescaler(freq_in: u32, freq_max: u32) -> u32 {
444 freq_in.saturating_sub(1) / freq_max
445}