mirror of
https://github.com/hubaldv/bioz-firmware-rs.git
synced 2026-03-10 02:50:30 +00:00
Started writing nice library.
This commit is contained in:
346
src/ad5940.rs
346
src/ad5940.rs
@@ -7,6 +7,134 @@ use heapless::LinearMap;
|
||||
|
||||
use crate::ad5940_registers::*;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default)]
|
||||
pub struct SwitchConfig {
|
||||
t9con: Option<T9CON>,
|
||||
tmuxcon: Option<TMUXCON>,
|
||||
nmuxcon: Option<NMUXCON>,
|
||||
pmuxcon: Option<PMUXCON>,
|
||||
dmuxcon: Option<DMUXCON>,
|
||||
}
|
||||
|
||||
impl SwitchConfig {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn t9con(mut self, t9con: T9CON) -> Self {
|
||||
self.t9con = Some(t9con);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn tmuxcon(mut self, tmuxcon: TMUXCON) -> Self {
|
||||
self.tmuxcon = Some(tmuxcon);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn nmuxcon(mut self, nmuxcon: NMUXCON) -> Self {
|
||||
self.nmuxcon = Some(nmuxcon);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn pmuxcon(mut self, pmuxcon: PMUXCON) -> Self {
|
||||
self.pmuxcon = Some(pmuxcon);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn dmuxcon(mut self, dmuxcon: DMUXCON) -> Self {
|
||||
self.dmuxcon = Some(dmuxcon);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default)]
|
||||
pub struct DspConfig {
|
||||
muxseln: Option<MUXSELN>,
|
||||
muxselp: Option<MUXSELP>,
|
||||
ctiacon: Option<CTIACON>,
|
||||
rtiacon: Option<RTIACON>,
|
||||
sinc3osr: Option<SINC3OSR>,
|
||||
sinc2osr: Option<SINC2OSR>,
|
||||
adcsamplerate: Option<ADCSAMPLERATE>,
|
||||
dftin: Option<DFTINSEL>,
|
||||
dftnum: Option<DFTNUM>,
|
||||
hanning: Option<bool>,
|
||||
}
|
||||
|
||||
impl DspConfig {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn adc_mux_n(mut self, muxseln: MUXSELN) -> Self {
|
||||
self.muxseln = Some(muxseln);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn adc_mux_p(mut self, muxselp: MUXSELP) -> Self {
|
||||
self.muxselp = Some(muxselp);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn ctiacon(mut self, ctiacon: CTIACON) -> Self {
|
||||
self.ctiacon = Some(ctiacon);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn rtiacon(mut self, rtiacon: RTIACON) -> Self {
|
||||
self.rtiacon = Some(rtiacon);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn sinc3osr(mut self, sinc3osr: SINC3OSR) -> Self {
|
||||
self.sinc3osr = Some(sinc3osr);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn sinc2osr(mut self, sinc2osr: SINC2OSR) -> Self {
|
||||
self.sinc2osr = Some(sinc2osr);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn adcsamplerate(mut self, adcsamplerate: ADCSAMPLERATE) -> Self {
|
||||
self.adcsamplerate = Some(adcsamplerate);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn dftin_sel(mut self, dftin: DFTINSEL) -> Self {
|
||||
self.dftin = Some(dftin);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn dftnum(mut self, dftnum: DFTNUM) -> Self {
|
||||
self.dftnum = Some(dftnum);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn hanning(mut self, hanning: bool) -> Self {
|
||||
self.hanning = Some(hanning);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Sequencer {
|
||||
|
||||
}
|
||||
|
||||
impl Sequencer {
|
||||
pub fn new() -> Self {
|
||||
Sequencer {}
|
||||
}
|
||||
|
||||
pub async fn configure(&mut self, ad5940: &mut AD5940) -> Result<(), Error> {
|
||||
// Configure the sequencer here if needed
|
||||
// This is a placeholder for future sequencer configuration logic
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AD5940 {
|
||||
spi: Spi<'static, Blocking>,
|
||||
cs: Output<'static>,
|
||||
@@ -231,14 +359,110 @@ impl AD5940 {
|
||||
error!("Sequencers from 0 till 3 are allows, now: seq={}", seq);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// for _ in 0..100 {
|
||||
// let test = self.read_reg_raw(0x206C).await.unwrap();
|
||||
// info!("DATAFIFORD: 0x{:08X}", test);
|
||||
// }
|
||||
|
||||
// let test = self.read_reg_raw(0x2200).await.unwrap();
|
||||
// info!("FIFOCNTSTA: {}", (test>>16) & 0b111_1111_1111);
|
||||
pub async fn apply_switch_config(&mut self, config: SwitchConfig) -> Result<(), Error> {
|
||||
// SWCON
|
||||
let mut current = self.read_reg(Register::SWCON).await?;
|
||||
|
||||
if let Some(t9con) = config.t9con {
|
||||
current &= !(0b1 << 17);
|
||||
current |= (t9con as u32) << 17;
|
||||
}
|
||||
|
||||
if let Some(tmuxcon) = config.tmuxcon {
|
||||
current &= !(0b1111 << 12);
|
||||
current |= (tmuxcon as u32) << 12;
|
||||
}
|
||||
|
||||
if let Some(nmuxcon) = config.nmuxcon {
|
||||
current &= !(0b1111 << 8);
|
||||
current |= (nmuxcon as u32) << 8;
|
||||
}
|
||||
|
||||
if let Some(pmuxcon) = config.pmuxcon {
|
||||
current &= !(0b1111 << 4);
|
||||
current |= (pmuxcon as u32) << 4;
|
||||
}
|
||||
|
||||
if let Some(dmuxcon) = config.dmuxcon {
|
||||
current &= !(0b1111);
|
||||
current |= dmuxcon as u32;
|
||||
}
|
||||
|
||||
self.write_reg(Register::SWCON, 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?;
|
||||
|
||||
if let Some(muxseln) = config.muxseln {
|
||||
current &= !(0b11111 << 8);
|
||||
current |= (muxseln as u32) << 8;
|
||||
}
|
||||
if let Some(muxselp) = config.muxselp {
|
||||
current &= !(0b11111);
|
||||
current |= muxselp as u32;
|
||||
}
|
||||
|
||||
self.write_reg(Register::ADCCON, current).await?;
|
||||
|
||||
// HSRTIACON
|
||||
let mut current = self.read_reg(Register::HSRTIACON).await?;
|
||||
|
||||
if let Some(ctiacon) = config.ctiacon {
|
||||
current &= !(0b1111 << 5);
|
||||
current |= (ctiacon as u32) << 5;
|
||||
}
|
||||
|
||||
if let Some(rtiacon) = config.rtiacon {
|
||||
current &= !(0b1111);
|
||||
current |= rtiacon as u32;
|
||||
}
|
||||
|
||||
self.write_reg(Register::HSRTIACON, current).await?;
|
||||
|
||||
// ADCFILTERCON
|
||||
let mut current = self.read_reg(Register::ADCFILTERCON).await?;
|
||||
|
||||
if let Some(sinc3osr) = config.sinc3osr{
|
||||
current &= !(0b11 << 12);
|
||||
current |= (sinc3osr as u32) << 12;
|
||||
}
|
||||
|
||||
if let Some(sinc2osr) = config.sinc2osr {
|
||||
current &= !(0b1111 << 8);
|
||||
current |= (sinc2osr as u32) << 8;
|
||||
}
|
||||
|
||||
if let Some(adcsamplerate) = config.adcsamplerate {
|
||||
current &= !1;
|
||||
current |= adcsamplerate as u32;
|
||||
}
|
||||
|
||||
self.write_reg(Register::ADCFILTERCON, current).await?;
|
||||
|
||||
// DFTCON
|
||||
let mut current = self.read_reg(Register::DFTCON).await?;
|
||||
|
||||
if let Some(dftin) = config.dftin {
|
||||
current &= !(0b11 << 20);
|
||||
current |= (dftin as u32) << 20;
|
||||
}
|
||||
if let Some(dftnum) = config.dftnum {
|
||||
current &= !(0b1111 << 4);
|
||||
current |= (dftnum as u32) << 4;
|
||||
}
|
||||
if let Some(hanning) = config.hanning {
|
||||
current &= !(0b1 << 0);
|
||||
current |= (hanning as u32) << 0;
|
||||
}
|
||||
self.write_reg(Register::DFTCON, current).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn afecon(&mut self, ctr: AFECON, state: bool) {
|
||||
@@ -275,62 +499,6 @@ impl AD5940 {
|
||||
self.write_reg(Register::AFECON, reg.bits()).await.unwrap();
|
||||
}
|
||||
|
||||
pub async fn swcon(&mut self, ctr: SWCON) {
|
||||
let reg = self.read_reg(Register::SWCON).await.unwrap();
|
||||
let mut reg = SWCON::from_bits_truncate(reg);
|
||||
|
||||
// T9CON
|
||||
if ctr.contains(SWCON::T9CON) {
|
||||
reg |= SWCON::T9CON;
|
||||
} else {
|
||||
reg &= !SWCON::T9CON;
|
||||
}
|
||||
|
||||
// TMUXCON
|
||||
if (ctr & SWCON::TMUXCON_MSK) == SWCON::TMUXCON_T2 {
|
||||
reg &= !SWCON::TMUXCON_MSK;
|
||||
reg |= SWCON::TMUXCON_T2;
|
||||
} else if (ctr & SWCON::TMUXCON_MSK) == SWCON::TMUXCON_TR1 {
|
||||
reg &= !SWCON::TMUXCON_MSK;
|
||||
reg |= SWCON::TMUXCON_TR1;
|
||||
}
|
||||
|
||||
// NMUXCON
|
||||
if (ctr & SWCON::NMUXCON_MSK) == SWCON::NMUXCON_N2 {
|
||||
reg &= !SWCON::NMUXCON_MSK;
|
||||
reg |= SWCON::NMUXCON_N2;
|
||||
} else if (ctr & SWCON::NMUXCON_MSK) == SWCON::NMUXCON_N5 {
|
||||
reg &= !SWCON::NMUXCON_MSK;
|
||||
reg |= SWCON::NMUXCON_N5;
|
||||
} else if (ctr & SWCON::NMUXCON_MSK) == SWCON::NMUXCON_NR1 {
|
||||
reg &= !SWCON::NMUXCON_MSK;
|
||||
reg |= SWCON::NMUXCON_NR1;
|
||||
}
|
||||
|
||||
// PMUXCON
|
||||
if (ctr & SWCON::PMUXCON_MSK) == SWCON::PMUXCON_P2 {
|
||||
reg &= !SWCON::PMUXCON_MSK;
|
||||
reg |= SWCON::PMUXCON_P2;
|
||||
} else if (ctr & SWCON::PMUXCON_MSK) == SWCON::PMUXCON_P11 {
|
||||
reg &= !SWCON::PMUXCON_MSK;
|
||||
reg |= SWCON::PMUXCON_P11;
|
||||
} else if (ctr & SWCON::PMUXCON_MSK) == SWCON::PMUXCON_PR0 {
|
||||
reg &= !SWCON::PMUXCON_MSK;
|
||||
reg |= SWCON::PMUXCON_PR0;
|
||||
}
|
||||
|
||||
// DMUXCON
|
||||
if (ctr & SWCON::DMUXCON_MSK) == SWCON::DMUXCON_D5 {
|
||||
reg &= !SWCON::DMUXCON_MSK;
|
||||
reg |= SWCON::DMUXCON_D5;
|
||||
} else if { ctr & SWCON::DMUXCON_MSK } == SWCON::DMUXCON_DR0 {
|
||||
reg &= !SWCON::DMUXCON_MSK;
|
||||
reg |= SWCON::DMUXCON_DR0;
|
||||
}
|
||||
|
||||
self.write_reg(Register::SWCON, reg.bits()).await.unwrap();
|
||||
}
|
||||
|
||||
pub async fn wgfcw(&mut self, frequency: u32) {
|
||||
let sinefcw = (frequency as f64) * (1_073_741_824.0 / 16_000_000.0);
|
||||
let sinefcw = 0x00FFFFFF & sinefcw as u32;
|
||||
@@ -415,12 +583,13 @@ impl AD5940 {
|
||||
let config_wgcon = WGCON::TYPESEL_SIN.bits();
|
||||
self.write_reg(Register::WGCON, config_wgcon).await?;
|
||||
|
||||
// SWCON - set up switch matrix
|
||||
self.swcon(
|
||||
SWCON::NMUXCON_N2
|
||||
| SWCON::PMUXCON_P11
|
||||
| SWCON::DMUXCON_D5).await;
|
||||
|
||||
// SWCON - set up switch matri
|
||||
let switch_config = SwitchConfig::new()
|
||||
.nmuxcon(NMUXCON::N2Closed)
|
||||
.pmuxcon(PMUXCON::P11Closed)
|
||||
.dmuxcon(DMUXCON::D5Closed);
|
||||
self.apply_switch_config(switch_config).await?;
|
||||
|
||||
// AFECON:
|
||||
self.afecon(
|
||||
AFECON::DACREFEN
|
||||
@@ -441,42 +610,33 @@ impl AD5940 {
|
||||
AFECON::DACBUFEN
|
||||
| AFECON::DACREFEN
|
||||
| AFECON::SINC2EN
|
||||
// | AFECON::DFTEN
|
||||
// | AFECON::WAVEGENEN
|
||||
| AFECON::TIAEN
|
||||
| AFECON::INAMPEN
|
||||
| AFECON::EXBUFEN
|
||||
// | AFECON::ADCCONVEN
|
||||
// | AFECON::ADCEN
|
||||
| AFECON::DACEN,
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
|
||||
// SWCON - set up switch matrix for impedance measurement
|
||||
// self.swcon(
|
||||
// SWCON::NMUXCON_N2
|
||||
// | SWCON::PMUXCON_P11
|
||||
// | SWCON::DMUXCON_D5).await;
|
||||
// Set DSP configuration
|
||||
let dsp_config = DspConfig::default()
|
||||
.adc_mux_n(MUXSELN::HsTiaNeg)
|
||||
.adc_mux_p(MUXSELP::HsTiaPos)
|
||||
.ctiacon(CTIACON::C32)
|
||||
.rtiacon(RTIACON::R5k)
|
||||
.sinc3osr(SINC3OSR::R5)
|
||||
.sinc2osr(SINC2OSR::R178)
|
||||
.adcsamplerate(ADCSAMPLERATE::R800Hz)
|
||||
.dftin_sel(DFTINSEL::GainOffset)
|
||||
.dftnum(DFTNUM::Num16384)
|
||||
.hanning(true);
|
||||
|
||||
self.apply_dsp_config(dsp_config).await.unwrap();
|
||||
|
||||
// WGCON: set sinus output
|
||||
let config_wgcon = WGCON::TYPESEL_SIN.bits();
|
||||
self.write_reg(Register::WGCON, config_wgcon).await.unwrap();
|
||||
|
||||
// BUFSENCON
|
||||
self.write_reg(Register::BUFSENCON, 0b1).await.unwrap();
|
||||
|
||||
// DFTCON
|
||||
self.write_reg(Register::DFTCON, 0b0111 << 4 | 0b1).await.unwrap(); // 1024 OSR
|
||||
// SINC3 = 5 --> 160000 Hz
|
||||
// SINC2 = 178 --> 898,8764044944Hz
|
||||
// ... (DFTNUM = 2048)
|
||||
|
||||
// ADCCON
|
||||
self.write_reg(Register::ADCCON, ADCCON::MUXSELN_TIAN.bits() | ADCCON::MUXSELP_TIAP.bits()).await?;
|
||||
|
||||
// HSRTIACON: RTIACON 32pF & 5k
|
||||
self.write_reg(Register::HSRTIACON, 0b10000 << 5 | 0b0010).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user