firmware/ad9154: combine analog and digital delay of hmc7043 for sysref scan

This commit is contained in:
Florent Kermarrec 2018-04-27 14:32:03 +02:00
parent fe9834bac4
commit 4e2d9abaf7
2 changed files with 26 additions and 22 deletions

View File

@ -1,6 +1,6 @@
use board::{csr, clock}; use board::{csr, clock};
use ad9154_reg; use ad9154_reg;
use hmc830_7043::{hmc7043}; use hmc830_7043::hmc7043;
fn spi_setup(dacno: u8) { fn spi_setup(dacno: u8) {
unsafe { unsafe {
@ -611,39 +611,39 @@ fn dac_cfg_retry(dacno: u8) -> Result<(), &'static str> {
fn dac_sysref_cfg(dacno: u8) { fn dac_sysref_cfg(dacno: u8) {
let mut sync_error: u16 = 0; let mut sync_error: u16 = 0;
let mut sync_error_last: u16 = 0; let mut sync_error_last: u16 = 0;
let mut cphase_min_found: bool = false; let mut phase_min_found: bool = false;
let mut cphase_min: u8 = 0; let mut phase_min: u16 = 0;
let mut cphase_max_found: bool = false; let mut phase_max_found: bool = false;
let mut cphase_max: u8 = 0; let mut phase_max: u16 = 0;
let mut cphase_opt: u8 = 0; let mut phase_opt: u16 = 0;
info!("AD9154-{} SYSREF scan/conf...", dacno); info!("AD9154-{} SYSREF scan/conf...", dacno);
for cphase in 0..32 { for phase in 0..512 {
hmc7043::cfg_dac_sysref(dacno, 0, cphase); hmc7043::cfg_dac_sysref(dacno, phase);
clock::spin_us(10000); clock::spin_us(10000);
spi_setup(dacno); spi_setup(dacno);
sync_error = ((read(ad9154_reg::SYNC_CURRERR_L) as u16) | sync_error = ((read(ad9154_reg::SYNC_CURRERR_L) as u16) |
((read(ad9154_reg::SYNC_CURRERR_H) as u16) << 8)) ((read(ad9154_reg::SYNC_CURRERR_H) as u16) << 8))
& 0x1ff; & 0x1ff;
info!(" cphase: {}, sync error: {}", cphase, sync_error); info!(" phase: {}, sync error: {}", phase, sync_error);
if sync_error != 0 { if sync_error != 0 {
if cphase_min_found { if phase_min_found {
if sync_error != sync_error_last { if sync_error != sync_error_last {
cphase_max_found = true; phase_max_found = true;
cphase_max = cphase - 1; phase_max = phase - 1;
break; break;
} }
} else { } else {
cphase_min_found = true; phase_min_found = true;
cphase_min = cphase; phase_min = phase;
} }
} }
sync_error_last = sync_error; sync_error_last = sync_error;
} }
cphase_opt = cphase_min + (cphase_max-cphase_min)/2; phase_opt = phase_min + (phase_max-phase_min)/2;
info!(" cphase min: {}, cphase max: {}, cphase opt: {}", cphase_min, cphase_max, cphase_opt); info!(" phase min: {}, phase max: {}, phase opt: {}", phase_min, phase_max, phase_opt);
hmc7043::cfg_dac_sysref(dacno, 0, cphase_opt); hmc7043::cfg_dac_sysref(dacno, phase_opt);
} }
pub fn init() -> Result<(), &'static str> { pub fn init() -> Result<(), &'static str> {

View File

@ -250,14 +250,18 @@ pub mod hmc7043 {
Ok(()) Ok(())
} }
pub fn cfg_dac_sysref(dacno: u8, aphase: u8, cphase: u8) { pub fn cfg_dac_sysref(dacno: u8, phase: u16) {
spi_setup(); spi_setup();
/* Analog delay resolution: 25ps
* Digital delay resolution: 1/2 input clock cycle = 416ps for 1.2GHz
* 16*25ps = 400ps: limit analog delay to 16 steps instead of 32.
*/
if dacno == 0 { if dacno == 0 {
write(0x00D5, aphase); write(0x00d5, (phase & 0xf) as u8);
write(0x00D6, cphase); write(0x00d6, ((phase >> 4) & 0x1f) as u8);
} else if dacno == 1 { } else if dacno == 1 {
write(0x00E9, aphase); write(0x00e9, (phase & 0xf) as u8);
write(0x00EA, cphase); write(0x00ea, ((phase >> 4) & 0x1f) as u8);
} else { } else {
unimplemented!(); unimplemented!();
} }