master wrpll: remove nested mmcm module

This commit is contained in:
morgan 2024-02-29 16:25:03 +08:00
parent 7300ecce25
commit 5aade6abb2
1 changed files with 94 additions and 99 deletions

View File

@ -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) {