forked from M-Labs/artiq-zynq
FIQ_issue
This commit is contained in:
parent
f8f6dcef14
commit
adaecf87a8
|
@ -231,6 +231,7 @@ class GenericMaster(SoCCore):
|
||||||
pads=data_pads,
|
pads=data_pads,
|
||||||
clk_freq=clk_freq)
|
clk_freq=clk_freq)
|
||||||
self.csr_devices.append("gt_drtio")
|
self.csr_devices.append("gt_drtio")
|
||||||
|
self.config["RTIO_FREQUENCY"] = str(clk_freq/1e6)
|
||||||
self.config["CLOCK_FREQUENCY"] = int(clk_freq)
|
self.config["CLOCK_FREQUENCY"] = int(clk_freq)
|
||||||
|
|
||||||
txout_buf = Signal()
|
txout_buf = Signal()
|
||||||
|
@ -259,10 +260,17 @@ class GenericMaster(SoCCore):
|
||||||
|
|
||||||
if with_wrpll:
|
if with_wrpll:
|
||||||
self.submodules.wrpll_refclk = wrpll.SMAFrequencyMultiplier(platform.request("sma_clkin"))
|
self.submodules.wrpll_refclk = wrpll.SMAFrequencyMultiplier(platform.request("sma_clkin"))
|
||||||
self.csr_devices.append("wrpll_refclk")
|
|
||||||
|
|
||||||
self.submodules.main_dcxo = si549.Si549(platform.request("ddmtd_main_dcxo_i2c"))
|
self.submodules.main_dcxo = si549.Si549(platform.request("ddmtd_main_dcxo_i2c"))
|
||||||
|
self.submodules.helper_dcxo = si549.Si549(platform.request("ddmtd_helper_dcxo_i2c"))
|
||||||
|
self.submodules.wrpll = wrpll.WRPLL(
|
||||||
|
cd_ref=self.wrpll_refclk.cd_ref,
|
||||||
|
main_dcxo_pads=platform.request("cdr_clk_clean_fabric"),
|
||||||
|
helper_dcxo_pads=platform.request("ddmtd_helper_clk"))
|
||||||
|
self.csr_devices.append("wrpll_refclk")
|
||||||
self.csr_devices.append("main_dcxo")
|
self.csr_devices.append("main_dcxo")
|
||||||
|
self.csr_devices.append("helper_dcxo")
|
||||||
|
self.csr_devices.append("wrpll")
|
||||||
|
self.comb += self.ps7.core.core0.nfiq.eq(self.wrpll.ev.irq)
|
||||||
self.config["HAS_SI549"] = None
|
self.config["HAS_SI549"] = None
|
||||||
self.config["WRPLL_REF_CLK"] = "SMA_CLKIN"
|
self.config["WRPLL_REF_CLK"] = "SMA_CLKIN"
|
||||||
else:
|
else:
|
||||||
|
@ -612,7 +620,7 @@ def main():
|
||||||
help="build gateware into the specified directory")
|
help="build gateware into the specified directory")
|
||||||
parser.add_argument("--acpki", default=False, action="store_true",
|
parser.add_argument("--acpki", default=False, action="store_true",
|
||||||
help="enable ACPKI")
|
help="enable ACPKI")
|
||||||
parser.add_argument("--with-wrpll", default=False, action="store_true",
|
parser.add_argument("--with-wrpll", default=True, action="store_true",
|
||||||
help="enable WRPLL")
|
help="enable WRPLL")
|
||||||
parser.add_argument("description", metavar="DESCRIPTION",
|
parser.add_argument("description", metavar="DESCRIPTION",
|
||||||
help="JSON system description file")
|
help="JSON system description file")
|
||||||
|
|
|
@ -60,7 +60,7 @@ class WRPLL(Module, AutoCSR):
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
self.helper_reset = CSRStorage(reset=1)
|
self.helper_reset = CSRStorage()
|
||||||
self.clock_domains.cd_helper = ClockDomain()
|
self.clock_domains.cd_helper = ClockDomain()
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance("IBUFGDS",
|
Instance("IBUFGDS",
|
||||||
|
@ -131,6 +131,7 @@ class SMAFrequencyMultiplier(Module, AutoCSR):
|
||||||
freq = 125e6
|
freq = 125e6
|
||||||
period = 1e9/freq # ns
|
period = 1e9/freq # ns
|
||||||
|
|
||||||
|
sma_clkin_se = Signal()
|
||||||
mmcm_locked = Signal()
|
mmcm_locked = Signal()
|
||||||
mmcm_fb_clk = Signal()
|
mmcm_fb_clk = Signal()
|
||||||
ref_clk = Signal()
|
ref_clk = Signal()
|
||||||
|
@ -150,6 +151,9 @@ class SMAFrequencyMultiplier(Module, AutoCSR):
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
self.specials += [
|
self.specials += [
|
||||||
|
Instance("IBUFDS",
|
||||||
|
i_I=sma_clkin.p, i_IB=sma_clkin.n,
|
||||||
|
o_O=sma_clkin_se),
|
||||||
# MMCME2 is capable to accept 10Mhz input while PLLE2 only support down to 19Mhz input (DS191)
|
# MMCME2 is capable to accept 10Mhz input while PLLE2 only support down to 19Mhz input (DS191)
|
||||||
Instance("MMCME2_ADV",
|
Instance("MMCME2_ADV",
|
||||||
p_BANDWIDTH="LOW", # lower jitter
|
p_BANDWIDTH="LOW", # lower jitter
|
||||||
|
@ -157,7 +161,7 @@ class SMAFrequencyMultiplier(Module, AutoCSR):
|
||||||
i_RST=self.mmcm_reset.storage,
|
i_RST=self.mmcm_reset.storage,
|
||||||
|
|
||||||
p_CLKIN1_PERIOD=period,
|
p_CLKIN1_PERIOD=period,
|
||||||
i_CLKIN1=ClockSignal("sys"),
|
i_CLKIN1=sma_clkin_se,
|
||||||
i_CLKINSEL=1, # 1=CLKIN1 0=CLKIN2
|
i_CLKINSEL=1, # 1=CLKIN1 0=CLKIN2
|
||||||
|
|
||||||
# VCO @ 1.25Ghz
|
# VCO @ 1.25Ghz
|
||||||
|
@ -178,7 +182,4 @@ class SMAFrequencyMultiplier(Module, AutoCSR):
|
||||||
),
|
),
|
||||||
Instance("BUFG", i_I=ref_clk, o_O=self.cd_ref.clk),
|
Instance("BUFG", i_I=ref_clk, o_O=self.cd_ref.clk),
|
||||||
AsyncResetSynchronizer(self.cd_ref, ~self.mmcm_locked.status),
|
AsyncResetSynchronizer(self.cd_ref, ~self.mmcm_locked.status),
|
||||||
|
|
||||||
# debug output
|
|
||||||
Instance("OBUFDS", i_I=self.cd_ref.clk, o_O=sma_clkin.p, o_OB=sma_clkin.n)
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,12 +7,14 @@ use crate::pl::csr;
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
const ADDRESS: u8 = 0x67;
|
const ADDRESS: u8 = 0x67;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct DividerConfig {
|
pub struct DividerConfig {
|
||||||
pub hsdiv: u16,
|
pub hsdiv: u16,
|
||||||
pub lsdiv: u8,
|
pub lsdiv: u8,
|
||||||
pub fbdiv: u64,
|
pub fbdiv: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct FrequencySetting {
|
pub struct FrequencySetting {
|
||||||
pub main: DividerConfig,
|
pub main: DividerConfig,
|
||||||
#[cfg(has_wrpll)]
|
#[cfg(has_wrpll)]
|
||||||
|
@ -272,6 +274,7 @@ pub fn main_setup(timer: &mut GlobalTimer, settings: FrequencySetting) -> Result
|
||||||
#[cfg(has_wrpll)]
|
#[cfg(has_wrpll)]
|
||||||
pub mod wrpll {
|
pub mod wrpll {
|
||||||
|
|
||||||
|
use embedded_hal::blocking::delay::DelayMs;
|
||||||
use libcortex_a9::mutex::Mutex;
|
use libcortex_a9::mutex::Mutex;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -376,6 +379,8 @@ pub mod wrpll {
|
||||||
csr::helper_dcxo::bitbang_enable_write(0);
|
csr::helper_dcxo::bitbang_enable_write(0);
|
||||||
}
|
}
|
||||||
info!("Helper Si549 started");
|
info!("Helper Si549 started");
|
||||||
|
|
||||||
|
timer.delay_ms(5_000);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,12 +451,15 @@ pub mod wrpll {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_freq_counts(timer: &mut GlobalTimer) -> (u32, u32) {
|
pub fn get_freq_counts(timer: &mut GlobalTimer) -> (u32, u32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::wrpll::frequency_counter_update_en_write(1);
|
csr::wrpll::frequency_counter_update_en_write(1);
|
||||||
timer.delay_us(150_000); // 8ns << TIMER_WIDTH
|
timer.delay_us(150_000); // 8ns << TIMER_WIDTH
|
||||||
csr::wrpll::frequency_counter_update_en_write(0);
|
csr::wrpll::frequency_counter_update_en_write(0);
|
||||||
let ref_count = csr::wrpll::frequency_counter_counter_gtx0_rtio_rx_read();
|
#[cfg(wrpll_ref_clk = "GTX_CDR")]
|
||||||
|
let ref_count = csr::wrpll::frequency_counter_counter_rtio_rx0_read();
|
||||||
|
#[cfg(wrpll_ref_clk = "SMA_CLKIN")]
|
||||||
|
let ref_count = csr::wrpll::frequency_counter_counter_ref_read();
|
||||||
let main_count = csr::wrpll::frequency_counter_counter_sys_read();
|
let main_count = csr::wrpll::frequency_counter_counter_sys_read();
|
||||||
|
|
||||||
(ref_count, main_count)
|
(ref_count, main_count)
|
||||||
|
@ -500,6 +508,21 @@ pub mod wrpll {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn helper_pll() -> Result<(), &'static str> {
|
fn helper_pll() -> Result<(), &'static str> {
|
||||||
|
// unsafe {
|
||||||
|
// use libboard_zynq::println;
|
||||||
|
|
||||||
|
// ERR_ARR[COUNTER] = tag_collector::get_period_error();
|
||||||
|
|
||||||
|
// if COUNTER == SIZE - 1 {
|
||||||
|
// for i in 0..SIZE {
|
||||||
|
// println!("{}", ERR_ARR[i])
|
||||||
|
// }
|
||||||
|
// COUNTER = 0;
|
||||||
|
// let mut timer = GlobalTimer::get();
|
||||||
|
// timer.delay_us(20_000_000);
|
||||||
|
// }
|
||||||
|
// COUNTER += 1;
|
||||||
|
// }
|
||||||
let period_err = tag_collector::get_period_error();
|
let period_err = tag_collector::get_period_error();
|
||||||
let mut integrator_lock = H_INTEGRATOR.lock();
|
let mut integrator_lock = H_INTEGRATOR.lock();
|
||||||
|
|
||||||
|
@ -512,7 +535,29 @@ pub mod wrpll {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SIZE: usize = 2000;
|
||||||
|
static mut COUNTER: usize = 0;
|
||||||
|
static mut ERR_ARR: [i32; SIZE] = [0; SIZE];
|
||||||
|
static mut FIN_ADPLL: i32 = 0;
|
||||||
|
|
||||||
fn main_pll() -> Result<(), &'static str> {
|
fn main_pll() -> Result<(), &'static str> {
|
||||||
|
// unsafe {
|
||||||
|
// use libboard_zynq::println;
|
||||||
|
|
||||||
|
// ERR_ARR[COUNTER] = tag_collector::get_phase_error();
|
||||||
|
|
||||||
|
// if COUNTER == SIZE - 1 {
|
||||||
|
// for i in 0..SIZE {
|
||||||
|
// println!("{}", ERR_ARR[i])
|
||||||
|
// }
|
||||||
|
// println!("{:>3} Zero crossing adpll = {:>5}", SIZE, FIN_ADPLL);
|
||||||
|
// COUNTER = 0;
|
||||||
|
// let mut timer = GlobalTimer::get();
|
||||||
|
// timer.delay_us(20_000_000);
|
||||||
|
// }
|
||||||
|
// COUNTER += 1;
|
||||||
|
// }
|
||||||
|
|
||||||
let phase_err = tag_collector::get_phase_error();
|
let phase_err = tag_collector::get_phase_error();
|
||||||
let mut integrator_lock = M_INTEGRATOR.lock();
|
let mut integrator_lock = M_INTEGRATOR.lock();
|
||||||
|
|
||||||
|
@ -522,6 +567,12 @@ pub mod wrpll {
|
||||||
m_adpll = m_adpll.clamp(-ADPLL_MAX, ADPLL_MAX);
|
m_adpll = m_adpll.clamp(-ADPLL_MAX, ADPLL_MAX);
|
||||||
set_adpll(i2c::DCXO::Main, m_adpll)?;
|
set_adpll(i2c::DCXO::Main, m_adpll)?;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
if ERR_ARR[COUNTER] == 0 {
|
||||||
|
FIN_ADPLL = m_adpll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,18 +583,50 @@ pub mod wrpll {
|
||||||
tag_collector::reset();
|
tag_collector::reset();
|
||||||
reset_plls().expect("failed to reset main and helper PLL");
|
reset_plls().expect("failed to reset main and helper PLL");
|
||||||
|
|
||||||
info!("warming up GTX CDR...");
|
info!("warming up refclk...");
|
||||||
// gtx need a couple seconds for freq counter to read it properly
|
// refclk need a couple seconds for freq counter to read it properly
|
||||||
timer.delay_us(20_000_000);
|
// timer.delay_us(20_000_000);
|
||||||
set_base_adpll(timer).expect("failed to set base adpll");
|
set_base_adpll(timer).expect("failed to set base adpll");
|
||||||
|
|
||||||
|
let ppm = 0.0;
|
||||||
|
*BASE_ADPLL.lock() += (ppm / 0.0001164) as i32;
|
||||||
|
timer.delay_us(200);
|
||||||
|
info!("KP = {}, KI = {}", KP, KI);
|
||||||
|
info!("adding {}ppm to main & helper base adpll ({})", ppm, *BASE_ADPLL.lock());
|
||||||
|
|
||||||
// clear gateware pending flag
|
// clear gateware pending flag
|
||||||
clear_pending(FIQ::RefTag);
|
clear_pending(FIQ::RefTag);
|
||||||
clear_pending(FIQ::MainTag);
|
clear_pending(FIQ::MainTag);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
info!("ref tag = {} ", csr::wrpll::ref_tag_read());
|
||||||
|
info!("main tag = {} ", csr::wrpll::main_tag_read());
|
||||||
|
}
|
||||||
|
|
||||||
// use nFIQ to avoid IRQ being disabled by mutex lock and mess up PLL
|
// use nFIQ to avoid IRQ being disabled by mutex lock and mess up PLL
|
||||||
set_fiq(true);
|
set_fiq(true);
|
||||||
info!("WRPLL interrupt enabled");
|
info!("WRPLL interrupt enabled");
|
||||||
|
|
||||||
|
timer.delay_ms(500);
|
||||||
|
unsafe {
|
||||||
|
info!("main_tag_ev_enable_read() = {}", csr::wrpll::main_tag_ev_enable_read());
|
||||||
|
info!("main_tag_ev_status_read() = {}", csr::wrpll::main_tag_ev_status_read());
|
||||||
|
info!("ref_tag_ev_enable_read() = {}", csr::wrpll::ref_tag_ev_enable_read());
|
||||||
|
info!("ref_tag_ev_status_read() = {}", csr::wrpll::ref_tag_ev_status_read());
|
||||||
|
|
||||||
|
// loop {
|
||||||
|
// if is_pending(FIQ::RefTag) {
|
||||||
|
// info!("REF tag is pending")
|
||||||
|
// }
|
||||||
|
// if is_pending(FIQ::MainTag) {
|
||||||
|
// info!("Main tag is pending")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // info!("ref tag = {} ", csr::wrpll::ref_tag_read());
|
||||||
|
// // info!("main tag = {} ", csr::wrpll::main_tag_read());
|
||||||
|
// timer.delay_ms(500);
|
||||||
|
// }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -671,13 +754,25 @@ pub mod wrpll_refclk {
|
||||||
if !locked {
|
if !locked {
|
||||||
return Err("failed to generate 125Mhz ref clock from SMA CLKIN");
|
return Err("failed to generate 125Mhz ref clock from SMA CLKIN");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// const TIMER_WIDTH: u32 = 24;
|
||||||
|
// const COUNTER_DIV: u32 = 2;
|
||||||
|
|
||||||
|
// let (ref_count, main_count) = wrpll::get_freq_counts(timer);
|
||||||
|
|
||||||
|
// let f_sys = 125e6;
|
||||||
|
|
||||||
|
// info!(
|
||||||
|
// "ref counter = {} freq = {}",
|
||||||
|
// ref_count,
|
||||||
|
// (ref_count as f64 * f_sys) as f64 / (1 << (TIMER_WIDTH - COUNTER_DIV)) as f64
|
||||||
|
// );
|
||||||
|
// info!(
|
||||||
|
// "Main counter = {} freq = {}",
|
||||||
|
// main_count,
|
||||||
|
// (main_count as f64 * f_sys) as f64 / (1 << (TIMER_WIDTH - COUNTER_DIV)) as f64
|
||||||
|
// );
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup(timer: &mut GlobalTimer) {
|
|
||||||
for addr in 7..12 {
|
|
||||||
info!("address = {:#x} | val = {:016b}", addr, mmcm::read(timer, addr));
|
|
||||||
}
|
|
||||||
info!("running SMA PLL");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ use libcortex_a9::{interrupt_handler, regs::MPIDR};
|
||||||
use libregister::RegisterR;
|
use libregister::RegisterR;
|
||||||
|
|
||||||
interrupt_handler!(FIQ, fiq, __irq_stack0_start, __irq_stack1_start, {
|
interrupt_handler!(FIQ, fiq, __irq_stack0_start, __irq_stack1_start, {
|
||||||
|
// println!("hello?");
|
||||||
match MPIDR.read().cpu_id() {
|
match MPIDR.read().cpu_id() {
|
||||||
0 => {
|
0 => {
|
||||||
// nFIQ is driven directly and bypass GIC
|
// nFIQ is driven directly and bypass GIC
|
||||||
|
|
|
@ -6,6 +6,8 @@ use libboard_artiq::pl;
|
||||||
use libboard_artiq::si5324;
|
use libboard_artiq::si5324;
|
||||||
#[cfg(has_si549)]
|
#[cfg(has_si549)]
|
||||||
use libboard_artiq::si549;
|
use libboard_artiq::si549;
|
||||||
|
#[cfg(has_wrpll)]
|
||||||
|
use libboard_artiq::si549::wrpll_refclk;
|
||||||
#[cfg(has_si5324)]
|
#[cfg(has_si5324)]
|
||||||
use libboard_zynq::i2c::I2c;
|
use libboard_zynq::i2c::I2c;
|
||||||
use libboard_zynq::timer::GlobalTimer;
|
use libboard_zynq::timer::GlobalTimer;
|
||||||
|
@ -262,46 +264,137 @@ fn setup_si5324(i2c: &mut I2c, timer: &mut GlobalTimer, clk: RtioClock) {
|
||||||
si5324::setup(i2c, &si5324_settings, si5324_ref_input, timer).expect("cannot initialize Si5324");
|
si5324::setup(i2c, &si5324_settings, si5324_ref_input, timer).expect("cannot initialize Si5324");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_si549)]
|
#[cfg(has_wrpll)]
|
||||||
fn setup_si549(timer: &mut GlobalTimer, clk: RtioClock) {
|
fn wrpll_setup(timer: &mut GlobalTimer, clk: RtioClock, si549_settings: si549::FrequencySetting) {
|
||||||
let si549_settings = match clk {
|
let mmcm_setting = match clk {
|
||||||
|
RtioClock::Ext0_Synth0_10to125 => si549::wrpll_refclk::MmcmSetting {
|
||||||
|
clkout0_reg1: 0x1083,
|
||||||
|
clkout0_reg2: 0x0080,
|
||||||
|
clkfbout_reg1: 0x179e,
|
||||||
|
clkfbout_reg2: 0x4c00,
|
||||||
|
div_reg: 0x1041,
|
||||||
|
lock_reg1: 0x00fa,
|
||||||
|
lock_reg2: 0x7c01,
|
||||||
|
lock_reg3: 0xffe9,
|
||||||
|
power_reg: 0x9900,
|
||||||
|
filt_reg1: 0x0808,
|
||||||
|
filt_reg2: 0x0800,
|
||||||
|
},
|
||||||
|
RtioClock::Ext0_Synth0_80to125 => si549::wrpll_refclk::MmcmSetting {
|
||||||
|
clkout0_reg1: 0x1145,
|
||||||
|
clkout0_reg2: 0x0000,
|
||||||
|
clkfbout_reg1: 0x11c7,
|
||||||
|
clkfbout_reg2: 0x5880,
|
||||||
|
div_reg: 0x1041,
|
||||||
|
lock_reg1: 0x028a,
|
||||||
|
lock_reg2: 0x7c01,
|
||||||
|
lock_reg3: 0xffe9,
|
||||||
|
power_reg: 0x9900,
|
||||||
|
filt_reg1: 0x0808,
|
||||||
|
filt_reg2: 0x9800,
|
||||||
|
},
|
||||||
|
RtioClock::Ext0_Synth0_100to125 => si549::wrpll_refclk::MmcmSetting {
|
||||||
|
clkout0_reg1: 0x1145,
|
||||||
|
clkout0_reg2: 0x0000,
|
||||||
|
clkfbout_reg1: 0x1145,
|
||||||
|
clkfbout_reg2: 0x4c00,
|
||||||
|
div_reg: 0x1041,
|
||||||
|
lock_reg1: 0x0339,
|
||||||
|
lock_reg2: 0x7c01,
|
||||||
|
lock_reg3: 0xffe9,
|
||||||
|
power_reg: 0x9900,
|
||||||
|
filt_reg1: 0x0808,
|
||||||
|
filt_reg2: 0x9800,
|
||||||
|
},
|
||||||
|
RtioClock::Ext0_Synth0_125to125 => si549::wrpll_refclk::MmcmSetting {
|
||||||
|
clkout0_reg1: 0x1145,
|
||||||
|
clkout0_reg2: 0x0000,
|
||||||
|
clkfbout_reg1: 0x1145,
|
||||||
|
clkfbout_reg2: 0x0000,
|
||||||
|
div_reg: 0x1041,
|
||||||
|
lock_reg1: 0x03e8,
|
||||||
|
lock_reg2: 0x7001,
|
||||||
|
lock_reg3: 0xf3e9,
|
||||||
|
power_reg: 0x0100,
|
||||||
|
filt_reg1: 0x0808,
|
||||||
|
filt_reg2: 0x1100,
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
si549::main_setup(timer, si549_settings).expect("cannot initialize main Si549");
|
||||||
|
si549::wrpll::helper_setup(timer, si549_settings).expect("cannot initialize helper Si549");
|
||||||
|
|
||||||
|
si549::wrpll_refclk::setup(timer, mmcm_setting).expect("cannot initialize ref clk for wrpll");
|
||||||
|
// si549::wrpll::select_recovered_clock(true, timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_si549_setting(clk: RtioClock) -> si549::FrequencySetting {
|
||||||
|
match clk {
|
||||||
|
RtioClock::Ext0_Synth0_10to125 => {
|
||||||
|
info!("using 10MHz reference to make 125MHz RTIO clock with WRPLL");
|
||||||
|
}
|
||||||
|
RtioClock::Ext0_Synth0_80to125 => {
|
||||||
|
info!("using 80MHz reference to make 125MHz RTIO clock with WRPLL");
|
||||||
|
}
|
||||||
|
RtioClock::Ext0_Synth0_100to125 => {
|
||||||
|
info!("using 100MHz reference to make 125MHz RTIO clock with WRPLL");
|
||||||
|
}
|
||||||
|
RtioClock::Ext0_Synth0_125to125 => {
|
||||||
|
info!("using 125MHz reference to make 125MHz RTIO clock with WRPLL");
|
||||||
|
}
|
||||||
|
RtioClock::Int_150 => {
|
||||||
|
info!("using internal 150MHz RTIO clock");
|
||||||
|
}
|
||||||
RtioClock::Int_100 => {
|
RtioClock::Int_100 => {
|
||||||
info!("using internal 100MHz RTIO clock");
|
info!("using internal 100MHz RTIO clock");
|
||||||
|
}
|
||||||
|
RtioClock::Int_125 => {
|
||||||
|
info!("using internal 125MHz RTIO clock");
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
warn!(
|
||||||
|
"rtio_clock setting '{:?}' is unsupported. Falling back to default internal 125MHz RTIO clock.",
|
||||||
|
clk
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match clk {
|
||||||
|
RtioClock::Int_100 => {
|
||||||
si549::FrequencySetting {
|
si549::FrequencySetting {
|
||||||
main: si549::DividerConfig {
|
main: si549::DividerConfig {
|
||||||
hsdiv: 0x06C,
|
hsdiv: 0x06C,
|
||||||
lsdiv: 0,
|
lsdiv: 0,
|
||||||
fbdiv: 0x046C5F49797,
|
fbdiv: 0x046C5F49797,
|
||||||
},
|
},
|
||||||
}
|
#[cfg(has_wrpll)]
|
||||||
}
|
helper: si549::DividerConfig {
|
||||||
RtioClock::Int_125 => {
|
// 100Mhz*32767/32768
|
||||||
info!("using internal 125MHz RTIO clock");
|
hsdiv: 0x06C,
|
||||||
si549::FrequencySetting {
|
|
||||||
main: si549::DividerConfig {
|
|
||||||
hsdiv: 0x058,
|
|
||||||
lsdiv: 0,
|
lsdiv: 0,
|
||||||
fbdiv: 0x04815791F25,
|
fbdiv: 0x046C5670BBD,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// same setting as Int_125, but fallback to default
|
// Everything else use 125Mhz
|
||||||
warn!(
|
|
||||||
"rtio_clock setting '{:?}' is unsupported. Falling back to default 125MHz RTIO clock.",
|
|
||||||
clk
|
|
||||||
);
|
|
||||||
si549::FrequencySetting {
|
si549::FrequencySetting {
|
||||||
main: si549::DividerConfig {
|
main: si549::DividerConfig {
|
||||||
hsdiv: 0x058,
|
hsdiv: 0x058,
|
||||||
lsdiv: 0,
|
lsdiv: 0,
|
||||||
fbdiv: 0x04815791F25,
|
fbdiv: 0x04815791F25,
|
||||||
},
|
},
|
||||||
|
#[cfg(has_wrpll)]
|
||||||
|
helper: si549::DividerConfig {
|
||||||
|
// 125Mhz*32767/32768
|
||||||
|
hsdiv: 0x058,
|
||||||
|
lsdiv: 0,
|
||||||
|
fbdiv: 0x04814E8F442,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
si549::main_setup(timer, si549_settings).expect("cannot initialize main Si549");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(timer: &mut GlobalTimer, cfg: &Config) {
|
pub fn init(timer: &mut GlobalTimer, cfg: &Config) {
|
||||||
|
@ -317,10 +410,23 @@ pub fn init(timer: &mut GlobalTimer, cfg: &Config) {
|
||||||
_ => setup_si5324(i2c, timer, clk),
|
_ => setup_si5324(i2c, timer, clk),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_si549)]
|
#[cfg(has_si549)]
|
||||||
{
|
{
|
||||||
si549::sma_pll::setup(timer);
|
let si549_settings = get_si549_setting(clk);
|
||||||
setup_si549(timer, clk);
|
|
||||||
|
match clk {
|
||||||
|
RtioClock::Ext0_Synth0_10to125
|
||||||
|
| RtioClock::Ext0_Synth0_80to125
|
||||||
|
| RtioClock::Ext0_Synth0_100to125
|
||||||
|
| RtioClock::Ext0_Synth0_125to125 => {
|
||||||
|
wrpll_setup(timer, clk, si549_settings);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
wrpll_setup(timer, RtioClock::Ext0_Synth0_125to125, si549_settings);
|
||||||
|
// si549::main_setup(timer, si549_settings).expect("cannot initialize main Si549");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
|
@ -328,4 +434,7 @@ pub fn init(timer: &mut GlobalTimer, cfg: &Config) {
|
||||||
|
|
||||||
#[cfg(not(has_drtio))]
|
#[cfg(not(has_drtio))]
|
||||||
init_rtio(timer);
|
init_rtio(timer);
|
||||||
|
|
||||||
|
// !! move back to cfg after testing
|
||||||
|
si549::wrpll::select_recovered_clock(true, timer);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue