master wrpll: remove nested mmcm module
This commit is contained in:
parent
7300ecce25
commit
5aade6abb2
|
@ -552,131 +552,126 @@ pub mod wrpll {
|
||||||
pub mod sma_pll {
|
pub mod sma_pll {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
mod mmcm {
|
pub struct MmcmSetting {
|
||||||
|
pub clkout0_reg1: u16, //0x08
|
||||||
|
pub clkout0_reg2: u16, //0x09
|
||||||
|
pub clkfbout_reg1: u16, //0x14
|
||||||
|
pub clkfbout_reg2: u16, //0x15
|
||||||
|
pub div_reg: u16, //0x16
|
||||||
|
pub lock_reg1: u16, //0x18
|
||||||
|
pub lock_reg2: u16, //0x19
|
||||||
|
pub lock_reg3: u16, //0x1A
|
||||||
|
pub power_reg: u16, //0x28
|
||||||
|
pub filt_reg1: u16, //0x4E
|
||||||
|
pub filt_reg2: u16, //0x4F
|
||||||
|
}
|
||||||
|
|
||||||
use super::*;
|
fn one_clock_cycle(timer: &mut GlobalTimer) {
|
||||||
|
unsafe {
|
||||||
pub struct MmcmSetting {
|
csr::sma_pll::drp_clk_write(1);
|
||||||
pub clkout0_reg1: u16, //0x08
|
timer.delay_us(1);
|
||||||
pub clkout0_reg2: u16, //0x09
|
csr::sma_pll::drp_clk_write(0);
|
||||||
pub clkfbout_reg1: u16, //0x14
|
timer.delay_us(1);
|
||||||
pub clkfbout_reg2: u16, //0x15
|
|
||||||
pub div_reg: u16, //0x16
|
|
||||||
pub lock_reg1: u16, //0x18
|
|
||||||
pub lock_reg2: u16, //0x19
|
|
||||||
pub lock_reg3: u16, //0x1A
|
|
||||||
pub power_reg: u16, //0x28
|
|
||||||
pub filt_reg1: u16, //0x4E
|
|
||||||
pub filt_reg2: u16, //0x4F
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn one_clock_cycle(timer: &mut GlobalTimer) {
|
fn set_addr(address: u8) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::sma_pll::drp_clk_write(1);
|
csr::sma_pll::drp_addr_write(address);
|
||||||
timer.delay_us(1);
|
|
||||||
csr::sma_pll::drp_clk_write(0);
|
|
||||||
timer.delay_us(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn set_addr(address: u8) {
|
fn set_data(value: u16) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::sma_pll::drp_addr_write(address);
|
csr::sma_pll::drp_in_write(value);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn set_data(value: u16) {
|
fn set_enable(en: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::sma_pll::drp_in_write(value);
|
let val = if en { 1 } else { 0 };
|
||||||
}
|
csr::sma_pll::drp_en_write(val);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn set_enable(en: bool) {
|
fn set_write_enable(en: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let val = if en { 1 } else { 0 };
|
let val = if en { 1 } else { 0 };
|
||||||
csr::sma_pll::drp_en_write(val);
|
csr::sma_pll::drp_w_en_write(val);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn set_write_enable(en: bool) {
|
fn get_data() -> u16 {
|
||||||
unsafe {
|
unsafe { csr::sma_pll::drp_out_read() }
|
||||||
let val = if en { 1 } else { 0 };
|
}
|
||||||
csr::sma_pll::drp_w_en_write(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_data() -> u16 {
|
fn drp_ready() -> bool {
|
||||||
unsafe { csr::sma_pll::drp_out_read() }
|
unsafe { csr::sma_pll::drp_ready_read() == 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drp_ready() -> bool {
|
fn read(timer: &mut GlobalTimer, address: u8) -> u16 {
|
||||||
unsafe { csr::sma_pll::drp_ready_read() == 1 }
|
set_addr(address);
|
||||||
}
|
set_enable(true);
|
||||||
|
// Set DADDR on the MMCM and assert DEN for one clock cycle
|
||||||
|
one_clock_cycle(timer);
|
||||||
|
|
||||||
pub fn read(timer: &mut GlobalTimer, address: u8) -> u16 {
|
set_enable(false);
|
||||||
set_addr(address);
|
while !drp_ready() {
|
||||||
set_enable(true);
|
// keep the clock signal until data is ready
|
||||||
// Set DADDR on the MMCM and assert DEN for one clock cycle
|
|
||||||
one_clock_cycle(timer);
|
one_clock_cycle(timer);
|
||||||
|
|
||||||
set_enable(false);
|
|
||||||
while !drp_ready() {
|
|
||||||
// keep the clock signal until data is ready
|
|
||||||
one_clock_cycle(timer);
|
|
||||||
}
|
|
||||||
get_data()
|
|
||||||
}
|
}
|
||||||
|
get_data()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write(timer: &mut GlobalTimer, address: u8, value: u16) {
|
fn write(timer: &mut GlobalTimer, address: u8, value: u16) {
|
||||||
set_addr(address);
|
set_addr(address);
|
||||||
set_data(value);
|
set_data(value);
|
||||||
set_write_enable(true);
|
set_write_enable(true);
|
||||||
set_enable(true);
|
set_enable(true);
|
||||||
// Set DADDR, DI on the MMCM and assert DWE, DEN for one clock cycle
|
// Set DADDR, DI on the MMCM and assert DWE, DEN for one clock cycle
|
||||||
|
one_clock_cycle(timer);
|
||||||
|
|
||||||
|
set_write_enable(false);
|
||||||
|
set_enable(false);
|
||||||
|
while !drp_ready() {
|
||||||
|
// keep the clock signal until write is finished
|
||||||
one_clock_cycle(timer);
|
one_clock_cycle(timer);
|
||||||
|
|
||||||
set_write_enable(false);
|
|
||||||
set_enable(false);
|
|
||||||
while !drp_ready() {
|
|
||||||
// keep the clock signal until write is finished
|
|
||||||
one_clock_cycle(timer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reset(rst: bool) {
|
fn reset(rst: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let val = if rst { 1 } else { 0 };
|
let val = if rst { 1 } else { 0 };
|
||||||
csr::sma_pll::mmcm_reset_write(val)
|
csr::sma_pll::mmcm_reset_write(val)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn setup(timer: &mut GlobalTimer, settings: MmcmSetting) -> Result<(), &'static str> {
|
pub fn setup(timer: &mut GlobalTimer, settings: MmcmSetting) -> Result<(), &'static str> {
|
||||||
// Based on "DRP State Machine" from XAPP888
|
// Based on "DRP State Machine" from XAPP888
|
||||||
|
|
||||||
// hold reset HIGH during mmcm config
|
// hold reset HIGH during mmcm config
|
||||||
reset(true);
|
reset(true);
|
||||||
write(timer, 0x08, settings.clkout0_reg1);
|
write(timer, 0x08, settings.clkout0_reg1);
|
||||||
write(timer, 0x09, settings.clkout0_reg2);
|
write(timer, 0x09, settings.clkout0_reg2);
|
||||||
write(timer, 0x14, settings.clkfbout_reg1);
|
write(timer, 0x14, settings.clkfbout_reg1);
|
||||||
write(timer, 0x15, settings.clkfbout_reg2);
|
write(timer, 0x15, settings.clkfbout_reg2);
|
||||||
write(timer, 0x16, settings.div_reg);
|
write(timer, 0x16, settings.div_reg);
|
||||||
write(timer, 0x18, settings.lock_reg1);
|
write(timer, 0x18, settings.lock_reg1);
|
||||||
write(timer, 0x19, settings.lock_reg2);
|
write(timer, 0x19, settings.lock_reg2);
|
||||||
write(timer, 0x1A, settings.lock_reg3);
|
write(timer, 0x1A, settings.lock_reg3);
|
||||||
write(timer, 0x28, settings.power_reg);
|
write(timer, 0x28, settings.power_reg);
|
||||||
write(timer, 0x4E, settings.filt_reg1);
|
write(timer, 0x4E, settings.filt_reg1);
|
||||||
write(timer, 0x4F, settings.filt_reg2);
|
write(timer, 0x4F, settings.filt_reg2);
|
||||||
reset(false);
|
reset(false);
|
||||||
|
|
||||||
// wait for the mmcm to lock
|
// wait for the mmcm to lock
|
||||||
timer.delay_us(100);
|
timer.delay_us(100);
|
||||||
|
|
||||||
let locked = unsafe { csr::sma_pll::mmcm_locked_read() == 1 };
|
let locked = unsafe { csr::sma_pll::mmcm_locked_read() == 1 };
|
||||||
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");
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup(timer: &mut GlobalTimer) {
|
pub fn setup(timer: &mut GlobalTimer) {
|
||||||
|
|
Loading…
Reference in New Issue