Compare commits

..

4 Commits

Author SHA1 Message Date
0d639adc45 semi working quadrature output 2023-09-27 23:15:31 -04:00
46d6bf1001 Added manual phase offset 2023-09-26 19:46:06 -04:00
208c5709d6 Initial Fork cleanup 2023-09-26 18:57:06 -04:00
a489493a66 Initial fork 2023-09-26 18:47:07 -04:00
5 changed files with 81 additions and 101 deletions

View File

@@ -1,54 +0,0 @@
# Based on the "trust" template v0.1.2
# https://github.com/japaric/trust/tree/v0.1.2
language: rust
services: docker
matrix:
include:
# Linux
- env: TARGET=x86_64-unknown-linux-gnu
rust: nightly
# Bare metal
- env: TARGET=thumbv6m-none-eabi
rust: nightly
- env: TARGET=thumbv7m-none-eabi
rust: nightly
- env: TARGET=thumbv7em-none-eabi
rust: nightly
- env: TARGET=thumbv7em-none-eabihf
rust: nightly
before_install:
- set -e
- rustup self update
install:
- sh ci/install.sh
- source ~/.cargo/env || true
script:
- bash ci/script.sh
after_script: set +e
cache:
cargo: true
directories:
- $HOME/.xargo
before_cache:
# Travis can't cache files that are not readable by "others"
- chmod -R a+r $HOME/.cargo
branches:
only:
- /^v\d+\.\d+\.\d+.*$/
- auto
- master
- try
notifications:
email:
on_success: never

View File

@@ -1,12 +1,6 @@
# si5351
[![docs](https://docs.rs/si5351/badge.svg)](https://docs.rs/si5351)
[![crates.io](https://img.shields.io/crates/v/si5351.svg)](https://crates.io/crates/si5351)
[![ci](https://travis-ci.org/ilya-epifanov/si5351.svg)](https://travis-ci.org/ilya-epifanov/si5351)
## Documentation
On [docs.rs](https://docs.rs/si5351)
Fork of github.com/ilya-epifanov/si5351
## License

View File

@@ -1,21 +0,0 @@
set -ex
main() {
# This fetches latest stable release of Xargo
local tag=$(git ls-remote --tags --refs --exit-code https://github.com/japaric/xargo \
| cut -d/ -f3 \
| grep -E '^v[0.1.0-9.]+$' \
| sort --version-sort \
| tail -n1)
curl -LSfs https://japaric.github.io/trust/install.sh | \
sh -s -- \
--force \
--git japaric/xargo \
--tag $tag \
--target x86_64-unknown-linux-musl
rustup component add rust-src
}
main

View File

@@ -1,16 +0,0 @@
# This script takes care of testing your crate
set -euxo pipefail
main() {
case $TARGET in
x86_64-unknown-linux-gnu)
cargo check --target $TARGET
;;
*)
xargo check --target $TARGET
;;
esac
}
main

View File

@@ -84,7 +84,7 @@ clock.set_frequency(si5351::PLL::A, si5351::ClockOutput::Clk0, 14_175_000)?;
extern crate bitflags;
use embedded_hal as hal;
use core::mem;
//use core::mem;
use crate::hal::blocking::i2c::{Write, WriteRead};
#[derive(Debug)]
@@ -227,6 +227,14 @@ enum Register {
Clk5 = 21,
Clk6 = 22,
Clk7 = 23,
Clk0Phoff = 165,
Clk1Phoff,
Clk2Phoff,
Clk3Phoff,
Clk4Phoff,
Clk5Phoff,
Clk6Phoff, //Not in datasheet
Clk7Phoff, //Not in datasheet
PLLReset = 177,
CrystalLoad = 183,
}
@@ -346,6 +354,7 @@ pub struct Si5351Device<I2C> {
clk_enabled_mask: u8,
ms_int_mode_mask: u8,
ms_src_mask: u8,
last_mdiv: u8,
}
pub trait Si5351 {
@@ -367,6 +376,14 @@ pub trait Si5351 {
fn setup_multisynth_int(&mut self, ms: Multisynth, mult: u16, r_div: OutputDivider) -> Result<(), Error>;
fn setup_multisynth(&mut self, ms: Multisynth, div: u16, num: u32, denom: u32, r_div: OutputDivider) -> Result<(), Error>;
fn select_clock_pll(&mut self, clocl: ClockOutput, pll: PLL);
fn set_quad(&mut self, freq: u32) -> Result<f32, Error>;
fn set_phase_offset(&mut self, clk: ClockOutput, phase_offset: u8) -> Result<(), Error>;
fn reset_pll(&mut self, pll: PLL) -> Result<(), Error>;
}
impl<T> Si5351Device<T> {
pub fn get_xtal_freq(&self) -> u32 {self.xtal_freq}
}
impl<I2C, E> Si5351Device<I2C>
@@ -382,11 +399,13 @@ impl<I2C, E> Si5351Device<I2C>
clk_enabled_mask: 0,
ms_int_mode_mask: 0,
ms_src_mask: 0,
last_mdiv: 0,
};
si5351
}
pub fn new_adafruit_module(i2c: I2C) -> Self {
Si5351Device::new(i2c, false, 25_000_000)
}
@@ -438,7 +457,7 @@ impl<I2C, E> Si5351Device<I2C>
Ok(())
}
fn reset_pll(&mut self, pll: PLL) -> Result<(), Error> {
pub fn reset_pll(&mut self, pll: PLL) -> Result<(), Error> {
self.write_register(Register::PLLReset, match pll {
PLL::A => PLLResetBits::PLLA_RST.bits(),
PLL::B => PLLResetBits::PLLB_RST.bits(),
@@ -448,7 +467,7 @@ impl<I2C, E> Si5351Device<I2C>
}
fn read_register(&mut self, reg: Register) -> Result<u8, Error> {
let mut buffer: [u8; 1] = unsafe { mem::uninitialized() };
let mut buffer: [u8; 1] = /*unsafe { mem::uninitialized() }*/ [0];
self.i2c.write_read(self.address, &[reg.addr()], &mut buffer).map_err(i2c_error)?;
Ok(buffer[0])
}
@@ -467,6 +486,11 @@ impl<I2C, E> Si5351Device<I2C>
impl<I2C, E> Si5351 for Si5351Device<I2C> where
I2C: WriteRead<Error=E> + Write<Error=E>
{
fn reset_pll(&mut self, pll: PLL) -> Result<(), Error> {
self.reset_pll(pll)
}
fn init_adafruit_module(&mut self) -> Result<(), Error> {
self.init(CrystalLoad::_10)
}
@@ -554,6 +578,59 @@ impl<I2C, E> Si5351 for Si5351Device<I2C> where
Ok(())
}
fn set_quad(&mut self, freq: u32) -> Result<f32, Error> {
let ms0 = Multisynth::MS0;
let ms1 = Multisynth::MS1;
let mut ms_div = 126;
let mut mult = (freq*ms_div) as f32 / self.get_xtal_freq() as f32;
while mult > 90.0 {
ms_div -= (ms_div as f32 * 0.2) as u32;
mult = (freq*ms_div) as f32 / self.get_xtal_freq() as f32;
}
if mult < 15.0 {return Err(Error::InvalidParameter);}
//easy calc fraction not the most accurate
let denom: u32 = 1048575;
let num = ((mult % 1.0) * denom as f32) as u32;
let mult = mult as u8;
let ms_div = ms_div as u8;
self.setup_pll(PLL::A, mult, num, denom)?;
self.setup_multisynth_int(ms0, ms_div as u16, OutputDivider::Div1)?;
self.setup_multisynth_int(ms1, ms_div as u16, OutputDivider::Div1)?;
self.select_clock_pll(ClockOutput::Clk0, PLL::A);
self.select_clock_pll(ClockOutput::Clk1, PLL::A);
self.set_clock_enabled(ClockOutput::Clk0, true);
self.set_clock_enabled(ClockOutput::Clk1, true);
self.flush_clock_control(ClockOutput::Clk0)?;
self.flush_clock_control(ClockOutput::Clk1)?;
if self.last_mdiv != ms_div {
self.set_phase_offset(ClockOutput::Clk1, ms_div as u8)?;
self.reset_pll(PLL::A)?;
}
self.last_mdiv = ms_div;
self.flush_output_enabled()?;
let freq_num = self.xtal_freq as f32 * (mult as f32 + (num as f32 / denom as f32));
Ok( freq_num / ms_div as f32 )
}
fn set_phase_offset(&mut self, clk: ClockOutput, phase_offset: u8) -> Result<(), Error> {
if phase_offset & 1<<7 > 0 {return Err(Error::InvalidParameter);}
let reg = match clk {
ClockOutput::Clk0 => Register::Clk0Phoff,
ClockOutput::Clk1 => Register::Clk1Phoff,
ClockOutput::Clk2 => Register::Clk2Phoff,
ClockOutput::Clk3 => Register::Clk3Phoff,
ClockOutput::Clk4 => Register::Clk4Phoff,
ClockOutput::Clk5 => Register::Clk5Phoff,
ClockOutput::Clk6 => Register::Clk6Phoff,
ClockOutput::Clk7 => Register::Clk7Phoff,
};
self.write_register(reg, phase_offset)?;
Ok(())
}
fn set_clock_enabled(&mut self, clk: ClockOutput, enabled: bool) {
let bit = 1u8 << clk.ix();