EIS/Measurement_Core.c

360 lines
12 KiB
C

// File: Measurement_Core.c
#include "App_Common.h"
void AD5941_InitAll(void) {
AD5940_HWReset();
AD5940_MCUResourceInit(0);
AD5940_Initialize();
// CRITICAL: Re-enable Platform Interrupts/GPIOs after HW Reset
AD5940PlatformCfg();
}
void AD5940ImpedanceStructInit(void) {
AppIMPCfg_Type *pImpedanceCfg;
AppIMPGetCfg(&pImpedanceCfg);
pImpedanceCfg->IMPInited = bFALSE;
pImpedanceCfg->SeqStartAddr = 0;
pImpedanceCfg->MaxSeqLen = 512;
pImpedanceCfg->RcalVal = 100.0;
pImpedanceCfg->RtiaVal = CalibratedHstiaVal;
pImpedanceCfg->SinFreq = 1000.0;
pImpedanceCfg->FifoThresh = 6;
pImpedanceCfg->DacVoltPP = 600.0;
pImpedanceCfg->ExcitBufGain = EXCITBUFGAIN_0P25;
pImpedanceCfg->HsDacGain = HSDACGAIN_0P2;
pImpedanceCfg->HsDacUpdateRate = 7;
// --- Switch Matrix Configuration ---
// D-Switch: Connect DAC to CE0 (Force +)
pImpedanceCfg->DswitchSel = SWD_CE0;
// P-Switch: Connect CE0 to P-Bus (Optional, but standard)
pImpedanceCfg->PswitchSel = SWP_CE0;
// N-Switch: Connect SE0 to N-Bus (Force - / Current Input)
// This is the CRITICAL path for HSTIA current measurement.
pImpedanceCfg->NswitchSel = SWN_SE0;
// T-Switch: Only connect the Feedback Resistor (TRTIA).
// DO NOT connect SWT_SE0 (T11), as it may short SE0 to RE0/LPTIA nodes.
pImpedanceCfg->TswitchSel = 0; // Impedance.c adds SWT_TRTIA automatically
pImpedanceCfg->HstiaRtiaSel = GetHSTIARtia(ConfigHstiaVal);
pImpedanceCfg->BiasVolt = 0.0;
pImpedanceCfg->SweepCfg.SweepEn = bFALSE;
pImpedanceCfg->SweepCfg.SweepStart = 100.0f;
pImpedanceCfg->SweepCfg.SweepStop = 100000.0f;
pImpedanceCfg->SweepCfg.SweepPoints = 50;
pImpedanceCfg->SweepCfg.SweepLog = bTRUE;
pImpedanceCfg->PwrMod = AFEPWR_LP;
pImpedanceCfg->ADCSinc3Osr = ADCSINC3OSR_4;
pImpedanceCfg->DftNum = DFTNUM_16384;
pImpedanceCfg->DftSrc = DFTSRC_SINC3;
pImpedanceCfg->ShortRe0Se0 = GlobalShortRe0Se0;
}
void AD5940AMPStructInit(void) {
AppAMPCfg_Type *pAMPCfg;
AppAMPGetCfg(&pAMPCfg);
pAMPCfg->AMPInited = bFALSE;
pAMPCfg->WuptClkFreq = LFOSCFreq;
pAMPCfg->SeqStartAddr = 0;
pAMPCfg->MaxSeqLen = 512;
pAMPCfg->RcalVal = 100.0;
pAMPCfg->NumOfData = -1;
pAMPCfg->AmpODR = 1.0;
pAMPCfg->FifoThresh = 4;
pAMPCfg->SensorBias = 0;
pAMPCfg->LptiaRtiaSel = GetLPTIARtia(ConfigLptiaVal);
pAMPCfg->LpTiaRl = ConfigRLoad;
pAMPCfg->LpTiaRf = CurrentLpTiaRf;
pAMPCfg->Vzero = 1100;
pAMPCfg->ADCRefVolt = 1.82;
pAMPCfg->RtiaCalValue.Magnitude = CalibratedLptiaVal;
pAMPCfg->ShortRe0Se0 = GlobalShortRe0Se0;
}
void AD5940RampStructInit(void) {
AppRAMPCfg_Type *pRampCfg;
AppRAMPGetCfg(&pRampCfg);
pRampCfg->RAMPInited = bFALSE;
pRampCfg->SeqStartAddr = 0;
pRampCfg->MaxSeqLen = 1024;
pRampCfg->RcalVal = 100.0;
pRampCfg->ADCRefVolt = 1820.0f;
pRampCfg->FifoThresh = 4;
pRampCfg->SysClkFreq = 16000000.0f;
pRampCfg->LFOSCClkFreq = LFOSCFreq;
pRampCfg->RampStartVolt = -500.0f;
pRampCfg->RampPeakVolt = +500.0f;
pRampCfg->VzeroStart = 1100.0f;
pRampCfg->VzeroPeak = 1100.0f;
pRampCfg->StepNumber = 100;
pRampCfg->RampDuration = 10000;
pRampCfg->SampleDelay = 1.0f;
pRampCfg->LPTIARtiaSel = GetLPTIARtia(ConfigLptiaVal);
pRampCfg->LPTIARloadSel = ConfigRLoad;
pRampCfg->LpTiaRf = CurrentLpTiaRf;
pRampCfg->AdcPgaGain = ADCPGA_1P5;
pRampCfg->RtiaValue.Magnitude = CalibratedLptiaVal;
pRampCfg->ShortRe0Se0 = GlobalShortRe0Se0;
}
void Config_LPLOOP(float bias_mv) {
uint32_t vzero_code = 32;
float vzero_volts = vzero_code * (2200.0f / 64.0f);
float vbias_volts = vzero_volts + bias_mv;
uint32_t vbias_code = (uint32_t)(vbias_volts / (2200.0f / 4095.0f));
if(vbias_code > 4095) vbias_code = 4095;
LPDACCfg_Type lpdac_cfg;
lpdac_cfg.LpdacSel = LPDAC0;
lpdac_cfg.LpDacVbiasMux = LPDACVBIAS_12BIT;
lpdac_cfg.LpDacVzeroMux = LPDACVZERO_6BIT;
lpdac_cfg.DacData6Bit = vzero_code;
lpdac_cfg.DacData12Bit = vbias_code;
lpdac_cfg.DataRst = bFALSE;
lpdac_cfg.LpDacSW = LPDACSW_VBIAS2LPPA | LPDACSW_VBIAS2PIN | LPDACSW_VZERO2LPTIA | LPDACSW_VZERO2PIN;
lpdac_cfg.LpDacRef = LPDACREF_2P5;
lpdac_cfg.LpDacSrc = LPDACSRC_MMR;
lpdac_cfg.PowerEn = bTRUE;
AD5940_LPDACCfgS(&lpdac_cfg);
LPLoopCfg_Type lp_loop;
lp_loop.LpAmpCfg.LpAmpSel = LPAMP0;
lp_loop.LpAmpCfg.LpAmpPwrMod = LPAMPPWR_NORM;
lp_loop.LpAmpCfg.LpPaPwrEn = bTRUE;
lp_loop.LpAmpCfg.LpTiaPwrEn = bTRUE;
lp_loop.LpAmpCfg.LpTiaRf = CurrentLpTiaRf;
lp_loop.LpAmpCfg.LpTiaRload = ConfigRLoad;
lp_loop.LpAmpCfg.LpTiaRtia = GetLPTIARtia(ConfigLptiaVal);
// Base Switches
lp_loop.LpAmpCfg.LpTiaSW = LPTIASW(5)|LPTIASW(2)|LPTIASW(4)|LPTIASW(12)|LPTIASW(13);
// Apply Short Option
if(GlobalShortRe0Se0) {
lp_loop.LpAmpCfg.LpTiaSW |= LPTIASW(11);
}
AD5940_LPLoopCfgS(&lp_loop);
}
void Calibrate_HSDAC(float freq) {
HSDACCal_Type hsdac_cal;
ADCPGACal_Type adcpga_cal;
CLKCfg_Type clk_cfg;
// Configure Clock based on frequency (matches Do_WaveGen logic)
clk_cfg.ADCClkDiv = ADCCLKDIV_1;
clk_cfg.ADCCLkSrc = ADCCLKSRC_HFOSC;
clk_cfg.SysClkDiv = SYSCLKDIV_1;
clk_cfg.SysClkSrc = SYSCLKSRC_HFOSC;
clk_cfg.HFXTALEn = bFALSE;
clk_cfg.LFOSCEn = bTRUE;
if(freq > 80000) {
clk_cfg.HfOSC32MHzMode = bTRUE;
clk_cfg.HFOSCEn = bTRUE;
AD5940_CLKCfg(&clk_cfg);
AD5940_HPModeEn(bTRUE);
} else {
clk_cfg.HfOSC32MHzMode = bFALSE;
clk_cfg.HFOSCEn = bTRUE;
AD5940_CLKCfg(&clk_cfg);
AD5940_HPModeEn(bFALSE);
}
AD5940_AFEPwrBW(AFEPWR_LP, AFEBW_250KHZ);
adcpga_cal.AdcClkFreq = 16000000;
adcpga_cal.ADCPga = ADCPGA_1P5;
adcpga_cal.ADCSinc2Osr = ADCSINC2OSR_1333;
adcpga_cal.ADCSinc3Osr = ADCSINC3OSR_4;
adcpga_cal.PGACalType = PGACALTYPE_OFFSET;
adcpga_cal.TimeOut10us = 1000;
adcpga_cal.VRef1p11 = 1.11;
adcpga_cal.VRef1p82 = 1.82;
AD5940_ADCPGACal(&adcpga_cal);
hsdac_cal.ExcitBufGain = EXCITBUFGAIN_2;
hsdac_cal.HsDacGain = HSDACGAIN_1;
hsdac_cal.AfePwrMode = AFEPWR_LP;
hsdac_cal.ADCSinc2Osr = ADCSINC2OSR_1333;
hsdac_cal.ADCSinc3Osr = ADCSINC3OSR_4;
AD5940_HSDACCal(&hsdac_cal);
hsdac_cal.ExcitBufGain = EXCITBUFGAIN_2;
hsdac_cal.HsDacGain = HSDACGAIN_0P2;
AD5940_HSDACCal(&hsdac_cal);
hsdac_cal.ExcitBufGain = EXCITBUFGAIN_0P25;
hsdac_cal.HsDacGain = HSDACGAIN_1;
AD5940_HSDACCal(&hsdac_cal);
hsdac_cal.ExcitBufGain = EXCITBUFGAIN_0P25;
hsdac_cal.HsDacGain = HSDACGAIN_0P2;
AD5940_HSDACCal(&hsdac_cal);
}
void Configure_Filters(float freq) {
ADCFilterCfg_Type adc_filter;
DFTCfg_Type dft_cfg;
FIFOCfg_Type fifo_cfg;
fifo_cfg.FIFOEn = bFALSE;
fifo_cfg.FIFOMode = FIFOMODE_FIFO;
fifo_cfg.FIFOSize = FIFOSIZE_4KB;
fifo_cfg.FIFOSrc = FIFOSRC_DFT;
fifo_cfg.FIFOThresh = 2;
AD5940_FIFOCfg(&fifo_cfg);
fifo_cfg.FIFOEn = bTRUE;
AD5940_FIFOCfg(&fifo_cfg);
AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N);
AD5940_StructInit(&adc_filter, sizeof(adc_filter));
AD5940_StructInit(&dft_cfg, sizeof(dft_cfg));
if (freq < 0.51f) {
adc_filter.ADCAvgNum = ADCAVGNUM_16;
adc_filter.ADCSinc2Osr = ADCSINC2OSR_267;
adc_filter.ADCSinc3Osr = ADCSINC3OSR_5;
adc_filter.BpNotch = bTRUE;
adc_filter.BpSinc3 = bFALSE;
adc_filter.Sinc2NotchEnable = bTRUE;
adc_filter.ADCRate = ADCRATE_800KHZ;
dft_cfg.DftNum = DFTNUM_8192;
dft_cfg.DftSrc = DFTSRC_SINC2NOTCH;
} else if(freq < 5.0f) {
adc_filter.ADCAvgNum = ADCAVGNUM_16;
adc_filter.ADCSinc2Osr = ADCSINC2OSR_178;
adc_filter.ADCSinc3Osr = ADCSINC3OSR_4;
adc_filter.BpNotch = bTRUE;
adc_filter.BpSinc3 = bFALSE;
adc_filter.Sinc2NotchEnable = bTRUE;
adc_filter.ADCRate = ADCRATE_800KHZ;
dft_cfg.DftNum = DFTNUM_8192;
dft_cfg.DftSrc = DFTSRC_SINC2NOTCH;
} else if(freq < 450.0f) {
adc_filter.ADCAvgNum = ADCAVGNUM_16;
adc_filter.ADCSinc2Osr = ADCSINC2OSR_44;
adc_filter.ADCSinc3Osr = ADCSINC3OSR_4;
adc_filter.BpNotch = bTRUE;
adc_filter.BpSinc3 = bFALSE;
adc_filter.Sinc2NotchEnable = bTRUE;
adc_filter.ADCRate = ADCRATE_800KHZ;
dft_cfg.DftNum = DFTNUM_4096;
dft_cfg.DftSrc = DFTSRC_SINC2NOTCH;
} else if(freq < 80000.0f) {
adc_filter.ADCAvgNum = ADCAVGNUM_16;
adc_filter.ADCSinc2Osr = ADCSINC2OSR_178;
adc_filter.ADCSinc3Osr = ADCSINC3OSR_4;
adc_filter.BpNotch = bTRUE;
adc_filter.BpSinc3 = bFALSE;
adc_filter.Sinc2NotchEnable = bFALSE;
adc_filter.ADCRate = ADCRATE_800KHZ;
dft_cfg.DftNum = DFTNUM_16384;
dft_cfg.DftSrc = DFTSRC_SINC3;
} else {
adc_filter.ADCAvgNum = ADCAVGNUM_16;
adc_filter.ADCSinc2Osr = ADCSINC2OSR_178;
adc_filter.ADCSinc3Osr = ADCSINC3OSR_2;
adc_filter.BpNotch = bTRUE;
adc_filter.BpSinc3 = bFALSE;
adc_filter.Sinc2NotchEnable = bFALSE;
adc_filter.ADCRate = ADCRATE_1P6MHZ;
dft_cfg.DftNum = DFTNUM_16384;
dft_cfg.DftSrc = DFTSRC_SINC3;
}
dft_cfg.HanWinEn = bTRUE;
AD5940_ADCFilterCfgS(&adc_filter);
AD5940_DFTCfgS(&dft_cfg);
}
void Do_WaveGen(float freq) {
CLKCfg_Type clk_cfg;
AFERefCfg_Type aferef_cfg;
HSLoopCfg_Type HpLoopCfg;
ADCBaseCfg_Type adc_base;
clk_cfg.ADCClkDiv = ADCCLKDIV_1;
clk_cfg.ADCCLkSrc = ADCCLKSRC_HFOSC;
clk_cfg.SysClkDiv = SYSCLKDIV_1;
clk_cfg.SysClkSrc = SYSCLKSRC_HFOSC;
clk_cfg.HFXTALEn = bFALSE;
clk_cfg.LFOSCEn = bTRUE;
if(freq > 80000) {
clk_cfg.HfOSC32MHzMode = bTRUE;
clk_cfg.HFOSCEn = bTRUE;
AD5940_CLKCfg(&clk_cfg);
AD5940_HPModeEn(bTRUE);
} else {
clk_cfg.HfOSC32MHzMode = bFALSE;
clk_cfg.HFOSCEn = bTRUE;
AD5940_CLKCfg(&clk_cfg);
AD5940_HPModeEn(bFALSE);
}
aferef_cfg.HpBandgapEn = bTRUE;
aferef_cfg.Hp1V1BuffEn = bTRUE;
aferef_cfg.Hp1V8BuffEn = bTRUE;
aferef_cfg.Disc1V1Cap = bFALSE;
aferef_cfg.Disc1V8Cap = bFALSE;
aferef_cfg.Hp1V8ThemBuff = bFALSE;
aferef_cfg.Hp1V8Ilimit = bFALSE;
aferef_cfg.Lp1V1BuffEn = bFALSE;
aferef_cfg.Lp1V8BuffEn = bFALSE;
aferef_cfg.LpBandgapEn = bTRUE;
aferef_cfg.LpRefBufEn = bTRUE;
aferef_cfg.LpRefBoostEn = bFALSE;
AD5940_REFCfgS(&aferef_cfg);
HpLoopCfg.HsDacCfg.ExcitBufGain = EXCITBUFGAIN_2;
HpLoopCfg.HsDacCfg.HsDacGain = HSDACGAIN_1;
HpLoopCfg.HsDacCfg.HsDacUpdateRate = (freq > 80000) ? 0x07 : 0x1B;
HpLoopCfg.HsTiaCfg.DiodeClose = bFALSE;
HpLoopCfg.HsTiaCfg.HstiaBias = HSTIABIAS_1P1;
HpLoopCfg.HsTiaCfg.HstiaCtia = 16;
HpLoopCfg.HsTiaCfg.HstiaDeRload = HSTIADERLOAD_OPEN;
HpLoopCfg.HsTiaCfg.HstiaDeRtia = HSTIADERTIA_TODE;
HpLoopCfg.HsTiaCfg.HstiaRtiaSel = GetHSTIARtia(ConfigHstiaVal);
adc_base.ADCPga = ADCPGA_1P5;
AD5940_ADCBaseCfgS(&adc_base);
// --- Switch Matrix Configuration (Manual Sweep) ---
HpLoopCfg.SWMatCfg.Dswitch = SWD_CE0;
HpLoopCfg.SWMatCfg.Pswitch = SWP_CE0;
HpLoopCfg.SWMatCfg.Nswitch = SWN_SE0;
// FIX: Only use TRTIA (Feedback). Do NOT use SWT_SE0.
HpLoopCfg.SWMatCfg.Tswitch = SWT_TRTIA;
AD5940_AFECtrlS(AFECTRL_WG, bFALSE);
HpLoopCfg.WgCfg.WgType = WGTYPE_SIN;
HpLoopCfg.WgCfg.GainCalEn = bFALSE;
HpLoopCfg.WgCfg.OffsetCalEn = bFALSE;
HpLoopCfg.WgCfg.SinCfg.SinFreqWord = AD5940_WGFreqWordCal(freq, (freq > 80000) ? 32000000.0 : 16000000.0);
// Reduced Amplitude: 50mV peak (100mV pp) to prevent saturation
// Range is +/- 607mV with Gain 2/1.
// 50 / 607 * 2047 = ~168
HpLoopCfg.WgCfg.SinCfg.SinAmplitudeWord = (uint32_t)(50.0f/607.0f*2047 + 0.5f);
HpLoopCfg.WgCfg.SinCfg.SinOffsetWord = 0;
HpLoopCfg.WgCfg.SinCfg.SinPhaseWord = 0;
AD5940_HSLoopCfgS(&HpLoopCfg);
AD5940_AFECtrlS(AFECTRL_DACREFPWR, bTRUE);
AD5940_AFECtrlS(AFECTRL_EXTBUFPWR | AFECTRL_INAMPPWR | AFECTRL_HSTIAPWR | AFECTRL_HSDACPWR, bTRUE);
AD5940_AFECtrlS(AFECTRL_WG, bTRUE);
AD5940_AFECtrlS(AFECTRL_DCBUFPWR, bTRUE);
AD5940_AFEPwrBW(AFEPWR_LP, AFEBW_250KHZ);
}