urukul: failsave for PLL timeout
This commit is contained in:
parent
adc5807ff1
commit
f1069d951d
33
src/dds.rs
33
src/dds.rs
@ -253,7 +253,12 @@ where
|
||||
}
|
||||
// Finally, try enabling PLL
|
||||
else {
|
||||
self.enable_pll(f_sys_clk)
|
||||
self.enable_pll(f_sys_clk)?;
|
||||
if self.f_sys_clk == self.get_sys_clk_frequency()? {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::WaitRetry)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -844,6 +849,32 @@ where
|
||||
pub fn get_f_sys_clk(&mut self) -> f64 {
|
||||
self.f_sys_clk
|
||||
}
|
||||
|
||||
// Acquire real f_sys_clk
|
||||
pub fn get_sys_clk_frequency(&mut self) -> Result<f64, Error<E>> {
|
||||
// Calculate the new system clock frequency, examine the clock tree
|
||||
let mut configuration_queries = [
|
||||
// Acquire PLL status
|
||||
(DDSCFRMask::PLL_ENABLE, 0),
|
||||
// Acquire N-divider, to adjust VCO if necessary
|
||||
(DDSCFRMask::N, 0),
|
||||
// Acquire REF_CLK divider bypass
|
||||
(DDSCFRMask::REFCLK_IN_DIV_BYPASS, 0)
|
||||
];
|
||||
|
||||
self.get_configurations(&mut configuration_queries)?;
|
||||
if configuration_queries[0].1 == 1 {
|
||||
// Recalculate sys_clk
|
||||
let divider :f64 = configuration_queries[1].1.into();
|
||||
Ok(self.f_ref_clk * divider)
|
||||
}
|
||||
else if configuration_queries[2].1 == 0 {
|
||||
Ok(self.f_ref_clk / 2.0)
|
||||
}
|
||||
else {
|
||||
Ok(self.f_ref_clk)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Strong check for bytes passed to a register
|
||||
|
@ -30,6 +30,16 @@ pub enum Error<E> {
|
||||
MqttCommandError,
|
||||
VectorOutOfSpace,
|
||||
StringOutOfSpace,
|
||||
WaitRetry, // Prompt driver to just wait and retry
|
||||
}
|
||||
|
||||
impl<E> Error<E> {
|
||||
pub fn is_wait_retry(&self) -> bool {
|
||||
match self {
|
||||
Error::WaitRetry => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@ -330,16 +340,39 @@ where
|
||||
}
|
||||
|
||||
pub fn set_channel_sys_clk(&mut self, channel: u8, f_sys_clk: f64) -> Result<(), Error<E>> {
|
||||
self.dds[usize::from(channel)].set_sys_clk_frequency(f_sys_clk).map(|_| ())
|
||||
loop {
|
||||
if let Err(e) = self.dds[usize::from(channel)].set_sys_clk_frequency(f_sys_clk).map(|_| ()) {
|
||||
if e.is_wait_retry() {
|
||||
cortex_m::asm::delay(400_000);
|
||||
} else {
|
||||
return Err(e);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_channel_sys_clk(&mut self, channel: u8) -> Result<f64, Error<E>> {
|
||||
Ok(self.dds[usize::from(channel)].get_f_sys_clk())
|
||||
}
|
||||
|
||||
pub fn get_channel_calculated_sys_clk(&mut self, channel: u8) -> Result<f64, Error<E>> {
|
||||
self.dds[usize::from(channel)].get_sys_clk_frequency()
|
||||
}
|
||||
|
||||
pub fn borrow_dds(&mut self, channel: u8) -> &mut DDS<SPI> {
|
||||
&mut self.dds[usize::from(channel)]
|
||||
}
|
||||
|
||||
pub fn borrow_config_register(&mut self) -> &mut ConfigRegister<SPI> {
|
||||
&mut self.config_register
|
||||
}
|
||||
|
||||
// Multi-dds channel functions
|
||||
// Do not allow reading of DDS registers
|
||||
// Make sure only 1 SPI transaction is compelted per function call
|
||||
// Make sure only 1 SPI transaction is completed per function call
|
||||
|
||||
// Setup NU_MASK in configuration register
|
||||
// This selects the DDS channels that will be covered by multi_channel DDS (spi3)
|
||||
|
Loading…
Reference in New Issue
Block a user