scpi: implement tst

This commit is contained in:
occheung 2020-08-31 17:43:15 +08:00
parent f60ec09b29
commit 8dbf621679
5 changed files with 102 additions and 23 deletions

View File

@ -78,6 +78,45 @@ where
Err(e) => Err(e),
}
}
/*
* Test method for Attenuators.
* Return the number of test failed.
*/
pub fn test(&mut self) -> Result<u32, Error<E>> {
// Test attenuators by getting back the attenuation
let mut error_count = 0;
// Convert cached SPI data into attenuation floats
let att_floats :[f32; 4] = [
((self.data[3] ^ 0xFC) as f32) / 8.0,
((self.data[2] ^ 0xFC) as f32) / 8.0,
((self.data[1] ^ 0xFC) as f32) / 8.0,
((self.data[0] ^ 0xFC) as f32) / 8.0,
];
// Set the attenuation to an arbitrary value, then read the attenuation
self.set_attenuation([
3.5, 9.5, 20.0, 28.5
])?;
match self.get_attenuation() {
Ok(arr) => {
if arr[0] != 3.5 {
error_count += 1;
}
if arr[1] != 9.5 {
error_count += 1;
}
if arr[2] != 20.0 {
error_count += 1;
}
if arr[3] != 28.5 {
error_count += 1;
}
},
Err(_) => return Err(Error::AttenuatorError),
};
self.set_attenuation(att_floats)?;
Ok(error_count)
}
}
impl<SPI, E> Transfer<u8> for Attenuator<SPI>

View File

@ -98,6 +98,18 @@ where
return self.set_all_configurations();
}
/*
* Test method for Configuration Register.
* Return the number of test failed.
*/
pub fn test(&mut self) -> Result<u32, Error<E>> {
// Test configuration register by getting PROTO_KEY.
match self.get_status(StatusMask::PROTO_KEY) {
Ok(8) => Ok(0),
Ok(_) => Ok(1),
Err(_) => Err(Error::ConfigRegisterError),
}
}
}
impl<SPI, E> Transfer<u8> for ConfigRegister<SPI>

View File

@ -147,26 +147,6 @@ where
// panic!("Invalid divider value for PLL!");
return Err(Error::DDSCLKError);
}
// // Select a VCO
// let vco = if divider == 1 {
// 6 // Bypass PLL if no frequency division needed
// } else if f_sys_clk > 1_150_000_000 {
// panic!("Invalid divider value for PLL!")
// } else if f_sys_clk > 820_000_000 {
// 5
// } else if f_sys_clk > 700_000_000 {
// 4
// } else if f_sys_clk > 600_000_000 {
// 3
// } else if f_sys_clk > 500_000_000 {
// 2
// } else if f_sys_clk > 420_000_000 {
// 1
// } else if f_sys_clk > 370_000_000 {
// 0
// } else {
// 7 // Bypass PLL if f_sys_clk is too low
// };
let vco = self.get_VCO_no(f_sys_clk, divider as u8)?;
self.set_configurations(&mut [
@ -368,6 +348,28 @@ where
])
}
/*
* Test method for DDS.
* Return the number of test failed.
*/
pub fn test(&mut self) -> Result<u32, Error<E>> {
// Test configuration register by getting SDIO_IN_ONLY and LSB_FIRST.
let mut error_count = 0;
let mut config_checks = [
(DDSCFRMask::SDIO_IN_ONLY, 0),
(DDSCFRMask::LSB_FIRST, 0)
];
self.get_configurations(&mut config_checks)?;
if config_checks[0].1 == 0 {
error_count += 1;
}
if config_checks[1].1 == 1 {
error_count += 1;
}
Ok(error_count)
}
}
macro_rules! impl_register_io {

View File

@ -27,6 +27,7 @@ use crate::cpld::DoOnGetRefMutData;
pub mod config_register;
use crate::config_register::ConfigRegister;
use crate::config_register::CFGMask;
use crate::config_register::StatusMask;
pub mod attenuator;
use crate::attenuator::Attenuator;
@ -117,10 +118,23 @@ where
// Clock tree reset. CPLD divides clock frequency by 4 by default.
for chip_no in 0..4 {
self.dds[chip_no].set_ref_clk_frequency(25_000_000);
self.dds[chip_no].set_ref_clk_frequency(25_000_000)?;
}
Ok(())
}
/*
* Test method fo Urukul.
* Return the number of test failed.
*/
pub fn test(&mut self) -> Result<u32, Error<E>> {
let mut count = self.config_register.test()?;
count += self.attenuator.test()?;
for chip_no in 0..4 {
count += self.dds[chip_no].test()?;
}
Ok(count)
}
}
// /*

View File

@ -68,6 +68,18 @@ where
))
}
}
fn tst(&mut self) -> Result<()> {
match self.test() {
Ok(0) => Ok(()),
Ok(_) => Err(Error::new(
ErrorCode::SelfTestFailed
)),
Err(_) => Err(Error::new(
ErrorCode::SelfTestFailed
)),
}
}
}
pub const TREE: &Node = scpi_tree![