From e04fec33f079db4c5d42aa412f7b670784ec1b68 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 13 Mar 2023 23:14:32 +0100 Subject: Add WSPR TX to eval-clock-cw-tx --- sw/eval-clock-cw-tx/src/si_clock.rs | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'sw/eval-clock-cw-tx/src/si_clock.rs') diff --git a/sw/eval-clock-cw-tx/src/si_clock.rs b/sw/eval-clock-cw-tx/src/si_clock.rs index 6de4c25..4bd2686 100644 --- a/sw/eval-clock-cw-tx/src/si_clock.rs +++ b/sw/eval-clock-cw-tx/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 SiClock I2C: WriteRead + Write, { pub fn new(i2c: I2C, bfo: u32, vfo: u32) -> SiClock { - 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 SiClock 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 SiClock 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> { -- cgit v1.2.3