forked from M-Labs/humpback-dds
dds: add single tone control
This commit is contained in:
parent
1d3ced0d16
commit
649b5b498b
52
src/dds.rs
52
src/dds.rs
@ -66,6 +66,7 @@ const READ_MASK :u8 = 0x80;
|
|||||||
pub struct DDS<SPI> {
|
pub struct DDS<SPI> {
|
||||||
spi: SPI,
|
spi: SPI,
|
||||||
f_ref_clk: u64,
|
f_ref_clk: u64,
|
||||||
|
f_sys_clk: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SPI, E> DDS<SPI>
|
impl<SPI, E> DDS<SPI>
|
||||||
@ -76,6 +77,7 @@ where
|
|||||||
DDS {
|
DDS {
|
||||||
spi,
|
spi,
|
||||||
f_ref_clk,
|
f_ref_clk,
|
||||||
|
f_sys_clk: f_ref_clk,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,7 +121,9 @@ where
|
|||||||
(DDSCFRMask::REFCLK_IN_DIV_BYPASS, 0),
|
(DDSCFRMask::REFCLK_IN_DIV_BYPASS, 0),
|
||||||
// Ensure divider is not reset
|
// Ensure divider is not reset
|
||||||
(DDSCFRMask::REFCLK_IN_DIV_RESETB, 1),
|
(DDSCFRMask::REFCLK_IN_DIV_RESETB, 1),
|
||||||
])
|
])?;
|
||||||
|
self.f_sys_clk = self.f_ref_clk / 2;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_normal_ref_clk(&mut self) -> Result<(), Error<E>> {
|
pub fn enable_normal_ref_clk(&mut self) -> Result<(), Error<E>> {
|
||||||
@ -130,7 +134,9 @@ where
|
|||||||
(DDSCFRMask::REFCLK_IN_DIV_BYPASS, 1),
|
(DDSCFRMask::REFCLK_IN_DIV_BYPASS, 1),
|
||||||
// Reset does not matter
|
// Reset does not matter
|
||||||
(DDSCFRMask::REFCLK_IN_DIV_RESETB, 1),
|
(DDSCFRMask::REFCLK_IN_DIV_RESETB, 1),
|
||||||
])
|
])?;
|
||||||
|
self.f_sys_clk = self.f_ref_clk;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_pll(&mut self, f_sys_clk: u64) -> Result<(), Error<E>> {
|
pub fn enable_pll(&mut self, f_sys_clk: u64) -> Result<(), Error<E>> {
|
||||||
@ -170,16 +176,19 @@ where
|
|||||||
])?;
|
])?;
|
||||||
self.set_configurations(&mut [
|
self.set_configurations(&mut [
|
||||||
(DDSCFRMask::PFD_RESET, 0),
|
(DDSCFRMask::PFD_RESET, 0),
|
||||||
])
|
])?;
|
||||||
|
self.f_sys_clk = self.f_ref_clk * divider;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change external clock source (ref_clk)
|
// Change external clock source (ref_clk)
|
||||||
pub fn set_ref_clk_frequency(&mut self, f_ref_clk: u64) {
|
pub fn set_ref_clk_frequency(&mut self, f_ref_clk: u64) {
|
||||||
self.f_ref_clk = f_ref_clk;
|
self.f_ref_clk = f_ref_clk;
|
||||||
|
// TODO: Examine clock tree and update f_sys_clk
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Impleement configurations registers I/O through bitmasks
|
* Implement configurations registers I/O through bitmasks
|
||||||
*
|
*
|
||||||
* Get all (cfr1, cfr2, cfr3) contents
|
* Get all (cfr1, cfr2, cfr3) contents
|
||||||
*/
|
*/
|
||||||
@ -246,6 +255,41 @@ where
|
|||||||
self.set_all_configurations(data_array.clone())
|
self.set_all_configurations(data_array.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a single tone profile
|
||||||
|
* Phase: Expressed in positive degree
|
||||||
|
* Frequency: Must be integer
|
||||||
|
* Amplitude: In a scale from 0 to 1, taking float
|
||||||
|
*/
|
||||||
|
pub fn set_single_tone_profile(&mut self, profile: u8, f_out: u64, phase_offset: f64, amp_scale_factor: f64) -> Result<(), Error<E>> {
|
||||||
|
|
||||||
|
assert!(profile < 8);
|
||||||
|
assert!(phase_offset >= 0.0 && phase_offset < 360.0);
|
||||||
|
assert!(amp_scale_factor >=0.0 && amp_scale_factor <= 1.0);
|
||||||
|
|
||||||
|
let resolutions :[u64; 3] = [1 << 32, 1 << 16, 1 << 14];
|
||||||
|
let ftw = (resolutions[0] * f_out / self.f_sys_clk) as u32;
|
||||||
|
let pow = ((resolutions[1] as f64) * phase_offset / 360.0) as u16;
|
||||||
|
let asf = ((resolutions[2] as f64) * amp_scale_factor) as u16;
|
||||||
|
// Setup configuration registers before writing single tone register
|
||||||
|
self.set_configurations(&mut [
|
||||||
|
(DDSCFRMask::RAM_ENABLE, 0),
|
||||||
|
(DDSCFRMask::DIGITAL_RAMP_ENABLE, 0),
|
||||||
|
(DDSCFRMask::PARALLEL_DATA_PORT_ENABLE, 0),
|
||||||
|
])?;
|
||||||
|
// Transfer single tone profile data
|
||||||
|
self.write_register(0x0E + profile, &mut [
|
||||||
|
((asf >> 8 ) & 0xFF) as u8,
|
||||||
|
((asf >> 0 ) & 0xFF) as u8,
|
||||||
|
((pow >> 8 ) & 0xFF) as u8,
|
||||||
|
((pow >> 0 ) & 0xFF) as u8,
|
||||||
|
((ftw >> 24) & 0xFF) as u8,
|
||||||
|
((ftw >> 16) & 0xFF) as u8,
|
||||||
|
((ftw >> 8 ) & 0xFF) as u8,
|
||||||
|
((ftw >> 0 ) & 0xFF) as u8,
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_register_io {
|
macro_rules! impl_register_io {
|
||||||
|
Loading…
Reference in New Issue
Block a user