Si5324 Rust driver brought on par with og artiq #132
|
@ -201,7 +201,7 @@ pub fn main_core0() {
|
|||
i2c::init();
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
si5324::setup(unsafe { (&mut i2c::I2C_BUS).as_mut().unwrap() },
|
||||
&SI5324_SETTINGS, si5324::Input::Ckin2).expect("cannot initialize Si5324");
|
||||
&SI5324_SETTINGS, si5324::Input::Ckin2, timer).expect("cannot initialize Si5324");
|
||||
|
||||
let cfg = match Config::new() {
|
||||
Ok(cfg) => cfg,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use core::result;
|
||||
use log::info;
|
||||
use libboard_zynq::i2c::I2c;
|
||||
use libboard_zynq::{i2c::I2c, timer::GlobalTimer, time::Milliseconds};
|
||||
use embedded_hal::blocking::delay::DelayUs;
|
||||
|
||||
type Result<T> = result::Result<T, &'static str>;
|
||||
|
||||
|
@ -134,9 +135,9 @@ fn ident(i2c: &mut I2c) -> Result<u16> {
|
|||
Ok(((read(i2c, 134)? as u16) << 8) | (read(i2c, 135)? as u16))
|
||||
}
|
||||
|
||||
fn soft_reset(i2c: &mut I2c) -> Result<()> {
|
||||
//TODO write_no_ack_value(i2c, 136, read(136)? | 0x80)?;
|
||||
//TODO clock::spin_us(10_000);
|
||||
fn soft_reset(i2c: &mut I2c, timer: GlobalTimer) -> Result<()> {
|
||||
write_no_ack_value(i2c, 136, read(i2c, 136)? | 0x80)?;
|
||||
timer.delay_us(10_000);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -155,20 +156,20 @@ fn locked(i2c: &mut I2c) -> Result<bool> {
|
|||
Ok((read(i2c, 130)? & 0x01) == 0) // LOL_INT=0
|
||||
}
|
||||
|
||||
fn monitor_lock(i2c: &mut I2c) -> Result<()> {
|
||||
fn monitor_lock(i2c: &mut I2c, timer: GlobalTimer) -> Result<()> {
|
||||
info!("waiting for Si5324 lock...");
|
||||
// TODO let t = clock::get_ms();
|
||||
let timeout = timer.get_time() + Milliseconds(20_000);
|
||||
while !locked(i2c)? {
|
||||
// Yes, lock can be really slow.
|
||||
/*if clock::get_ms() > t + 20000 {
|
||||
if timer.get_time() > timeout {
|
||||
return Err("Si5324 lock timeout");
|
||||
}*/
|
||||
}
|
||||
}
|
||||
info!(" ...locked");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn init(i2c: &mut I2c) -> Result<()> {
|
||||
fn init(i2c: &mut I2c, timer: GlobalTimer) -> Result<()> {
|
||||
#[cfg(feature = "target_kasli_soc")]
|
||||
{
|
||||
i2c.pca9548_select(0x70, 0)?;
|
||||
|
@ -179,16 +180,16 @@ fn init(i2c: &mut I2c) -> Result<()> {
|
|||
return Err("Si5324 does not have expected product number");
|
||||
}
|
||||
|
||||
soft_reset(i2c)?;
|
||||
soft_reset(i2c, timer)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn bypass(i2c: &mut I2c, input: Input) -> Result<()> {
|
||||
pub fn bypass(i2c: &mut I2c, input: Input, timer: GlobalTimer) -> Result<()> {
|
||||
let cksel_reg = match input {
|
||||
Input::Ckin1 => 0b00,
|
||||
Input::Ckin2 => 0b01,
|
||||
};
|
||||
init(i2c)?;
|
||||
init(i2c, timer)?;
|
||||
rmw(i2c, 21, |v| v & 0xfe)?; // CKSEL_PIN=0
|
||||
rmw(i2c, 3, |v| (v & 0x3f) | (cksel_reg << 6))?; // CKSEL_REG
|
||||
rmw(i2c, 4, |v| (v & 0x3f) | (0b00 << 6))?; // AUTOSEL_REG=b00
|
||||
|
@ -197,14 +198,14 @@ pub fn bypass(i2c: &mut I2c, input: Input) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn setup(i2c: &mut I2c, settings: &FrequencySettings, input: Input) -> Result<()> {
|
||||
pub fn setup(i2c: &mut I2c, settings: &FrequencySettings, input: Input, timer: GlobalTimer) -> Result<()> {
|
||||
let s = map_frequency_settings(settings)?;
|
||||
let cksel_reg = match input {
|
||||
Input::Ckin1 => 0b00,
|
||||
Input::Ckin2 => 0b01,
|
||||
};
|
||||
|
||||
init(i2c)?;
|
||||
init(i2c, timer)?;
|
||||
if settings.crystal_ref {
|
||||
rmw(i2c, 0, |v| v | 0x40)?; // FREE_RUN=1
|
||||
}
|
||||
|
@ -239,11 +240,11 @@ pub fn setup(i2c: &mut I2c, settings: &FrequencySettings, input: Input) -> Resul
|
|||
return Err("Si5324 misses clock input signal");
|
||||
}
|
||||
|
||||
monitor_lock(i2c)?;
|
||||
monitor_lock(i2c, timer)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn select_input(i2c: &mut I2c, input: Input) -> Result<()> {
|
||||
pub fn select_input(i2c: &mut I2c, input: Input, timer: GlobalTimer) -> Result<()> {
|
||||
let cksel_reg = match input {
|
||||
Input::Ckin1 => 0b00,
|
||||
Input::Ckin2 => 0b01,
|
||||
|
@ -252,6 +253,6 @@ pub fn select_input(i2c: &mut I2c, input: Input) -> Result<()> {
|
|||
if !has_ckin(i2c, input)? {
|
||||
return Err("Si5324 misses clock input signal");
|
||||
}
|
||||
monitor_lock(i2c)?;
|
||||
monitor_lock(i2c, timer)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue