si5324: kasli support

This commit is contained in:
Sebastien Bourdeauducq 2018-01-23 13:16:34 +08:00
parent 649deccd9b
commit cfffd9e13d
1 changed files with 34 additions and 15 deletions

View File

@ -1,5 +1,7 @@
use core::result; use core::result;
use board::{csr, clock}; use board::clock;
#[cfg(not(si5324_soft_reset))]
use board::csr;
use i2c; use i2c;
type Result<T> = result::Result<T, &'static str>; type Result<T> = result::Result<T, &'static str>;
@ -7,23 +9,27 @@ type Result<T> = result::Result<T, &'static str>;
const BUSNO: u8 = 0; const BUSNO: u8 = 0;
const ADDRESS: u8 = 0x68; const ADDRESS: u8 = 0x68;
#[cfg(any(soc_platform = "sayma_amc", soc_platform = "kc705"))] #[cfg(any(soc_platform = "kasli",
fn pca9548_select(address: u8, channel: u8) -> Result<()> { soc_platform = "sayma_amc",
soc_platform = "kc705"))]
fn pca9548_select(address: u8, channels: u8) -> Result<()> {
i2c::start(BUSNO).unwrap(); i2c::start(BUSNO).unwrap();
if !i2c::write(BUSNO, (address << 1)).unwrap() { if !i2c::write(BUSNO, (address << 1)).unwrap() {
return Err("PCA9548 failed to ack write address") return Err("PCA9548 failed to ack write address")
} }
if !i2c::write(BUSNO, 1 << channel).unwrap() { if !i2c::write(BUSNO, channels).unwrap() {
return Err("PCA9548 failed to ack control word") return Err("PCA9548 failed to ack control word")
} }
i2c::stop(BUSNO).unwrap(); i2c::stop(BUSNO).unwrap();
Ok(()) Ok(())
} }
fn reset(en: bool) { #[cfg(not(si5324_soft_reset))]
unsafe { fn hard_reset() {
csr::si5324_rst_n::out_write(if en { 0 } else { 1 }) unsafe { csr::si5324_rst_n::out_write(0); }
} clock::spin_us(1_000);
unsafe { csr::si5324_rst_n::out_write(1); }
clock::spin_us(10_000);
} }
// NOTE: the logical parameters DO NOT MAP to physical values written // NOTE: the logical parameters DO NOT MAP to physical values written
@ -127,6 +133,13 @@ fn ident() -> Result<u16> {
Ok(((read(134)? as u16) << 8) | (read(135)? as u16)) Ok(((read(134)? as u16) << 8) | (read(135)? as u16))
} }
#[cfg(si5324_soft_reset)]
fn soft_reset() -> Result<()> {
write(136, read(136)? | 0x80)?;
clock::spin_us(10_000);
Ok(())
}
fn has_xtal() -> Result<bool> { fn has_xtal() -> Result<bool> {
Ok((read(129)? & 0x01) == 0) // LOSX_INT=0 Ok((read(129)? & 0x01) == 0) // LOSX_INT=0
} }
@ -154,20 +167,26 @@ fn monitor_lock() -> Result<()> {
pub fn setup(settings: &FrequencySettings) -> Result<()> { pub fn setup(settings: &FrequencySettings) -> Result<()> {
let s = map_frequency_settings(settings)?; let s = map_frequency_settings(settings)?;
reset(true); #[cfg(not(si5324_soft_reset))]
clock::spin_us(1_000); hard_reset();
reset(false);
clock::spin_us(10_000);
#[cfg(soc_platform = "kc705")] #[cfg(soc_platform = "kasli")]
pca9548_select(0x74, 7)?; {
pca9548_select(0x70, 0)?;
pca9548_select(0x71, 1 << 3)?;
}
#[cfg(soc_platform = "sayma_amc")] #[cfg(soc_platform = "sayma_amc")]
pca9548_select(0x70, 4)?; pca9548_select(0x70, 1 << 4)?;
#[cfg(soc_platform = "kc705")]
pca9548_select(0x74, 1 << 7)?;
if ident()? != 0x0182 { if ident()? != 0x0182 {
return Err("Si5324 does not have expected product number"); return Err("Si5324 does not have expected product number");
} }
#[cfg(si5324_soft_reset)]
soft_reset()?;
write(0, read(0)? | 0x40)?; // FREE_RUN=1 write(0, read(0)? | 0x40)?; // FREE_RUN=1
write(2, (read(2)? & 0x0f) | (s.bwsel << 4))?; write(2, (read(2)? & 0x0f) | (s.bwsel << 4))?;
write(21, read(21)? & 0xfe)?; // CKSEL_PIN=0 write(21, read(21)? & 0xfe)?; // CKSEL_PIN=0