mirror of
https://github.com/hubaldv/bioz-firmware-rs.git
synced 2025-12-06 05:01:18 +00:00
Implemented LP DAC for enabling common-mode during 4-lead measurement.
This commit is contained in:
107
src/ad5940.rs
107
src/ad5940.rs
@@ -68,6 +68,55 @@ impl SwitchConfig {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default)]
|
||||
pub struct LpConfig {
|
||||
data_reset: Option<bool>,
|
||||
power_enable: Option<bool>,
|
||||
data_6bit: Option<u8>,
|
||||
common_mode_switch: Option<bool>,
|
||||
tia_switches_enabled: Option<u16>,
|
||||
tia_enable: Option<bool>,
|
||||
filter_resistor: Option<TIARF>,
|
||||
}
|
||||
|
||||
impl LpConfig {
|
||||
pub fn data_reset(&mut self, rsten: bool) -> &mut Self {
|
||||
self.data_reset = Some(rsten);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn power_enable(&mut self, pwden: bool) -> &mut Self {
|
||||
self.power_enable = Some(pwden);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn data_6bit(&mut self, data: u8) -> &mut Self {
|
||||
self.data_6bit = Some(data & 0x3F);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn common_mode_enable(&mut self, enable: bool) -> &mut Self {
|
||||
self.common_mode_switch = Some(enable);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn tia_switches_enabled(&mut self, enable: u16) -> &mut Self {
|
||||
self.tia_switches_enabled = Some(enable);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn tia_enable(&mut self, enable: bool) -> &mut Self {
|
||||
self.tia_enable = Some(enable);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn filter_resistor(&mut self, tiarf: TIARF) -> &mut Self {
|
||||
self.filter_resistor = Some(tiarf);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default)]
|
||||
pub struct DspConfig {
|
||||
@@ -594,6 +643,59 @@ impl AD5940 {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn apply_lp_config(&mut self, config: &LpConfig) -> Result<(), Error> {
|
||||
// LPDACCON0
|
||||
let mut current = self.read_reg(Register::LPDACCON0).await?;
|
||||
|
||||
if let Some(data_reset) = config.data_reset {
|
||||
current = RSTEN::apply(current, data_reset as u32);
|
||||
}
|
||||
|
||||
if let Some(power_enable) = config.power_enable {
|
||||
current = PWDEN::apply(current, !power_enable as u32);
|
||||
}
|
||||
|
||||
self.write_reg(Register::LPDACCON0, current).await?;
|
||||
|
||||
// LPDACDAT0
|
||||
let mut current = self.read_reg(Register::LPDACDAT0).await?;
|
||||
|
||||
if let Some(data) = config.data_6bit {
|
||||
current = DACIN6::apply(current, data as u32);
|
||||
}
|
||||
|
||||
self.write_reg(Register::LPDACDAT0, current).await?;
|
||||
|
||||
// SWMUX
|
||||
let mut current = self.read_reg(Register::SWMUX).await?;
|
||||
|
||||
if let Some(common_mode_switch) = config.common_mode_switch {
|
||||
current = SWMUX::apply(current, common_mode_switch as u32);
|
||||
}
|
||||
|
||||
self.write_reg(Register::SWMUX, current).await?;
|
||||
|
||||
// LPTIASW0
|
||||
if let Some(tia_switches_enabled) = config.tia_switches_enabled {
|
||||
self.write_reg(Register::LPTIASW0, tia_switches_enabled as u32).await?;
|
||||
}
|
||||
|
||||
// LPTIACON0
|
||||
let mut current = self.read_reg(Register::LPTIACON0).await?;
|
||||
|
||||
if let Some(tia_enable) = config.tia_enable {
|
||||
current = TIAPDEN::apply(current, !tia_enable as u32);
|
||||
}
|
||||
|
||||
if let Some(tiarf) = config.filter_resistor {
|
||||
current = TIARF::apply(current, tiarf as u32);
|
||||
}
|
||||
|
||||
self.write_reg(Register::LPTIACON0, 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?;
|
||||
@@ -849,6 +951,10 @@ pub enum Register {
|
||||
CMDFIFOWRITE = 0x0000_2070, // Command FIFO Write Register
|
||||
TEMPSENSDAT = 0x0000_2084, // Temperature Sensor Result Register
|
||||
ADCDAT = 0x0000_2074, // ADC Raw Result Register
|
||||
LPTIASW0 = 0x0000_20E4, // Low power TIA switch configuration
|
||||
LPTIACON0 = 0x0000_20EC, // Low power TIA control bits, Channel 0
|
||||
LPDACDAT0 = 0x0000_2120, // Low power DAC data output Register
|
||||
LPDACCON0 = 0x0000_2128, // Low power DAC configuration register
|
||||
TEMPSENS = 0x0000_2174, // Temperature Sensor Configuration Register
|
||||
ADCCON = 0x0000_21A8, // ADC Configuration Register
|
||||
SEQ0INFO = 0x0000_21CC, // Sequence 0 Information Register
|
||||
@@ -859,6 +965,7 @@ pub enum Register {
|
||||
AFEGENINTSTA = 0x0000_209C, // Analog Generation Interrupt Register
|
||||
CMDFIFOWADDR = 0x0000_21D4, // Command FIFO Write Address Register
|
||||
PMBW = 0x0000_22F0, // Power Mode Configuration Register
|
||||
SWMUX = 0x0000_235C, // Common-mode switch mux select register
|
||||
INTCFLAG0 = 0x0000_3010, // Interrupt Control Flag 0 Register
|
||||
INTCFLAG1 = 0x0000_3014, // Interrupt Control Flag 1 Register
|
||||
OSCCON = 0x0000_0A10, // Oscillator Control Register
|
||||
|
||||
@@ -130,6 +130,107 @@ impl RegisterField for DMUXCON {
|
||||
const MASK: u32 = 0b1111;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum RSTEN {
|
||||
Disabled = 0b0,
|
||||
Enabled = 0b1,
|
||||
}
|
||||
|
||||
impl RegisterField for RSTEN {
|
||||
fn reset() -> Self {
|
||||
RSTEN::Disabled
|
||||
}
|
||||
const BIT_OFFSET: u32 = 0;
|
||||
const MASK: u32 = 0b1;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum PWDEN {
|
||||
DACPoweredOn = 0b0,
|
||||
DACPoweredOff = 0b1,
|
||||
}
|
||||
|
||||
impl RegisterField for PWDEN {
|
||||
fn reset() -> Self {
|
||||
PWDEN::DACPoweredOff
|
||||
}
|
||||
const BIT_OFFSET: u32 = 1;
|
||||
const MASK: u32 = 0b1;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum DACIN6 {
|
||||
Default = 0b0,
|
||||
}
|
||||
|
||||
impl RegisterField for DACIN6 {
|
||||
fn reset() -> Self {
|
||||
DACIN6::Default
|
||||
}
|
||||
const BIT_OFFSET: u32 = 12;
|
||||
const MASK: u32 = 0b11_1111;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum SWMUX {
|
||||
CommonModeOff = 0b0,
|
||||
COmmonModeOn = 0b1,
|
||||
}
|
||||
|
||||
impl RegisterField for SWMUX {
|
||||
fn reset() -> Self {
|
||||
SWMUX::CommonModeOff
|
||||
}
|
||||
const BIT_OFFSET: u32 = 3;
|
||||
const MASK: u32 = 0b1;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum TIAPDEN {
|
||||
PowerUp = 0b0,
|
||||
PowerDown = 0b1,
|
||||
}
|
||||
|
||||
impl RegisterField for TIAPDEN {
|
||||
fn reset() -> Self {
|
||||
TIAPDEN::PowerDown
|
||||
}
|
||||
const BIT_OFFSET: u32 = 0;
|
||||
const MASK: u32 = 0b1;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum TIARF {
|
||||
Disconnected = 0b0,
|
||||
R0 = 0b1,
|
||||
R20k = 0b10,
|
||||
R100k = 0b11,
|
||||
R200k = 0b100,
|
||||
R400k = 0b101,
|
||||
R600k = 0b110,
|
||||
R1M = 0b111,
|
||||
}
|
||||
|
||||
impl RegisterField for TIARF {
|
||||
fn reset() -> Self {
|
||||
TIARF::Disconnected
|
||||
}
|
||||
const BIT_OFFSET: u32 = 13;
|
||||
const MASK: u32 = 0b111;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone)]
|
||||
@@ -158,7 +259,9 @@ pub enum MUXSELN
|
||||
HsTiaNeg = 0b00001,
|
||||
LpTiaNeg = 0b00010,
|
||||
AIN1 = 0b00101,
|
||||
AIN2 = 0b00110,
|
||||
AIN3 = 0b00111,
|
||||
VBIAS_CAP= 0b01000,
|
||||
ExciNNode= 0b10100,
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,9 @@ impl ImpedanceSetup {
|
||||
|
||||
self.ad5940.apply_clk_config(&clk_config).await.unwrap();
|
||||
|
||||
// Configure LP DAC and TIA
|
||||
self.common_mode_output_enable(false).await.unwrap();
|
||||
|
||||
// Set DSP configuration
|
||||
let mut dsp_config = DspConfig::default();
|
||||
dsp_config
|
||||
@@ -253,7 +256,36 @@ impl ImpedanceSetup {
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
pub async fn common_mode_output_enable(&mut self, enable: bool) -> Result<(), Error> {
|
||||
// Configure LP DAC and TIA
|
||||
let mut lp_config = LpConfig::default();
|
||||
|
||||
if enable {
|
||||
lp_config
|
||||
.data_reset(true)
|
||||
.power_enable(true)
|
||||
.data_6bit(31) // Mid-scale for 6-bit DAC
|
||||
.common_mode_enable(true)
|
||||
.tia_switches_enabled(1 << 5 | 1 << 7 | 1 << 9 | 1 << 13)
|
||||
.tia_enable(true)
|
||||
.filter_resistor(TIARF::R20k);
|
||||
|
||||
} else {
|
||||
lp_config
|
||||
.power_enable(false)
|
||||
.common_mode_enable(false)
|
||||
.tia_enable(false);
|
||||
}
|
||||
|
||||
self.ad5940.apply_lp_config(&lp_config).await.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn init_single_frequency_measurement_2_lead(&mut self, frequency: u32, dft_number: IcdDftNum) -> Result<f32, ImpedanceInitError> {
|
||||
// Configure LP DAC and TIA
|
||||
self.common_mode_output_enable(false).await.unwrap();
|
||||
|
||||
// Reset FIFO
|
||||
self.ad5940.clear_and_enable_fifo().await.unwrap();
|
||||
|
||||
@@ -333,6 +365,9 @@ impl ImpedanceSetup {
|
||||
}
|
||||
|
||||
pub async fn init_single_frequency_measurement_4_lead(&mut self, frequency: u32, dft_number: IcdDftNum) -> Result<f32, ImpedanceInitError> {
|
||||
// Configure LP DAC and TIA
|
||||
self.common_mode_output_enable(true).await.unwrap();
|
||||
|
||||
// Reset FIFO
|
||||
self.ad5940.clear_and_enable_fifo().await.unwrap();
|
||||
|
||||
@@ -430,6 +465,9 @@ impl ImpedanceSetup {
|
||||
}
|
||||
|
||||
pub async fn init_multi_frequency_measurement_2_lead<const N: usize>(&mut self, number_of_points: MeasurementPointSet) -> Result<heapless::Vec<f32, N>, ImpedanceInitError> {
|
||||
// Configure LP DAC and TIA
|
||||
self.common_mode_output_enable(false).await.unwrap();
|
||||
|
||||
// Create vector to store the periods per DFT for each frequency
|
||||
let mut periods_per_dft_vec = heapless::Vec::<f32, N>::new();
|
||||
|
||||
@@ -535,6 +573,9 @@ impl ImpedanceSetup {
|
||||
}
|
||||
|
||||
pub async fn init_multi_frequency_measurement_4_lead<const N: usize>(&mut self, number_of_points: MeasurementPointSet) -> Result<heapless::Vec<f32, N>, ImpedanceInitError> {
|
||||
// Configure LP DAC and TIA
|
||||
self.common_mode_output_enable(true).await.unwrap();
|
||||
|
||||
// Create vector to store the periods per DFT for each frequency
|
||||
let mut periods_per_dft_vec = heapless::Vec::<f32, N>::new();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user