I decided to include this because it has has bug fixes that aren't in the official driver. also the bug hadn't been fully squashed; i stomped on it.

This commit is contained in:
pszsh 2026-01-27 21:53:25 -08:00
parent 52c6bef53b
commit 42871ed837
5 changed files with 4492 additions and 41 deletions

2
.gitignore vendored
View File

@ -6,7 +6,7 @@ build
*.swp *.swp
*.cmake *.cmake
requirements.txt requirements.txt
ad5940.* ad5940
pico_sdk_import.cmake pico_sdk_import.cmake
build* build*
*.png *.png

View File

@ -5,7 +5,7 @@
#include "math.h" #include "math.h"
#include "Impedance.h" #include "Impedance.h"
/* Default LPDAC resolution(2.5V internal reference). */ /* Default LPDAC resolution (2.5V internal reference) */
#define DAC12BITVOLT_1LSB (2200.0f/4095) // mV #define DAC12BITVOLT_1LSB (2200.0f/4095) // mV
#define DAC6BITVOLT_1LSB (DAC12BITVOLT_1LSB*64) // mV #define DAC6BITVOLT_1LSB (DAC12BITVOLT_1LSB*64) // mV
@ -18,14 +18,14 @@ AppIMPCfg_Type AppIMPCfg =
.SeqStartAddrCal = 0, .SeqStartAddrCal = 0,
.MaxSeqLenCal = 0, .MaxSeqLenCal = 0,
.ImpODR = 20.0, /* 20.0 Hz = 50ms period */ .ImpODR = 20.0, /* Output Data Rate: 20.0 Hz */
.NumOfData = -1, .NumOfData = -1, /* -1 for infinite/continuous measurement */
.RealDataCount = -1, /* Default to no filtering */ .RealDataCount = -1,
.SysClkFreq = 16000000.0, .SysClkFreq = 16000000.0,
.WuptClkFreq = 32000.0, .WuptClkFreq = 32000.0, /* Low Frequency Oscillator (LFO) typically 32kHz */
.AdcClkFreq = 16000000.0, .AdcClkFreq = 16000000.0,
.RcalVal = 10000.0, .RcalVal = 10000.0, /* Calibration Resistor Value (Ohms) */
.RtiaVal = 200.0, .RtiaVal = 200.0, /* TIA Gain Resistor Value (Ohms) */
.DswitchSel = SWD_CE0, .DswitchSel = SWD_CE0,
.PswitchSel = SWP_CE0, .PswitchSel = SWP_CE0,
@ -39,14 +39,14 @@ AppIMPCfg_Type AppIMPCfg =
.ExcitBufGain = EXCITBUFGAIN_0P25, .ExcitBufGain = EXCITBUFGAIN_0P25,
.HsDacGain = HSDACGAIN_0P2, .HsDacGain = HSDACGAIN_0P2,
.HsDacUpdateRate = 7, .HsDacUpdateRate = 7,
.DacVoltPP = 600.0, .DacVoltPP = 600.0, /* Excitation Amplitude (mV peak-to-peak) */
.BiasVolt = -0.0f, .BiasVolt = -0.0f, /* DC Bias Voltage */
.SinFreq = 1000.0, .SinFreq = 1000.0, /* Fixed Frequency (Hz) */
.DftNum = DFTNUM_16384, .DftNum = DFTNUM_16384, /* DFT Point Count */
.DftSrc = DFTSRC_SINC3, .DftSrc = DFTSRC_SINC3,
.HanWinEn = bTRUE, .HanWinEn = bTRUE, /* Hanning Window for spectral leakage reduction */
.AdcPgaGain = ADCPGA_1P5, .AdcPgaGain = ADCPGA_1P5,
.ADCSinc3Osr = ADCSINC3OSR_2, .ADCSinc3Osr = ADCSINC3OSR_2,
@ -61,7 +61,7 @@ AppIMPCfg_Type AppIMPCfg =
.SweepCfg.SweepLog = bFALSE, .SweepCfg.SweepLog = bFALSE,
.SweepCfg.SweepIndex = 0, .SweepCfg.SweepIndex = 0,
.FifoThresh = 6, /* 3 measurements * 2 (Real/Imag) = 6 words */ .FifoThresh = 6, /* Threshold: 3 measurements * 2 (Real/Imag) = 6 words */
.IMPInited = bFALSE, .IMPInited = bFALSE,
.StopRequired = bFALSE, .StopRequired = bFALSE,
}; };
@ -70,18 +70,21 @@ AppIMPCfg_Type AppIMPCfg =
/* Helper Functions */ /* Helper Functions */
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
// Forward declaration to allow usage in AppIMPCtrl
AD5940Err AppIMPCheckFreq(float freq);
void AppIMPCleanup(void) { void AppIMPCleanup(void) {
// Ensure chip is awake before sending commands // Ensure chip is awake before sending commands
if(AD5940_WakeUp(10) > 10) return; if(AD5940_WakeUp(10) > 10) return;
// 1. Stop Sequencer and Wakeup Timer // Stop Sequencer and Wakeup Timer
AD5940_WUPTCtrl(bFALSE); AD5940_WUPTCtrl(bFALSE);
AD5940_SEQCtrlS(bFALSE); AD5940_SEQCtrlS(bFALSE);
// 2. Stop any active conversions/WG, but KEEP Reference/LDOs ON // Stop active conversions and Waveform Generator, keep Reference/LDOs on
AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT|AFECTRL_WG, bFALSE); AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT|AFECTRL_WG, bFALSE);
// 3. Reset FIFO // Reset FIFO configuration
FIFOCfg_Type fifo_cfg; FIFOCfg_Type fifo_cfg;
fifo_cfg.FIFOEn = bFALSE; fifo_cfg.FIFOEn = bFALSE;
AD5940_FIFOCfg(&fifo_cfg); AD5940_FIFOCfg(&fifo_cfg);
@ -93,7 +96,7 @@ void AppIMPCleanup(void) {
fifo_cfg.FIFOThresh = 6; fifo_cfg.FIFOThresh = 6;
AD5940_FIFOCfg(&fifo_cfg); AD5940_FIFOCfg(&fifo_cfg);
// 4. Clear Interrupts // Clear all interrupt flags
AD5940_INTCClrFlag(AFEINTSRC_ALLINT); AD5940_INTCClrFlag(AFEINTSRC_ALLINT);
} }
@ -104,7 +107,7 @@ void AppIMPCalibrateLFO(void) {
cal_cfg.SystemClkFreq = 16000000.0; cal_cfg.SystemClkFreq = 16000000.0;
float freq; float freq;
// Use SDK function to measure LFOSC // Measure LFOSC frequency to calibrate Wakeup Timer
if(AD5940_LFOSCMeasure(&cal_cfg, &freq) == AD5940ERR_OK) { if(AD5940_LFOSCMeasure(&cal_cfg, &freq) == AD5940ERR_OK) {
AppIMPCfg.WuptClkFreq = freq; AppIMPCfg.WuptClkFreq = freq;
} }
@ -128,7 +131,7 @@ int32_t AppIMPCtrl(uint32_t Command, void *pPara)
{ {
case IMPCTRL_START: case IMPCTRL_START:
{ {
// Unified Start Logic: Always use Manual Trigger + ENDSEQ Interrupt // Configure interrupts and trigger the first sequence manually
AD5940_WUPTCtrl(bFALSE); AD5940_WUPTCtrl(bFALSE);
AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ENDSEQ, bTRUE); AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ENDSEQ, bTRUE);
@ -138,7 +141,23 @@ int32_t AppIMPCtrl(uint32_t Command, void *pPara)
AppIMPCfg.FifoDataCount = 0; AppIMPCfg.FifoDataCount = 0;
AppIMPCfg.StopRequired = bFALSE; AppIMPCfg.StopRequired = bFALSE;
// Trigger first sequence manually // Reset Sweep State for subsequent sweeps
if(AppIMPCfg.SweepCfg.SweepEn)
{
AppIMPCfg.SweepCfg.SweepIndex = 0;
AppIMPCfg.SweepCurrFreq = AppIMPCfg.SweepCfg.SweepStart;
AppIMPCfg.FreqofData = AppIMPCfg.SweepCfg.SweepStart;
// Calculate next frequency immediately so the ISR has the correct 'next' value
AD5940_SweepNext(&AppIMPCfg.SweepCfg, &AppIMPCfg.SweepNextFreq);
// Reset Hardware WG Frequency to Start Frequency (it was left at Stop Freq)
AD5940_WGFreqCtrlS(AppIMPCfg.SweepCurrFreq, AppIMPCfg.SysClkFreq);
// Reset SRAM Wait Times for the Start Frequency
AppIMPCheckFreq(AppIMPCfg.SweepCurrFreq);
}
AD5940_SEQMmrTrig(SEQID_0); AD5940_SEQMmrTrig(SEQID_0);
break; break;
} }
@ -189,6 +208,7 @@ float AppIMPGetCurrFreq(void)
return AppIMPCfg.SinFreq; return AppIMPCfg.SinFreq;
} }
/* Generate Initialization Sequence */
static AD5940Err AppIMPSeqCfgGen(void) static AD5940Err AppIMPSeqCfgGen(void)
{ {
AD5940Err error = AD5940ERR_OK; AD5940Err error = AD5940ERR_OK;
@ -202,6 +222,7 @@ static AD5940Err AppIMPSeqCfgGen(void)
AD5940_SEQGenCtrl(bTRUE); AD5940_SEQGenCtrl(bTRUE);
AD5940_AFECtrlS(AFECTRL_ALL, bFALSE); AD5940_AFECtrlS(AFECTRL_ALL, bFALSE);
// Configure Reference System (High Power and Low Power Buffers)
aferef_cfg.HpBandgapEn = bTRUE; aferef_cfg.HpBandgapEn = bTRUE;
aferef_cfg.Hp1V1BuffEn = bTRUE; aferef_cfg.Hp1V1BuffEn = bTRUE;
aferef_cfg.Hp1V8BuffEn = bTRUE; aferef_cfg.Hp1V8BuffEn = bTRUE;
@ -216,6 +237,7 @@ static AD5940Err AppIMPSeqCfgGen(void)
aferef_cfg.LpRefBoostEn = bFALSE; aferef_cfg.LpRefBoostEn = bFALSE;
AD5940_REFCfgS(&aferef_cfg); AD5940_REFCfgS(&aferef_cfg);
// Configure High Speed Loop (DAC and TIA)
HsLoopCfg.HsDacCfg.ExcitBufGain = AppIMPCfg.ExcitBufGain; HsLoopCfg.HsDacCfg.ExcitBufGain = AppIMPCfg.ExcitBufGain;
HsLoopCfg.HsDacCfg.HsDacGain = AppIMPCfg.HsDacGain; HsLoopCfg.HsDacCfg.HsDacGain = AppIMPCfg.HsDacGain;
HsLoopCfg.HsDacCfg.HsDacUpdateRate = AppIMPCfg.HsDacUpdateRate; HsLoopCfg.HsDacCfg.HsDacUpdateRate = AppIMPCfg.HsDacUpdateRate;
@ -228,11 +250,13 @@ static AD5940Err AppIMPSeqCfgGen(void)
HsLoopCfg.HsTiaCfg.HstiaRtiaSel = AppIMPCfg.HstiaRtiaSel; HsLoopCfg.HsTiaCfg.HstiaRtiaSel = AppIMPCfg.HstiaRtiaSel;
HsLoopCfg.HsTiaCfg.ExtRtia = AppIMPCfg.ExtRtia; HsLoopCfg.HsTiaCfg.ExtRtia = AppIMPCfg.ExtRtia;
// Configure Switch Matrix
HsLoopCfg.SWMatCfg.Dswitch = AppIMPCfg.DswitchSel; HsLoopCfg.SWMatCfg.Dswitch = AppIMPCfg.DswitchSel;
HsLoopCfg.SWMatCfg.Pswitch = AppIMPCfg.PswitchSel; HsLoopCfg.SWMatCfg.Pswitch = AppIMPCfg.PswitchSel;
HsLoopCfg.SWMatCfg.Nswitch = AppIMPCfg.NswitchSel; HsLoopCfg.SWMatCfg.Nswitch = AppIMPCfg.NswitchSel;
HsLoopCfg.SWMatCfg.Tswitch = SWT_TRTIA|AppIMPCfg.TswitchSel; HsLoopCfg.SWMatCfg.Tswitch = SWT_TRTIA|AppIMPCfg.TswitchSel;
// Configure Waveform Generator (Sine Wave)
HsLoopCfg.WgCfg.WgType = WGTYPE_SIN; HsLoopCfg.WgCfg.WgType = WGTYPE_SIN;
HsLoopCfg.WgCfg.GainCalEn = bTRUE; HsLoopCfg.WgCfg.GainCalEn = bTRUE;
HsLoopCfg.WgCfg.OffsetCalEn = bTRUE; HsLoopCfg.WgCfg.OffsetCalEn = bTRUE;
@ -256,6 +280,7 @@ static AD5940Err AppIMPSeqCfgGen(void)
HsLoopCfg.WgCfg.SinCfg.SinPhaseWord = 0; HsLoopCfg.WgCfg.SinCfg.SinPhaseWord = 0;
AD5940_HSLoopCfgS(&HsLoopCfg); AD5940_HSLoopCfgS(&HsLoopCfg);
// Configure DSP and ADC
dsp_cfg.ADCBaseCfg.ADCMuxN = ADCMUXN_HSTIA_N; dsp_cfg.ADCBaseCfg.ADCMuxN = ADCMUXN_HSTIA_N;
dsp_cfg.ADCBaseCfg.ADCMuxP = ADCMUXP_HSTIA_P; dsp_cfg.ADCBaseCfg.ADCMuxP = ADCMUXP_HSTIA_P;
dsp_cfg.ADCBaseCfg.ADCPga = AppIMPCfg.AdcPgaGain; dsp_cfg.ADCBaseCfg.ADCPga = AppIMPCfg.AdcPgaGain;
@ -276,6 +301,7 @@ static AD5940Err AppIMPSeqCfgGen(void)
memset(&dsp_cfg.StatCfg, 0, sizeof(dsp_cfg.StatCfg)); memset(&dsp_cfg.StatCfg, 0, sizeof(dsp_cfg.StatCfg));
AD5940_DSPCfgS(&dsp_cfg); AD5940_DSPCfgS(&dsp_cfg);
// Enable Power for AFE blocks
AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\ AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\
AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\ AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\
AFECTRL_SINC2NOTCH, bTRUE); AFECTRL_SINC2NOTCH, bTRUE);
@ -297,6 +323,7 @@ static AD5940Err AppIMPSeqCfgGen(void)
return AD5940ERR_OK; return AD5940ERR_OK;
} }
/* Generate Measurement Sequence */
static AD5940Err AppIMPSeqMeasureGen(void) static AD5940Err AppIMPSeqMeasureGen(void)
{ {
AD5940Err error = AD5940ERR_OK; AD5940Err error = AD5940ERR_OK;
@ -306,6 +333,7 @@ static AD5940Err AppIMPSeqMeasureGen(void)
SWMatrixCfg_Type sw_cfg; SWMatrixCfg_Type sw_cfg;
ClksCalInfo_Type clks_cal; ClksCalInfo_Type clks_cal;
// Calculate settling time (WaitClks) based on DFT/Filter settings
clks_cal.DataType = DATATYPE_DFT; clks_cal.DataType = DATATYPE_DFT;
clks_cal.DftSrc = AppIMPCfg.DftSrc; clks_cal.DftSrc = AppIMPCfg.DftSrc;
clks_cal.DataCount = 1L<<(AppIMPCfg.DftNum+2); clks_cal.DataCount = 1L<<(AppIMPCfg.DftNum+2);
@ -320,7 +348,7 @@ static AD5940Err AppIMPSeqMeasureGen(void)
AD5940_SEQGenInsert(SEQ_WAIT(16*250)); AD5940_SEQGenInsert(SEQ_WAIT(16*250));
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* Measurement 1: RCAL (Current) */ /* Step 1: Measure Current across RCAL (Calibration) */
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
sw_cfg.Dswitch = SWD_RCAL0; sw_cfg.Dswitch = SWD_RCAL0;
sw_cfg.Pswitch = SWP_RCAL0; sw_cfg.Pswitch = SWP_RCAL0;
@ -328,9 +356,10 @@ static AD5940Err AppIMPSeqMeasureGen(void)
sw_cfg.Tswitch = SWT_RCAL1|SWT_TRTIA; sw_cfg.Tswitch = SWT_RCAL1|SWT_TRTIA;
AD5940_SWMatrixCfgS(&sw_cfg); AD5940_SWMatrixCfgS(&sw_cfg);
/* ADC Mux for Current (HSTIA) */ // ADC Mux for Current (HSTIA)
AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N); AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N);
// Enable AFE Power and Waveform Generator
AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\ AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\
AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\ AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\
AFECTRL_SINC2NOTCH, bTRUE); AFECTRL_SINC2NOTCH, bTRUE);
@ -338,6 +367,7 @@ static AD5940Err AppIMPSeqMeasureGen(void)
AD5940_SEQGenInsert(SEQ_WAIT(16*2000)); AD5940_SEQGenInsert(SEQ_WAIT(16*2000));
AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE); AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE);
// Store address to update wait times later during sweep
AD5940_SEQGenFetchSeq(NULL, &AppIMPCfg.SeqWaitAddr[0]); AD5940_SEQGenFetchSeq(NULL, &AppIMPCfg.SeqWaitAddr[0]);
AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2));
AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2));
@ -348,7 +378,7 @@ static AD5940Err AppIMPSeqMeasureGen(void)
AD5940_AFECtrlS(AFECTRL_WG, bFALSE); AD5940_AFECtrlS(AFECTRL_WG, bFALSE);
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* Measurement 2: Sensor Current (I) */ /* Step 2: Measure Sensor Current (I) */
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
sw_cfg.Dswitch = AppIMPCfg.DswitchSel; sw_cfg.Dswitch = AppIMPCfg.DswitchSel;
sw_cfg.Pswitch = AppIMPCfg.PswitchSel; sw_cfg.Pswitch = AppIMPCfg.PswitchSel;
@ -356,7 +386,7 @@ static AD5940Err AppIMPSeqMeasureGen(void)
sw_cfg.Tswitch = SWT_TRTIA|AppIMPCfg.TswitchSel; sw_cfg.Tswitch = SWT_TRTIA|AppIMPCfg.TswitchSel;
AD5940_SWMatrixCfgS(&sw_cfg); AD5940_SWMatrixCfgS(&sw_cfg);
/* ADC Mux for Current (HSTIA) */ // ADC Mux for Current (HSTIA)
AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N); AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N);
AD5940_AFECtrlS(AFECTRL_ADCPWR|AFECTRL_WG, bTRUE); AD5940_AFECtrlS(AFECTRL_ADCPWR|AFECTRL_WG, bTRUE);
@ -367,17 +397,16 @@ static AD5940Err AppIMPSeqMeasureGen(void)
AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2));
AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2));
// Stop ADC/DFT first, wait 10us, then stop WG
AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bFALSE); AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bFALSE);
AD5940_SEQGenInsert(SEQ_WAIT(16*10)); AD5940_SEQGenInsert(SEQ_WAIT(16*10));
AD5940_AFECtrlS(AFECTRL_WG, bFALSE); AD5940_AFECtrlS(AFECTRL_WG, bFALSE);
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* Measurement 3: Sensor Voltage (V) */ /* Step 3: Measure Sensor Voltage (V) */
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* Switches remain same (Force path active) */ // Switches remain same (Force path active)
/* ADC Mux for Voltage (AIN2/AIN3) */ // ADC Mux for Voltage (AIN2/AIN3)
AD5940_ADCMuxCfgS(ADCMUXP_AIN2, ADCMUXN_AIN3); AD5940_ADCMuxCfgS(ADCMUXP_AIN2, ADCMUXN_AIN3);
AD5940_AFECtrlS(AFECTRL_ADCPWR|AFECTRL_WG, bTRUE); AD5940_AFECtrlS(AFECTRL_ADCPWR|AFECTRL_WG, bTRUE);
@ -388,11 +417,12 @@ static AD5940Err AppIMPSeqMeasureGen(void)
AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2));
AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2));
// Stop ADC/DFT first, wait 10us, then stop WG and ADC Power // Stop ADC/DFT, wait 10us, then stop WG and ADC Power
AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bFALSE); AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bFALSE);
AD5940_SEQGenInsert(SEQ_WAIT(16*10)); AD5940_SEQGenInsert(SEQ_WAIT(16*10));
AD5940_AFECtrlS(AFECTRL_WG|AFECTRL_ADCPWR, bFALSE); AD5940_AFECtrlS(AFECTRL_WG|AFECTRL_ADCPWR, bFALSE);
// Power down AFE blocks
AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\ AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\
AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\ AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\
AFECTRL_SINC2NOTCH, bFALSE); AFECTRL_SINC2NOTCH, bFALSE);
@ -444,7 +474,7 @@ AD5940Err AppIMPCheckFreq(float freq)
AD5940_ADCFilterCfgS(&filter_cfg); AD5940_ADCFilterCfgS(&filter_cfg);
AD5940_DFTCfgS(&dft_cfg); AD5940_DFTCfgS(&dft_cfg);
// Calculate new WaitClks for the sequence // Recalculate settling times (WaitClks) for the new frequency
clks_cal.DataType = DATATYPE_DFT; clks_cal.DataType = DATATYPE_DFT;
clks_cal.DftSrc = freq_params.DftSrc; clks_cal.DftSrc = freq_params.DftSrc;
clks_cal.DataCount = 1L<<(freq_params.DftNum+2); clks_cal.DataCount = 1L<<(freq_params.DftNum+2);
@ -482,7 +512,7 @@ int32_t AppIMPInit(uint32_t *pBuffer, uint32_t BufferSize)
if(AD5940_WakeUp(10) > 10) return AD5940ERR_WAKEUP; if(AD5940_WakeUp(10) > 10) return AD5940ERR_WAKEUP;
// CRITICAL: Stop WUPT and Sequencer before reconfiguration // Stop timers and sequencer before reconfiguration
AD5940_WUPTCtrl(bFALSE); AD5940_WUPTCtrl(bFALSE);
AD5940_SEQCtrlS(bFALSE); AD5940_SEQCtrlS(bFALSE);
@ -526,7 +556,7 @@ int32_t AppIMPInit(uint32_t *pBuffer, uint32_t BufferSize)
AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ENDSEQ, bTRUE); AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ENDSEQ, bTRUE);
// Safety timeout for Init Sequence // Wait for initialization sequence to complete
int timeout = 100000; int timeout = 100000;
while(AD5940_INTCTestFlag(AFEINTC_1, AFEINTSRC_ENDSEQ) == bFALSE) { while(AD5940_INTCTestFlag(AFEINTC_1, AFEINTSRC_ENDSEQ) == bFALSE) {
if(--timeout <= 0) { if(--timeout <= 0) {
@ -614,6 +644,7 @@ int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount)
MagV = sqrt((float)pDftV->Real*pDftV->Real + (float)pDftV->Image*pDftV->Image); MagV = sqrt((float)pDftV->Real*pDftV->Real + (float)pDftV->Image*pDftV->Image);
PhaseV = atan2(-pDftV->Image, pDftV->Real); PhaseV = atan2(-pDftV->Image, pDftV->Real);
// Calculate Impedance: Z = (V / I) * Rtia
if(MagI > 1e-9) if(MagI > 1e-9)
ZMag = (MagV / MagI) * AppIMPCfg.RtiaVal; ZMag = (MagV / MagI) * AppIMPCfg.RtiaVal;
else else
@ -705,9 +736,7 @@ int32_t AppIMPISR(void *pBuff, uint32_t *pCount)
AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK);
AppIMPDataProcess((int32_t*)pBuff, &FifoCnt); AppIMPDataProcess((int32_t*)pBuff, &FifoCnt);
// DUMMY POINT FILTERING // Discard extra data points if they exceed the requested count
// If we are in sweep mode and have exceeded the user's requested count,
// discard this data packet so the host doesn't see the artifact.
if (AppIMPCfg.SweepCfg.SweepEn && AppIMPCfg.RealDataCount > 0) { if (AppIMPCfg.SweepCfg.SweepEn && AppIMPCfg.RealDataCount > 0) {
if (AppIMPCfg.FifoDataCount > AppIMPCfg.RealDataCount) { if (AppIMPCfg.FifoDataCount > AppIMPCfg.RealDataCount) {
*pCount = 0; // Discard *pCount = 0; // Discard

4422
ad5940.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -82,7 +82,6 @@ void MainWindow::setupUi() {
nyquistGraph = new GraphWidget(this); nyquistGraph = new GraphWidget(this);
nyquistGraph->configureNyquistPlot(); nyquistGraph->configureNyquistPlot();
// Raw Data is now Default (Index 0)
tabWidget->addTab(rawGraph, "Raw Data"); tabWidget->addTab(rawGraph, "Raw Data");
tabWidget->addTab(nyquistGraph, "Nyquist Plot"); tabWidget->addTab(nyquistGraph, "Nyquist Plot");
@ -329,6 +328,7 @@ void MainWindow::parseData(const QString &data) {
} }
} }
void MainWindow::computeHilbert() { void MainWindow::computeHilbert() {
int n = sweepReals.size(); int n = sweepReals.size();
if (n == 0) return; if (n == 0) return;
@ -360,7 +360,7 @@ void MainWindow::computeHilbert() {
// 4. IFFT // 4. IFFT
ifft(signal); ifft(signal);
// 5. Extract Imaginary Part (Hilbert Transform) // 5. Extract Imaginary Part (Hilbert Transform) to represent the analytical.
QVector<double> hilbertImag; QVector<double> hilbertImag;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
hilbertImag.append(signal[i].imag()); hilbertImag.append(signal[i].imag());

View File

@ -1,4 +1,4 @@
// File: aluf/src/main.cpp // File: host/src/main.cpp
#include <QApplication> #include <QApplication>
#include "MainWindow.h" #include "MainWindow.h"