Added clk config part, increased ADC clk to 32MHz.

This commit is contained in:
2025-09-09 13:04:15 +02:00
parent 83731f77e0
commit b53e58ec31
3 changed files with 216 additions and 12 deletions

View File

@@ -7,6 +7,30 @@ use heapless::LinearMap;
use crate::ad5940_registers::*;
#[allow(dead_code)]
#[derive(Default)]
pub struct ClkConfig {
adcclkdiv: Option<ADCCLKDIV>,
sysclkdiv: Option<SYSCLKDIV>,
clk32mhzen: Option<CLK32MHZEN>,
}
impl ClkConfig {
pub fn adcclkdiv(mut self, adcclkdiv: ADCCLKDIV) -> Self {
self.adcclkdiv = Some(adcclkdiv);
self
}
pub fn sysclkdiv(mut self, sysclkdiv: SYSCLKDIV) -> Self {
self.sysclkdiv = Some(sysclkdiv);
self
}
pub fn clk32mhzen(mut self, clk32mhzen: CLK32MHZEN) -> Self {
self.clk32mhzen = Some(clk32mhzen);
self
}
}
#[allow(dead_code)]
#[derive(Default)]
pub struct SwitchConfig {
@@ -57,6 +81,9 @@ pub struct DspConfig {
dftin: Option<DFTINSEL>,
dftnum: Option<DFTNUM>,
hanning: Option<bool>,
pub fsys: Option<u32>,
pub fadc: Option<u32>,
ratio_sys2adc_clk: Option<f32>,
}
impl DspConfig {
@@ -109,6 +136,13 @@ impl DspConfig {
self.hanning = Some(hanning);
self
}
pub fn set_clks(mut self, fsys: u32, fadc: u32) -> Self {
self.fsys = Some(fsys);
self.fadc = Some(fadc);
self.ratio_sys2adc_clk = Some(fsys as f32 / fadc as f32);
self
}
}
#[allow(dead_code)]
@@ -482,9 +516,17 @@ impl AD5940 {
// When ACLK = 16MHz, ADC samplerate is 800kHz
// When ACLK = 32MHz, ADC samplerate is 1.6MHz
// --> Always per ADC sample 20 cycles
// If ACLK == SYSCLK --> Always per ADC sample 20 cycles
// If ACLK != SYSCLK --> Always per ADC sample 20*(SYSCLK/ACLK) cycles
// When SYSCLK is lower, the wait cycles to wait are less becasuse the ADC samples at higher rate
wait_time *= 20;
if let Some(ratio) = config.ratio_sys2adc_clk {
wait_time = (wait_time as f32 * ratio) as u32;
} else {
return None; // Ratio must be set
}
Some(wait_time)
}
@@ -517,6 +559,35 @@ impl AD5940 {
Ok(())
}
pub async fn apply_clk_config(&mut self, config: &ClkConfig) -> Result<(), Error> {
// PMBW
let mut current = self.read_reg(Register::PMBW).await?;
current |= 0b1;
self.write_reg(Register::PMBW, current).await?;
// CLKCON0
let mut current = self.read_reg(Register::CLKCON0).await?;
if let Some(adcclkdiv) = config.adcclkdiv {
current = ADCCLKDIV::apply(current, adcclkdiv as u32);
}
if let Some(sysclkdiv) = config.sysclkdiv {
current = SYSCLKDIV::apply(current, sysclkdiv as u32);
}
self.write_reg(Register::CLKCON0, current).await?;
// HSOSCCON
let mut current = self.read_reg(Register::HSOSCCON).await?;
if let Some(clk32mhzen) = config.clk32mhzen {
current = CLK32MHZEN::apply(current, clk32mhzen as u32);
}
self.write_reg(Register::HSOSCCON, current).await?;
Ok(())
}
pub async fn apply_dsp_config(&mut self, config: &DspConfig) -> Result<(), Error> {
// ADCCON
let mut current = self.read_reg(Register::ADCCON).await?;
@@ -782,5 +853,7 @@ pub enum Register {
HSRTIACON = 0x0000_20F0, // High Speed RTIA Configuration Register
BUFSENCON = 0x0000_2180, // HIGH POWER AND LOW POWER BUFFER CONTROL REGISTER
FIFOCNTSTA = 0x0000_2200, // Command and data FIFO internal data count register
ADCFILTERCON = 0x0000_2044 // ADC Output Filters Configuration Register
ADCFILTERCON = 0x0000_2044, // ADC Output Filters Configuration Register
CLKCON0 = 0x0000_0408, // Clock Divider Configuration Register
HSOSCCON = 0x0000_20BC, // High Power Oscillator Configuration Register
}