@@ -36,8 +36,9 @@ const SCALE: u32 = 8;
36
36
const STEP_SCALED : u32 = 32_000_000 >> ( 19 - SCALE ) ;
37
37
38
38
fn freq_to_pll_step ( freq_in_hz : u32 ) -> u32 {
39
- // NB! This works well at full MHz level, though there
40
- // are small differences when delving into 0.1MHz level
39
+ // We can use simplified integer formula which gives the same
40
+ // value for whole and half Mhz values ((i.e. 868.0, 868.5, 869, ...)
41
+ // `(freq_in_hz as f64 / 61.03515625) as u32`
41
42
( freq_in_hz / STEP_SCALED ) << SCALE
42
43
}
43
44
@@ -556,12 +557,17 @@ where
556
557
mod tests {
557
558
use super :: * ;
558
559
560
+ // FXOSC[32 MHz] * 1000000 (Hz/MHz) / 524288 (2^19)
561
+ const FREQUENCY_SYNTHESIZER_STEP : f64 = 61.03515625 ;
562
+
559
563
#[ test]
560
564
fn pll_step_freq_u32_vs_f64 ( ) {
561
- // Test whether our frequency -> pll_step and vice versa are good enough
562
- const FREQUENCY_SYNTHESIZER_STEP : f64 = 61.03515625 ;
563
- for freq in 137 ..=1020 {
564
- let f = freq * 1_000_000 ;
565
+ // Simplified integer calculation converges with floating
566
+ // point formula for full and half megahertz values
567
+ const D : u32 = 2 ;
568
+ for freq in D * 137 ..=( D * 1020 ) {
569
+ let f = freq * ( 1_000_000 / D ) ;
570
+
565
571
let pll = freq_to_pll_step ( f) ;
566
572
assert_eq ! ( pll, ( f as f64 / FREQUENCY_SYNTHESIZER_STEP ) as u32 ) ;
567
573
assert_eq ! ( pll_step_to_freq( pll) , f) ;
0 commit comments