aboutsummaryrefslogtreecommitdiffstats
path: root/sw/picardy/src/si_clock.rs
diff options
context:
space:
mode:
Diffstat (limited to 'sw/picardy/src/si_clock.rs')
-rw-r--r--sw/picardy/src/si_clock.rs36
1 files changed, 19 insertions, 17 deletions
diff --git a/sw/picardy/src/si_clock.rs b/sw/picardy/src/si_clock.rs
index 6de4c25..4bd2686 100644
--- a/sw/picardy/src/si_clock.rs
+++ b/sw/picardy/src/si_clock.rs
@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
- Copyright (c) 2020 Matthias P. Braendli
+ Copyright (c) 2023 Matthias P. Braendli
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -26,10 +26,10 @@ use core::convert::TryInto;
use si5351::{Si5351, Si5351Device};
use embedded_hal::blocking::i2c::{WriteRead, Write};
-const REF_CLOCK : u32 = 25_000_000;
+const REF_CLOCK_CHZ : u32 = 25_000_000 * 100;
const PLL_A_MULT : u32 = 32;
-fn gcd(x: u32, y: u32) -> u32 {
+fn gcd(x: u64, y: u64) -> u64 {
let mut x = x;
let mut y = y;
while y != 0 {
@@ -40,30 +40,32 @@ fn gcd(x: u32, y: u32) -> u32 {
x
}
-fn clock_settings_for_pll(freq: u32, pll: u32) -> (u16, u32, u32) {
+// All calculations in centihertz
+
+fn clock_settings_for_pll(freq: u64, pll: u64) -> (u16, u32, u32) {
let a = pll / freq;
let b = pll - (a * freq);
let gcd = gcd(b, freq);
let b = b / gcd;
let c = freq / gcd;
- (a.try_into().unwrap(), b, c)
+ (a.try_into().unwrap(), b.try_into().unwrap(), c.try_into().unwrap())
}
-fn clock_settings_with_pll_calculation(freq: u32) -> (u16, u8, u32, u32) {
- let mut divider : u32 = 900_000_000 / freq; // Calculate the division ratio. 900,000,000 is the maximum internal
+fn clock_settings_with_pll_calculation(freq_chz: u32) -> (u16, u8, u32, u32) {
+ let mut divider : u32 = (100*900_000_000u64 / freq_chz as u64).try_into().unwrap(); // Calculate the division ratio. 900,000,000 is the maximum internal
if (divider % 2) == 1 {
divider -= 1 // Ensure an even integer division ratio
}
- let pll_freq = divider * freq;
+ let pll_freq : u128 = divider as u128 * freq_chz as u128;
// mult is an integer that must be in the range 15..90
- let mult = pll_freq / REF_CLOCK;
- let l = pll_freq % REF_CLOCK;
+ let mult = pll_freq / (REF_CLOCK_CHZ as u128);
+ let l : u32 = (pll_freq % (REF_CLOCK_CHZ as u128)).try_into().unwrap();
let denom = 1048575;
- let num = f64::from(l) * f64::from(denom) / f64::from(REF_CLOCK);
+ let num = f64::from(l) * f64::from(denom) / f64::from(REF_CLOCK_CHZ);
(divider.try_into().unwrap(), mult.try_into().unwrap(), num as u32, denom)
}
@@ -74,7 +76,7 @@ fn set_bfo(siclock: &mut dyn Si5351, freq: u32) -> Result<(), si5351::Error>
siclock.set_clock_enabled(si5351::ClockOutput::Clk2, false);
}
else {
- let (a, b, c) = clock_settings_for_pll(freq, PLL_A_MULT * REF_CLOCK);
+ let (a, b, c) = clock_settings_for_pll(freq.into(), PLL_A_MULT as u64 * REF_CLOCK_CHZ as u64);
siclock.setup_multisynth(si5351::Multisynth::MS2, a, b, c, si5351::OutputDivider::Div1)?;
siclock.select_clock_pll(si5351::ClockOutput::Clk2, si5351::PLL::A);
siclock.set_clock_enabled(si5351::ClockOutput::Clk2, true);
@@ -82,7 +84,7 @@ fn set_bfo(siclock: &mut dyn Si5351, freq: u32) -> Result<(), si5351::Error>
siclock.flush_clock_control(si5351::ClockOutput::Clk2)
}
-fn set_vfo(siclock: &mut dyn Si5351, freq: u32)
+fn set_vfo_centihertz(siclock: &mut dyn Si5351, freq: u32)
{
if freq == 0 {
siclock.set_clock_enabled(si5351::ClockOutput::Clk0, false);
@@ -107,7 +109,7 @@ impl<I2C, E> SiClock<I2C>
I2C: WriteRead<Error = E> + Write<Error = E>,
{
pub fn new(i2c: I2C, bfo: u32, vfo: u32) -> SiClock<I2C> {
- let mut siclock = Si5351Device::new(i2c, false, REF_CLOCK);
+ let mut siclock = Si5351Device::new(i2c, false);
siclock.init(si5351::CrystalLoad::_10).unwrap();
// See freqplan.py for Si5351 frequency plan
@@ -118,7 +120,7 @@ impl<I2C, E> SiClock<I2C>
siclock.reset_pll(si5351::PLL::A).unwrap();
- set_vfo(&mut siclock, vfo);
+ set_vfo_centihertz(&mut siclock, vfo * 100);
siclock.reset_pll(si5351::PLL::B).unwrap();
@@ -127,8 +129,8 @@ impl<I2C, E> SiClock<I2C>
SiClock{siclock}
}
- pub fn set_vfo(&mut self, freq: u32) {
- set_vfo(&mut self.siclock, freq)
+ pub fn set_vfo_centihertz(&mut self, freq: u32) {
+ set_vfo_centihertz(&mut self.siclock, freq)
}
pub fn set_bfo(&mut self, freq: u32) -> Result<(), si5351::Error> {