diff --git a/.gitignore b/.gitignore index 3bf84da..6bb6743 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ build *.swp *.cmake requirements.txt -ad5940.* +ad5940 pico_sdk_import.cmake build* *.png diff --git a/Impedance.c b/Impedance.c index 4df368f..6b80c88 100644 --- a/Impedance.c +++ b/Impedance.c @@ -1,77 +1,76 @@ // File: Impedance.c -#include "ad5940.h" -#include -#include "string.h" -#include "math.h" #include "Impedance.h" +#include "ad5940.h" +#include "math.h" +#include "string.h" +#include #define AD5940ERR_STOP 10 /* Default LPDAC resolution (2.5V internal reference) */ -#define DAC12BITVOLT_1LSB (2200.0f/4095) // mV -#define DAC6BITVOLT_1LSB (DAC12BITVOLT_1LSB*64) // mV +#define DAC12BITVOLT_1LSB (2200.0f / 4095) // mV +#define DAC6BITVOLT_1LSB (DAC12BITVOLT_1LSB * 64) // mV /* Forward declaration */ AD5940Err AppIMPCheckFreq(float freq); -AppIMPCfg_Type AppIMPCfg = -{ - .bParaChanged = bFALSE, - .SeqStartAddr = 0, - .MaxSeqLen = 0, - - .SeqStartAddrCal = 0, - .MaxSeqLenCal = 0, +AppIMPCfg_Type AppIMPCfg = { + .bParaChanged = bFALSE, + .SeqStartAddr = 0, + .MaxSeqLen = 0, - .ImpODR = 20.0, /* Output Data Rate: 20.0 Hz */ - .NumOfData = 101, /* Default to 101 points (matches default sweep) */ - .RealDataCount = -1, - .SysClkFreq = 16000000.0, - .WuptClkFreq = 32000.0, /* Low Frequency Oscillator (LFO) typically 32kHz */ - .AdcClkFreq = 16000000.0, - .RcalVal = 100.0, /* Calibration Resistor Value (Ohms) */ - .RtiaVal = 200.0, /* TIA Gain Resistor Value (Ohms) */ + .SeqStartAddrCal = 0, + .MaxSeqLenCal = 0, - .DswitchSel = SWD_CE0, - .PswitchSel = SWP_CE0, - .NswitchSel = SWN_SE0, - .TswitchSel = SWT_TRTIA, + .ImpODR = 20.0, /* Output Data Rate: 20.0 Hz */ + .NumOfData = 101, /* Default to 101 points (matches default sweep) */ + .RealDataCount = -1, + .SysClkFreq = 16000000.0, + .WuptClkFreq = 32000.0, /* Low Frequency Oscillator (LFO) typically 32kHz */ + .AdcClkFreq = 16000000.0, + .RcalVal = 100.0, /* Calibration Resistor Value (Ohms) */ + .RtiaVal = 200.0, /* TIA Gain Resistor Value (Ohms) */ - .PwrMod = AFEPWR_HP, + .DswitchSel = SWD_CE0, + .PswitchSel = SWP_CE0, + .NswitchSel = SWN_SE0, + .TswitchSel = SWT_TRTIA, - .HstiaRtiaSel = HSTIARTIA_200, - .ExtRtia = 0, - .ExcitBufGain = EXCITBUFGAIN_0P25, - .HsDacGain = HSDACGAIN_0P2, - .HsDacUpdateRate = 7, - .DacVoltPP = 600.0, /* Excitation Amplitude (mV peak-to-peak) */ - .BiasVolt = -0.0f, /* DC Bias Voltage */ + .PwrMod = AFEPWR_HP, - .SinFreq = 1000.0, /* Fixed Frequency (Hz) */ + .HstiaRtiaSel = HSTIARTIA_200, + .ExtRtia = 0, + .ExcitBufGain = EXCITBUFGAIN_0P25, + .HsDacGain = HSDACGAIN_0P2, + .HsDacUpdateRate = 7, + .DacVoltPP = 600.0, /* Excitation Amplitude (mV peak-to-peak) */ + .BiasVolt = -0.0f, /* DC Bias Voltage */ - .DftNum = DFTNUM_16384, /* DFT Point Count */ - .DftSrc = DFTSRC_SINC3, - .HanWinEn = bTRUE, /* Hanning Window for spectral leakage reduction */ + .SinFreq = 1000.0, /* Fixed Frequency (Hz) */ - .AdcPgaGain = ADCPGA_1P5, - .ADCSinc3Osr = ADCSINC3OSR_2, - .ADCSinc2Osr = ADCSINC2OSR_22, + .DftNum = DFTNUM_16384, /* DFT Point Count */ + .DftSrc = DFTSRC_SINC3, + .HanWinEn = bTRUE, /* Hanning Window for spectral leakage reduction */ - .ADCAvgNum = ADCAVGNUM_16, + .AdcPgaGain = ADCPGA_1P5, + .ADCSinc3Osr = ADCSINC3OSR_2, + .ADCSinc2Osr = ADCSINC2OSR_22, - /* Default Sweep: 1kHz to 100kHz, 50 Points Per Decade (Log) */ - /* Decades = log10(100k) - log10(1k) = 2. Points = 2 * 50 + 1 = 101 */ - .SweepCfg.SweepEn = bTRUE, - .SweepCfg.SweepStart = 1000.0, - .SweepCfg.SweepStop = 100000.0, - .SweepCfg.SweepPoints = 101, - .SweepCfg.SweepLog = bTRUE, - .SweepCfg.SweepIndex = 0, + .ADCAvgNum = ADCAVGNUM_16, - .FifoThresh = 6, /* Threshold: 3 measurements * 2 (Real/Imag) = 6 words */ - .IMPInited = bFALSE, - .StopRequired = bFALSE, - .ShortRe0Se0 = bFALSE, + /* Default Sweep: 1kHz to 100kHz, 50 Points Per Decade (Log) */ + /* Decades = log10(100k) - log10(1k) = 2. Points = 2 * 50 + 1 = 101 */ + .SweepCfg.SweepEn = bTRUE, + .SweepCfg.SweepStart = 1000.0, + .SweepCfg.SweepStop = 100000.0, + .SweepCfg.SweepPoints = 101, + .SweepCfg.SweepLog = bTRUE, + .SweepCfg.SweepIndex = 0, + + .FifoThresh = 6, /* Threshold: 3 measurements * 2 (Real/Imag) = 6 words */ + .IMPInited = bFALSE, + .StopRequired = bFALSE, + .ShortRe0Se0 = bFALSE, }; /* ----------------------------------------------------------------------- */ @@ -79,175 +78,170 @@ AppIMPCfg_Type AppIMPCfg = /* ----------------------------------------------------------------------- */ /** -* @brief Configures the Impedance Sweep parameters. -* @param start Start Frequency in Hz -* @param stop Stop Frequency in Hz -* @param ppd Points Per Decade (Resolution) + * @brief Configures the Impedance Sweep parameters. + * @param start Start Frequency in Hz + * @param stop Stop Frequency in Hz + * @param ppd Points Per Decade (Resolution) */ void AppIMPConfigureSweep(float start, float stop, float ppd) { - if (start <= 0 || stop <= 0 || ppd <= 0) return; + if (start <= 0 || stop <= 0 || ppd <= 0) + return; - AppIMPCfg.SweepCfg.SweepEn = bTRUE; - AppIMPCfg.SweepCfg.SweepStart = start; - AppIMPCfg.SweepCfg.SweepStop = stop; - AppIMPCfg.SweepCfg.SweepLog = bTRUE; - - // Calculate total points based on decades and PPD - // Formula: Points = (Decades * PPD) + 1 - float decades = log10f(stop) - log10f(start); - if (decades < 0) decades = -decades; // Handle sweep down if needed - - uint32_t points = (uint32_t)(decades * ppd) + 1; - AppIMPCfg.SweepCfg.SweepPoints = points; - - // Set NumOfData to stop the sequencer automatically after the sweep - AppIMPCfg.NumOfData = points; - - // Reset Sweep State - AppIMPCfg.FifoDataCount = 0; - AppIMPCfg.SweepCfg.SweepIndex = 0; - AppIMPCfg.SweepCurrFreq = start; - AppIMPCfg.SweepNextFreq = start; + AppIMPCfg.SweepCfg.SweepEn = bTRUE; + AppIMPCfg.SweepCfg.SweepStart = start; + AppIMPCfg.SweepCfg.SweepStop = stop; + AppIMPCfg.SweepCfg.SweepLog = bTRUE; + + // Calculate total points based on decades and PPD + // Formula: Points = (Decades * PPD) + 1 + float decades = log10f(stop) - log10f(start); + if (decades < 0) + decades = -decades; // Handle sweep down if needed + + uint32_t points = (uint32_t)(decades * ppd) + 1; + AppIMPCfg.SweepCfg.SweepPoints = points; + + // Set NumOfData to stop the sequencer automatically after the sweep + AppIMPCfg.NumOfData = points; + + // Reset Sweep State + AppIMPCfg.FifoDataCount = 0; + AppIMPCfg.SweepCfg.SweepIndex = 0; + AppIMPCfg.SweepCurrFreq = start; + AppIMPCfg.SweepNextFreq = start; } void AppIMPCleanup(void) { - // Ensure chip is awake before sending commands - if(AD5940_WakeUp(10) > 10) return; + // Ensure chip is awake before sending commands + if (AD5940_WakeUp(10) > 10) + return; - // Stop Sequencer and Wakeup Timer - AD5940_WUPTCtrl(bFALSE); - AD5940_SEQCtrlS(bFALSE); - - // Stop active conversions and Waveform Generator, keep Reference/LDOs on - AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT|AFECTRL_WG, bFALSE); + // Stop Sequencer and Wakeup Timer + AD5940_WUPTCtrl(bFALSE); + AD5940_SEQCtrlS(bFALSE); - // Reset FIFO configuration - FIFOCfg_Type fifo_cfg; - fifo_cfg.FIFOEn = bFALSE; - AD5940_FIFOCfg(&fifo_cfg); - - fifo_cfg.FIFOEn = bTRUE; - fifo_cfg.FIFOMode = FIFOMODE_FIFO; - fifo_cfg.FIFOSize = FIFOSIZE_4KB; - fifo_cfg.FIFOSrc = FIFOSRC_DFT; - fifo_cfg.FIFOThresh = 6; - AD5940_FIFOCfg(&fifo_cfg); - - // Clear all interrupt flags - AD5940_INTCClrFlag(AFEINTSRC_ALLINT); + // Stop active conversions and Waveform Generator, keep Reference/LDOs on + AD5940_AFECtrlS(AFECTRL_ADCCNV | AFECTRL_DFT | AFECTRL_WG, bFALSE); + + // Reset FIFO configuration + FIFOCfg_Type fifo_cfg; + fifo_cfg.FIFOEn = bFALSE; + AD5940_FIFOCfg(&fifo_cfg); + + fifo_cfg.FIFOEn = bTRUE; + fifo_cfg.FIFOMode = FIFOMODE_FIFO; + fifo_cfg.FIFOSize = FIFOSIZE_4KB; + fifo_cfg.FIFOSrc = FIFOSRC_DFT; + fifo_cfg.FIFOThresh = 6; + AD5940_FIFOCfg(&fifo_cfg); + + // Clear all interrupt flags + AD5940_INTCClrFlag(AFEINTSRC_ALLINT); } void AppIMPCalibrateLFO(void) { - LFOSCMeasure_Type cal_cfg; - cal_cfg.CalDuration = 1000.0; // 1000ms for high accuracy - cal_cfg.CalSeqAddr = 0; // Use start of SRAM for calibration sequence - cal_cfg.SystemClkFreq = 16000000.0; - - float freq; - // Measure LFOSC frequency to calibrate Wakeup Timer - if(AD5940_LFOSCMeasure(&cal_cfg, &freq) == AD5940ERR_OK) { - AppIMPCfg.WuptClkFreq = freq; - } + LFOSCMeasure_Type cal_cfg; + cal_cfg.CalDuration = 1000.0; // 1000ms for high accuracy + cal_cfg.CalSeqAddr = 0; // Use start of SRAM for calibration sequence + cal_cfg.SystemClkFreq = 16000000.0; + + float freq; + // Measure LFOSC frequency to calibrate Wakeup Timer + if (AD5940_LFOSCMeasure(&cal_cfg, &freq) == AD5940ERR_OK) { + AppIMPCfg.WuptClkFreq = freq; + } } /* ----------------------------------------------------------------------- */ -int32_t AppIMPGetCfg(void *pCfg) -{ - if(pCfg) - { - *(AppIMPCfg_Type**)pCfg = &AppIMPCfg; +int32_t AppIMPGetCfg(void *pCfg) { + if (pCfg) { + *(AppIMPCfg_Type **)pCfg = &AppIMPCfg; return AD5940ERR_OK; } return AD5940ERR_PARA; } -int32_t AppIMPCtrl(uint32_t Command, void *pPara) -{ - switch (Command) - { - case IMPCTRL_START: - { - // Configure interrupts and trigger the first sequence manually - AD5940_WUPTCtrl(bFALSE); - - AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ENDSEQ, bTRUE); - AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_DATAFIFOTHRESH, bFALSE); - AD5940_INTCClrFlag(AFEINTSRC_ALLINT); - - AppIMPCfg.FifoDataCount = 0; - AppIMPCfg.StopRequired = bFALSE; - - // 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); - } +int32_t AppIMPCtrl(uint32_t Command, void *pPara) { + switch (Command) { + case IMPCTRL_START: { + // Configure interrupts and trigger the first sequence manually + AD5940_WUPTCtrl(bFALSE); - AD5940_SEQMmrTrig(SEQID_0); - break; + AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ENDSEQ, bTRUE); + AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_DATAFIFOTHRESH, bFALSE); + AD5940_INTCClrFlag(AFEINTSRC_ALLINT); + + AppIMPCfg.FifoDataCount = 0; + AppIMPCfg.StopRequired = bFALSE; + + // 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); } - case IMPCTRL_STOPNOW: - { - if(AD5940_WakeUp(10) > 10) return AD5940ERR_WAKEUP; - AD5940_WUPTCtrl(bFALSE); - AD5940_SEQCtrlS(bFALSE); - break; - } - case IMPCTRL_STOPSYNC: - { - AppIMPCfg.StopRequired = bTRUE; - break; - } - case IMPCTRL_GETFREQ: - { - if(pPara == 0) return AD5940ERR_PARA; - if(AppIMPCfg.SweepCfg.SweepEn == bTRUE) - *(float*)pPara = AppIMPCfg.FreqofData; - else - *(float*)pPara = AppIMPCfg.SinFreq; - break; - } - case IMPCTRL_SHUTDOWN: - { - AppIMPCtrl(IMPCTRL_STOPNOW, 0); - AFERefCfg_Type aferef_cfg; - LPLoopCfg_Type lp_loop; - memset(&aferef_cfg, 0, sizeof(aferef_cfg)); - AD5940_REFCfgS(&aferef_cfg); - memset(&lp_loop, 0, sizeof(lp_loop)); - AD5940_LPLoopCfgS(&lp_loop); - AD5940_EnterSleepS(); - break; - } - default: - break; + + AD5940_SEQMmrTrig(SEQID_0); + break; + } + case IMPCTRL_STOPNOW: { + if (AD5940_WakeUp(10) > 10) + return AD5940ERR_WAKEUP; + AD5940_WUPTCtrl(bFALSE); + AD5940_SEQCtrlS(bFALSE); + break; + } + case IMPCTRL_STOPSYNC: { + AppIMPCfg.StopRequired = bTRUE; + break; + } + case IMPCTRL_GETFREQ: { + if (pPara == 0) + return AD5940ERR_PARA; + if (AppIMPCfg.SweepCfg.SweepEn == bTRUE) + *(float *)pPara = AppIMPCfg.FreqofData; + else + *(float *)pPara = AppIMPCfg.SinFreq; + break; + } + case IMPCTRL_SHUTDOWN: { + AppIMPCtrl(IMPCTRL_STOPNOW, 0); + AFERefCfg_Type aferef_cfg; + LPLoopCfg_Type lp_loop; + memset(&aferef_cfg, 0, sizeof(aferef_cfg)); + AD5940_REFCfgS(&aferef_cfg); + memset(&lp_loop, 0, sizeof(lp_loop)); + AD5940_LPLoopCfgS(&lp_loop); + AD5940_EnterSleepS(); + break; + } + default: + break; } return AD5940ERR_OK; } -float AppIMPGetCurrFreq(void) -{ - if(AppIMPCfg.SweepCfg.SweepEn == bTRUE) +float AppIMPGetCurrFreq(void) { + if (AppIMPCfg.SweepCfg.SweepEn == bTRUE) return AppIMPCfg.FreqofData; else return AppIMPCfg.SinFreq; } /* Generate Initialization Sequence */ -static AD5940Err AppIMPSeqCfgGen(void) -{ +static AD5940Err AppIMPSeqCfgGen(void) { AD5940Err error = AD5940ERR_OK; const uint32_t *pSeqCmd; uint32_t SeqLen; @@ -272,8 +266,8 @@ static AD5940Err AppIMPSeqCfgGen(void) aferef_cfg.LpBandgapEn = bTRUE; aferef_cfg.LpRefBufEn = bTRUE; 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.HsDacGain = AppIMPCfg.HsDacGain; @@ -291,49 +285,43 @@ static AD5940Err AppIMPSeqCfgGen(void) HsLoopCfg.SWMatCfg.Dswitch = AppIMPCfg.DswitchSel; HsLoopCfg.SWMatCfg.Pswitch = AppIMPCfg.PswitchSel; 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.GainCalEn = bTRUE; HsLoopCfg.WgCfg.OffsetCalEn = bTRUE; - - if(AppIMPCfg.SweepCfg.SweepEn == bTRUE) - { + + if (AppIMPCfg.SweepCfg.SweepEn == bTRUE) { AppIMPCfg.FreqofData = AppIMPCfg.SweepCfg.SweepStart; AppIMPCfg.SweepCurrFreq = AppIMPCfg.SweepCfg.SweepStart; AD5940_SweepNext(&AppIMPCfg.SweepCfg, &AppIMPCfg.SweepNextFreq); sin_freq = AppIMPCfg.SweepCurrFreq; - } - else - { + } else { sin_freq = AppIMPCfg.SinFreq; AppIMPCfg.FreqofData = sin_freq; } - - HsLoopCfg.WgCfg.SinCfg.SinFreqWord = AD5940_WGFreqWordCal(sin_freq, AppIMPCfg.SysClkFreq); - HsLoopCfg.WgCfg.SinCfg.SinAmplitudeWord = (uint32_t)(AppIMPCfg.DacVoltPP/800.0f*2047 + 0.5f); + + HsLoopCfg.WgCfg.SinCfg.SinFreqWord = + AD5940_WGFreqWordCal(sin_freq, AppIMPCfg.SysClkFreq); + HsLoopCfg.WgCfg.SinCfg.SinAmplitudeWord = + (uint32_t)(AppIMPCfg.DacVoltPP / 800.0f * 2047 + 0.5f); HsLoopCfg.WgCfg.SinCfg.SinOffsetWord = 0; HsLoopCfg.WgCfg.SinCfg.SinPhaseWord = 0; AD5940_HSLoopCfgS(&HsLoopCfg); // Handle RE0-SE0 Short (SW11 in LPTIASW0) - if(AppIMPCfg.ShortRe0Se0 == bTRUE) - { - AD5940_SEQGenInsert(SEQ_WR(REG_AFE_LPTIASW0, 0x00000800)); // Close SW11 - } - else - { - AD5940_SEQGenInsert(SEQ_WR(REG_AFE_LPTIASW0, 0x00000000)); // Open all LPTIA switches + if (AppIMPCfg.ShortRe0Se0 == bTRUE) { + AD5940_SEQGenInsert(SEQ_WR(REG_AFE_LPTIASW0, 0x00000800)); // Close SW11 } // Configure DSP and ADC dsp_cfg.ADCBaseCfg.ADCMuxN = ADCMUXN_HSTIA_N; dsp_cfg.ADCBaseCfg.ADCMuxP = ADCMUXP_HSTIA_P; dsp_cfg.ADCBaseCfg.ADCPga = AppIMPCfg.AdcPgaGain; - + memset(&dsp_cfg.ADCDigCompCfg, 0, sizeof(dsp_cfg.ADCDigCompCfg)); - + dsp_cfg.ADCFilterCfg.ADCAvgNum = AppIMPCfg.ADCAvgNum; dsp_cfg.ADCFilterCfg.ADCRate = ADCRATE_800KHZ; dsp_cfg.ADCFilterCfg.ADCSinc2Osr = AppIMPCfg.ADCSinc2Osr; @@ -344,35 +332,33 @@ static AD5940Err AppIMPSeqCfgGen(void) dsp_cfg.DftCfg.DftNum = AppIMPCfg.DftNum; dsp_cfg.DftCfg.DftSrc = AppIMPCfg.DftSrc; dsp_cfg.DftCfg.HanWinEn = AppIMPCfg.HanWinEn; - + memset(&dsp_cfg.StatCfg, 0, sizeof(dsp_cfg.StatCfg)); AD5940_DSPCfgS(&dsp_cfg); - - // Enable Power for AFE blocks - AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\ - AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\ - AFECTRL_SINC2NOTCH, bTRUE); - AD5940_SEQGenInsert(SEQ_STOP()); + // Enable Power for AFE blocks + AD5940_AFECtrlS(AFECTRL_HSTIAPWR | AFECTRL_INAMPPWR | AFECTRL_EXTBUFPWR | + AFECTRL_WG | AFECTRL_DACREFPWR | AFECTRL_HSDACPWR | + AFECTRL_SINC2NOTCH, + bTRUE); + + AD5940_SEQGenInsert(SEQ_STOP()); error = AD5940_SEQGenFetchSeq(&pSeqCmd, &SeqLen); - AD5940_SEQGenCtrl(bFALSE); - if(error == AD5940ERR_OK) - { + AD5940_SEQGenCtrl(bFALSE); + if (error == AD5940ERR_OK) { AppIMPCfg.InitSeqInfo.SeqId = SEQID_1; AppIMPCfg.InitSeqInfo.SeqRamAddr = AppIMPCfg.SeqStartAddr; AppIMPCfg.InitSeqInfo.pSeqCmd = pSeqCmd; AppIMPCfg.InitSeqInfo.SeqLen = SeqLen; AD5940_SEQCmdWrite(AppIMPCfg.InitSeqInfo.SeqRamAddr, pSeqCmd, SeqLen); - } - else - return error; + } else + return error; return AD5940ERR_OK; } /* Generate Measurement Sequence */ -static AD5940Err AppIMPSeqMeasureGen(void) -{ +static AD5940Err AppIMPSeqMeasureGen(void) { AD5940Err error = AD5940ERR_OK; const uint32_t *pSeqCmd; uint32_t SeqLen; @@ -383,16 +369,16 @@ static AD5940Err AppIMPSeqMeasureGen(void) // Calculate settling time (WaitClks) based on DFT/Filter settings clks_cal.DataType = DATATYPE_DFT; clks_cal.DftSrc = AppIMPCfg.DftSrc; - clks_cal.DataCount = 1L<<(AppIMPCfg.DftNum+2); + clks_cal.DataCount = 1L << (AppIMPCfg.DftNum + 2); clks_cal.ADCSinc2Osr = AppIMPCfg.ADCSinc2Osr; clks_cal.ADCSinc3Osr = AppIMPCfg.ADCSinc3Osr; clks_cal.ADCAvgNum = AppIMPCfg.ADCAvgNum; - clks_cal.RatioSys2AdcClk = AppIMPCfg.SysClkFreq/AppIMPCfg.AdcClkFreq; + clks_cal.RatioSys2AdcClk = AppIMPCfg.SysClkFreq / AppIMPCfg.AdcClkFreq; AD5940_ClksCalculate(&clks_cal, &WaitClks); AD5940_SEQGenCtrl(bTRUE); - AD5940_SEQGpioCtrlS(AGPIO_Pin2); - AD5940_SEQGenInsert(SEQ_WAIT(16*250)); + AD5940_SEQGpioCtrlS(AGPIO_Pin2); + AD5940_SEQGenInsert(SEQ_WAIT(16 * 250)); /* ----------------------------------------------------------------------- */ /* Step 1: Measure Current across RCAL (Calibration) */ @@ -400,28 +386,29 @@ static AD5940Err AppIMPSeqMeasureGen(void) sw_cfg.Dswitch = SWD_RCAL0; sw_cfg.Pswitch = SWP_RCAL0; sw_cfg.Nswitch = SWN_RCAL1; - sw_cfg.Tswitch = SWT_RCAL1|SWT_TRTIA; + sw_cfg.Tswitch = SWT_RCAL1 | SWT_TRTIA; AD5940_SWMatrixCfgS(&sw_cfg); - + // ADC Mux for Current (HSTIA) AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N); // Enable AFE Power and Waveform Generator - AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\ - AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\ - AFECTRL_SINC2NOTCH, bTRUE); - AD5940_AFECtrlS(AFECTRL_WG|AFECTRL_ADCPWR, bTRUE); - AD5940_SEQGenInsert(SEQ_WAIT(16*2000)); - AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE); - + AD5940_AFECtrlS(AFECTRL_HSTIAPWR | AFECTRL_INAMPPWR | AFECTRL_EXTBUFPWR | + AFECTRL_WG | AFECTRL_DACREFPWR | AFECTRL_HSDACPWR | + AFECTRL_SINC2NOTCH, + bTRUE); + AD5940_AFECtrlS(AFECTRL_WG | AFECTRL_ADCPWR, bTRUE); + AD5940_SEQGenInsert(SEQ_WAIT(16 * 2000)); + AD5940_AFECtrlS(AFECTRL_ADCCNV | AFECTRL_DFT, bTRUE); + // Store address to update wait times later during sweep - AD5940_SEQGenFetchSeq(NULL, &AppIMPCfg.SeqWaitAddr[0]); - AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); - AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); - + AD5940_SEQGenFetchSeq(NULL, &AppIMPCfg.SeqWaitAddr[0]); + 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_SEQGenInsert(SEQ_WAIT(16*10)); + AD5940_AFECtrlS(AFECTRL_ADCCNV | AFECTRL_DFT, bFALSE); + AD5940_SEQGenInsert(SEQ_WAIT(16 * 10)); AD5940_AFECtrlS(AFECTRL_WG, bFALSE); /* ----------------------------------------------------------------------- */ @@ -430,71 +417,70 @@ static AD5940Err AppIMPSeqMeasureGen(void) sw_cfg.Dswitch = AppIMPCfg.DswitchSel; sw_cfg.Pswitch = AppIMPCfg.PswitchSel; sw_cfg.Nswitch = AppIMPCfg.NswitchSel; - sw_cfg.Tswitch = SWT_TRTIA|AppIMPCfg.TswitchSel; + sw_cfg.Tswitch = SWT_TRTIA | AppIMPCfg.TswitchSel; AD5940_SWMatrixCfgS(&sw_cfg); - + // ADC Mux for Current (HSTIA) AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N); - AD5940_AFECtrlS(AFECTRL_ADCPWR|AFECTRL_WG, bTRUE); - AD5940_SEQGenInsert(SEQ_WAIT(16*2000)); - AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE); - - AD5940_SEQGenFetchSeq(NULL, &AppIMPCfg.SeqWaitAddr[1]); - AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); - AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); + AD5940_AFECtrlS(AFECTRL_ADCPWR | AFECTRL_WG, bTRUE); + AD5940_SEQGenInsert(SEQ_WAIT(16 * 2000)); + AD5940_AFECtrlS(AFECTRL_ADCCNV | AFECTRL_DFT, bTRUE); - AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bFALSE); - AD5940_SEQGenInsert(SEQ_WAIT(16*10)); + AD5940_SEQGenFetchSeq(NULL, &AppIMPCfg.SeqWaitAddr[1]); + AD5940_SEQGenInsert(SEQ_WAIT(WaitClks / 2)); + AD5940_SEQGenInsert(SEQ_WAIT(WaitClks / 2)); + + AD5940_AFECtrlS(AFECTRL_ADCCNV | AFECTRL_DFT, bFALSE); + AD5940_SEQGenInsert(SEQ_WAIT(16 * 10)); AD5940_AFECtrlS(AFECTRL_WG, bFALSE); /* ----------------------------------------------------------------------- */ /* Step 3: Measure Sensor Voltage (V) */ /* ----------------------------------------------------------------------- */ // Switches remain same (Force path active) - + // ADC Mux for Voltage (AIN2/AIN3) AD5940_ADCMuxCfgS(ADCMUXP_AIN2, ADCMUXN_AIN3); - AD5940_AFECtrlS(AFECTRL_ADCPWR|AFECTRL_WG, bTRUE); - AD5940_SEQGenInsert(SEQ_WAIT(16*2000)); - AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE); - - AD5940_SEQGenFetchSeq(NULL, &AppIMPCfg.SeqWaitAddr[2]); - AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); - AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); + AD5940_AFECtrlS(AFECTRL_ADCPWR | AFECTRL_WG, bTRUE); + AD5940_SEQGenInsert(SEQ_WAIT(16 * 2000)); + AD5940_AFECtrlS(AFECTRL_ADCCNV | AFECTRL_DFT, bTRUE); + + AD5940_SEQGenFetchSeq(NULL, &AppIMPCfg.SeqWaitAddr[2]); + AD5940_SEQGenInsert(SEQ_WAIT(WaitClks / 2)); + AD5940_SEQGenInsert(SEQ_WAIT(WaitClks / 2)); // Stop ADC/DFT, wait 10us, then stop WG and ADC Power - AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bFALSE); - AD5940_SEQGenInsert(SEQ_WAIT(16*10)); - AD5940_AFECtrlS(AFECTRL_WG|AFECTRL_ADCPWR, bFALSE); + AD5940_AFECtrlS(AFECTRL_ADCCNV | AFECTRL_DFT, bFALSE); + AD5940_SEQGenInsert(SEQ_WAIT(16 * 10)); + AD5940_AFECtrlS(AFECTRL_WG | AFECTRL_ADCPWR, bFALSE); // Power down AFE blocks - AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\ - AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\ - AFECTRL_SINC2NOTCH, bFALSE); - AD5940_SEQGpioCtrlS(0); + AD5940_AFECtrlS(AFECTRL_HSTIAPWR | AFECTRL_INAMPPWR | AFECTRL_EXTBUFPWR | + AFECTRL_WG | AFECTRL_DACREFPWR | AFECTRL_HSDACPWR | + AFECTRL_SINC2NOTCH, + bFALSE); + AD5940_SEQGpioCtrlS(0); - AD5940_SEQGenInsert(SEQ_STOP()); + AD5940_SEQGenInsert(SEQ_STOP()); error = AD5940_SEQGenFetchSeq(&pSeqCmd, &SeqLen); - AD5940_SEQGenCtrl(bFALSE); + AD5940_SEQGenCtrl(bFALSE); - if(error == AD5940ERR_OK) - { + if (error == AD5940ERR_OK) { AppIMPCfg.MeasureSeqInfo.SeqId = SEQID_0; - AppIMPCfg.MeasureSeqInfo.SeqRamAddr = AppIMPCfg.InitSeqInfo.SeqRamAddr + AppIMPCfg.InitSeqInfo.SeqLen ; + AppIMPCfg.MeasureSeqInfo.SeqRamAddr = + AppIMPCfg.InitSeqInfo.SeqRamAddr + AppIMPCfg.InitSeqInfo.SeqLen; AppIMPCfg.MeasureSeqInfo.pSeqCmd = pSeqCmd; AppIMPCfg.MeasureSeqInfo.SeqLen = SeqLen; AD5940_SEQCmdWrite(AppIMPCfg.MeasureSeqInfo.SeqRamAddr, pSeqCmd, SeqLen); - } - else - return error; + } else + return error; return AD5940ERR_OK; } -AD5940Err AppIMPCheckFreq(float freq) -{ +AD5940Err AppIMPCheckFreq(float freq) { ADCFilterCfg_Type filter_cfg; DFTCfg_Type dft_cfg; uint32_t WaitClks; @@ -502,214 +488,212 @@ AD5940Err AppIMPCheckFreq(float freq) FreqParams_Type freq_params; uint32_t SeqCmdBuff[32]; uint32_t SRAMAddr = 0; - + freq_params = AD5940_GetFreqParameters(freq); - + // Update ADC Filter and DFT settings based on frequency - filter_cfg.ADCAvgNum = ADCAVGNUM_16; + filter_cfg.ADCAvgNum = ADCAVGNUM_16; filter_cfg.ADCSinc2Osr = freq_params.ADCSinc2Osr; filter_cfg.ADCSinc3Osr = freq_params.ADCSinc3Osr; filter_cfg.BpSinc3 = bFALSE; filter_cfg.BpNotch = bTRUE; filter_cfg.Sinc2NotchEnable = bTRUE; filter_cfg.ADCRate = ADCRATE_800KHZ; // Fixed ADC Rate for stability - + dft_cfg.DftNum = freq_params.DftNum; dft_cfg.DftSrc = freq_params.DftSrc; dft_cfg.HanWinEn = AppIMPCfg.HanWinEn; - + AD5940_ADCFilterCfgS(&filter_cfg); AD5940_DFTCfgS(&dft_cfg); - + // Recalculate settling times (WaitClks) for the new frequency clks_cal.DataType = DATATYPE_DFT; clks_cal.DftSrc = freq_params.DftSrc; - clks_cal.DataCount = 1L<<(freq_params.DftNum+2); + clks_cal.DataCount = 1L << (freq_params.DftNum + 2); clks_cal.ADCSinc2Osr = freq_params.ADCSinc2Osr; clks_cal.ADCSinc3Osr = freq_params.ADCSinc3Osr; clks_cal.ADCAvgNum = 0; - clks_cal.RatioSys2AdcClk = AppIMPCfg.SysClkFreq/AppIMPCfg.AdcClkFreq; - AD5940_ClksCalculate(&clks_cal, &WaitClks); - + clks_cal.RatioSys2AdcClk = AppIMPCfg.SysClkFreq / AppIMPCfg.AdcClkFreq; + AD5940_ClksCalculate(&clks_cal, &WaitClks); + // Add safety margin WaitClks += 200; - + // Update Wait Times in SRAM for all 3 measurements for (int i = 0; i < 3; i++) { - if (AppIMPCfg.SeqWaitAddr[i] == 0) continue; + if (AppIMPCfg.SeqWaitAddr[i] == 0) + continue; - SRAMAddr = AppIMPCfg.MeasureSeqInfo.SeqRamAddr + AppIMPCfg.SeqWaitAddr[i]; - - // Split wait time into two commands to handle large values - uint32_t finalWait = WaitClks/2; - - SeqCmdBuff[0] = SEQ_WAIT(finalWait); - SeqCmdBuff[1] = SEQ_WAIT(finalWait); - AD5940_SEQCmdWrite(SRAMAddr, SeqCmdBuff, 2); + SRAMAddr = AppIMPCfg.MeasureSeqInfo.SeqRamAddr + AppIMPCfg.SeqWaitAddr[i]; + + // Split wait time into two commands to handle large values + uint32_t finalWait = WaitClks / 2; + + SeqCmdBuff[0] = SEQ_WAIT(finalWait); + SeqCmdBuff[1] = SEQ_WAIT(finalWait); + AD5940_SEQCmdWrite(SRAMAddr, SeqCmdBuff, 2); } - + return AD5940ERR_OK; } -int32_t AppIMPInit(uint32_t *pBuffer, uint32_t BufferSize) -{ - AD5940Err error = AD5940ERR_OK; +int32_t AppIMPInit(uint32_t *pBuffer, uint32_t BufferSize) { + AD5940Err error = AD5940ERR_OK; SEQCfg_Type seq_cfg; FIFOCfg_Type fifo_cfg; - if(AD5940_WakeUp(10) > 10) return AD5940ERR_WAKEUP; + if (AD5940_WakeUp(10) > 10) + return AD5940ERR_WAKEUP; // Stop timers and sequencer before reconfiguration AD5940_WUPTCtrl(bFALSE); AD5940_SEQCtrlS(bFALSE); - seq_cfg.SeqMemSize = SEQMEMSIZE_2KB; + seq_cfg.SeqMemSize = SEQMEMSIZE_2KB; seq_cfg.SeqBreakEn = bFALSE; seq_cfg.SeqIgnoreEn = bTRUE; seq_cfg.SeqCntCRCClr = bTRUE; seq_cfg.SeqEnable = bFALSE; seq_cfg.SeqWrTimer = 0; AD5940_SEQCfg(&seq_cfg); - + AD5940_FIFOCtrlS(FIFOSRC_DFT, bFALSE); fifo_cfg.FIFOEn = bTRUE; fifo_cfg.FIFOMode = FIFOMODE_FIFO; - fifo_cfg.FIFOSize = FIFOSIZE_4KB; + fifo_cfg.FIFOSize = FIFOSIZE_4KB; fifo_cfg.FIFOSrc = FIFOSRC_DFT; - fifo_cfg.FIFOThresh = AppIMPCfg.FifoThresh; + fifo_cfg.FIFOThresh = AppIMPCfg.FifoThresh; AD5940_FIFOCfg(&fifo_cfg); AD5940_INTCClrFlag(AFEINTSRC_ALLINT); - if((AppIMPCfg.IMPInited == bFALSE)||(AppIMPCfg.bParaChanged == bTRUE)) - { - if(pBuffer == 0) return AD5940ERR_PARA; - if(BufferSize == 0) return AD5940ERR_PARA; + if ((AppIMPCfg.IMPInited == bFALSE) || (AppIMPCfg.bParaChanged == bTRUE)) { + if (pBuffer == 0) + return AD5940ERR_PARA; + if (BufferSize == 0) + return AD5940ERR_PARA; AD5940_SEQGenInit(pBuffer, BufferSize); - error = AppIMPSeqCfgGen(); - if(error != AD5940ERR_OK) return error; + error = AppIMPSeqCfgGen(); + if (error != AD5940ERR_OK) + return error; error = AppIMPSeqMeasureGen(); - if(error != AD5940ERR_OK) return error; + if (error != AD5940ERR_OK) + return error; - AppIMPCfg.bParaChanged = bFALSE; + AppIMPCfg.bParaChanged = bFALSE; } AppIMPCfg.InitSeqInfo.WriteSRAM = bFALSE; AD5940_SEQInfoCfg(&AppIMPCfg.InitSeqInfo); seq_cfg.SeqEnable = bTRUE; - AD5940_SEQCfg(&seq_cfg); + AD5940_SEQCfg(&seq_cfg); AD5940_SEQMmrTrig(AppIMPCfg.InitSeqInfo.SeqId); - + AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ENDSEQ, bTRUE); - + // Wait for initialization sequence to complete int timeout = 100000; - while(AD5940_INTCTestFlag(AFEINTC_1, AFEINTSRC_ENDSEQ) == bFALSE) { - if(--timeout <= 0) { - return AD5940ERR_TIMEOUT; - } + while (AD5940_INTCTestFlag(AFEINTC_1, AFEINTSRC_ENDSEQ) == bFALSE) { + if (--timeout <= 0) { + return AD5940ERR_TIMEOUT; + } } AD5940_INTCClrFlag(AFEINTSRC_ALLINT); AppIMPCfg.MeasureSeqInfo.WriteSRAM = bFALSE; AD5940_SEQInfoCfg(&AppIMPCfg.MeasureSeqInfo); - + // Set initial frequency parameters AppIMPCheckFreq(AppIMPCfg.FreqofData); seq_cfg.SeqEnable = bTRUE; - AD5940_SEQCfg(&seq_cfg); - AD5940_ClrMCUIntFlag(); + AD5940_SEQCfg(&seq_cfg); + AD5940_ClrMCUIntFlag(); - AppIMPCfg.IMPInited = bTRUE; + AppIMPCfg.IMPInited = bTRUE; return AD5940ERR_OK; } -int32_t AppIMPRegModify(int32_t * const pData, uint32_t *pDataCount) -{ - if(AppIMPCfg.NumOfData > 0) - { - AppIMPCfg.FifoDataCount += *pDataCount/6; - if(AppIMPCfg.FifoDataCount >= AppIMPCfg.NumOfData) - { +int32_t AppIMPRegModify(int32_t *const pData, uint32_t *pDataCount) { + if (AppIMPCfg.NumOfData > 0) { + AppIMPCfg.FifoDataCount += *pDataCount / 6; + if (AppIMPCfg.FifoDataCount >= AppIMPCfg.NumOfData) { AD5940_WUPTCtrl(bFALSE); - AD5940_SEQCtrlS(bFALSE); + AD5940_SEQCtrlS(bFALSE); return AD5940ERR_STOP; // Return STOP code } } - if(AppIMPCfg.StopRequired == bTRUE) - { + if (AppIMPCfg.StopRequired == bTRUE) { AD5940_WUPTCtrl(bFALSE); return AD5940ERR_OK; } - if(AppIMPCfg.SweepCfg.SweepEn) - { + if (AppIMPCfg.SweepCfg.SweepEn) { // Update Filters and Wait Times in SRAM AppIMPCheckFreq(AppIMPCfg.SweepNextFreq); - + // Update WG Frequency AD5940_WGFreqCtrlS(AppIMPCfg.SweepNextFreq, AppIMPCfg.SysClkFreq); } return AD5940ERR_OK; } -int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount) -{ +int32_t AppIMPDataProcess(int32_t *const pData, uint32_t *pDataCount) { uint32_t DataCount = *pDataCount; - uint32_t ImpResCount = DataCount/6; + uint32_t ImpResCount = DataCount / 6; - fImpPol_Type * const pOut = (fImpPol_Type*)pData; - iImpCar_Type * pSrcData = (iImpCar_Type*)pData; + fImpPol_Type *const pOut = (fImpPol_Type *)pData; + iImpCar_Type *pSrcData = (iImpCar_Type *)pData; *pDataCount = 0; - for(uint32_t i=0; iReal*pDftI->Real + (float)pDftI->Image*pDftI->Image); + + MagI = sqrt((float)pDftI->Real * pDftI->Real + + (float)pDftI->Image * pDftI->Image); PhaseI = atan2(-pDftI->Image, pDftI->Real); - 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); // Calculate Impedance: Z = (V / I) * Rtia - if(MagI > 1e-9) - ZMag = (MagV / MagI) * AppIMPCfg.RtiaVal; + if (MagI > 1e-9) + ZMag = (MagV / MagI) * AppIMPCfg.RtiaVal; else - ZMag = 0; + ZMag = 0; ZPhase = PhaseV - PhaseI + MATH_PI; - - while(ZPhase > MATH_PI) ZPhase -= 2*MATH_PI; - while(ZPhase < -MATH_PI) ZPhase += 2*MATH_PI; + + while (ZPhase > MATH_PI) + ZPhase -= 2 * MATH_PI; + while (ZPhase < -MATH_PI) + ZPhase += 2 * MATH_PI; pOut[i].Magnitude = ZMag; pOut[i].Phase = ZPhase; } - *pDataCount = ImpResCount; + *pDataCount = ImpResCount; AppIMPCfg.FreqofData = AppIMPCfg.SweepCurrFreq; - - if(AppIMPCfg.SweepCfg.SweepEn == bTRUE) - { + + if (AppIMPCfg.SweepCfg.SweepEn == bTRUE) { AppIMPCfg.FreqofData = AppIMPCfg.SweepCurrFreq; AppIMPCfg.SweepCurrFreq = AppIMPCfg.SweepNextFreq; AD5940_SweepNext(&AppIMPCfg.SweepCfg, &AppIMPCfg.SweepNextFreq); @@ -718,93 +702,88 @@ int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount) return 0; } -int32_t AppIMPISR(void *pBuff, uint32_t *pCount) -{ +int32_t AppIMPISR(void *pBuff, uint32_t *pCount) { uint32_t BuffCount; uint32_t FifoCnt; BuffCount = *pCount; - + *pCount = 0; - - if(AD5940_WakeUp(10) > 10) return AD5940ERR_WAKEUP; - AD5940_SleepKeyCtrlS(SLPKEY_LOCK); + + if (AD5940_WakeUp(10) > 10) + return AD5940ERR_WAKEUP; + AD5940_SleepKeyCtrlS(SLPKEY_LOCK); uint32_t IntFlag = AD5940_INTCGetFlag(AFEINTC_1); if (IntFlag & (AFEINTSRC_DATAFIFOOF | AFEINTSRC_DATAFIFOUF)) { - AD5940_INTCClrFlag(AFEINTSRC_DATAFIFOOF | AFEINTSRC_DATAFIFOUF); - FIFOCfg_Type fifo_cfg; - fifo_cfg.FIFOEn = bFALSE; - AD5940_FIFOCfg(&fifo_cfg); - fifo_cfg.FIFOEn = bTRUE; - fifo_cfg.FIFOMode = FIFOMODE_FIFO; - fifo_cfg.FIFOSize = FIFOSIZE_4KB; - fifo_cfg.FIFOSrc = FIFOSRC_DFT; - fifo_cfg.FIFOThresh = AppIMPCfg.FifoThresh; - AD5940_FIFOCfg(&fifo_cfg); - + AD5940_INTCClrFlag(AFEINTSRC_DATAFIFOOF | AFEINTSRC_DATAFIFOUF); + FIFOCfg_Type fifo_cfg; + fifo_cfg.FIFOEn = bFALSE; + AD5940_FIFOCfg(&fifo_cfg); + fifo_cfg.FIFOEn = bTRUE; + fifo_cfg.FIFOMode = FIFOMODE_FIFO; + fifo_cfg.FIFOSize = FIFOSIZE_4KB; + fifo_cfg.FIFOSrc = FIFOSRC_DFT; + fifo_cfg.FIFOThresh = AppIMPCfg.FifoThresh; + AD5940_FIFOCfg(&fifo_cfg); + + AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); + return AD5940ERR_FIFO; + } + + if (IntFlag & AFEINTSRC_ENDSEQ) { + int timeout = 200; + while (AD5940_FIFOGetCnt() < 6 && timeout-- > 0) { + AD5940_Delay10us(10); + } + + FifoCnt = (AD5940_FIFOGetCnt() / 6) * 6; + if (FifoCnt > BuffCount) + FifoCnt = BuffCount; + + AD5940_FIFORd((uint32_t *)pBuff, FifoCnt); + AD5940_INTCClrFlag(AFEINTSRC_ENDSEQ); + + if (FifoCnt > 0) { + AD5940_SEQCtrlS(bFALSE); + + int32_t status = AppIMPRegModify(pBuff, &FifoCnt); + if (status == AD5940ERR_OK) { + if (AppIMPCfg.FifoDataCount < AppIMPCfg.NumOfData || + AppIMPCfg.NumOfData == -1) { + if (AppIMPCfg.StopRequired == bFALSE) { + AD5940_Delay10us(20); + + AD5940_WriteReg(REG_AFE_SEQCNT, 0); + AD5940_SEQCtrlS(bTRUE); + AD5940_SEQMmrTrig(SEQID_0); + } + } + } + AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); - return AD5940ERR_FIFO; + AppIMPDataProcess((int32_t *)pBuff, &FifoCnt); + + // Discard extra data points if they exceed the requested count + if (AppIMPCfg.SweepCfg.SweepEn && AppIMPCfg.RealDataCount > 0) { + if (AppIMPCfg.FifoDataCount > AppIMPCfg.RealDataCount) { + *pCount = 0; // Discard + } else { + *pCount = FifoCnt; + } + } else { + *pCount = FifoCnt; + } + + if (status == AD5940ERR_STOP) + return AD5940ERR_STOP; + } else { + AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); + *pCount = 0; + } + return 0; } - if(IntFlag & AFEINTSRC_ENDSEQ) - { - int timeout = 200; - while(AD5940_FIFOGetCnt() < 6 && timeout-- > 0) - { - AD5940_Delay10us(10); - } - - FifoCnt = (AD5940_FIFOGetCnt()/6)*6; - if(FifoCnt > BuffCount) FifoCnt = BuffCount; - - AD5940_FIFORd((uint32_t *)pBuff, FifoCnt); - AD5940_INTCClrFlag(AFEINTSRC_ENDSEQ); - - if (FifoCnt > 0) - { - AD5940_SEQCtrlS(bFALSE); - - int32_t status = AppIMPRegModify(pBuff, &FifoCnt); - if (status == AD5940ERR_OK) - { - if(AppIMPCfg.FifoDataCount < AppIMPCfg.NumOfData || AppIMPCfg.NumOfData == -1) - { - if(AppIMPCfg.StopRequired == bFALSE) - { - AD5940_Delay10us(20); - - AD5940_WriteReg(REG_AFE_SEQCNT, 0); - AD5940_SEQCtrlS(bTRUE); - AD5940_SEQMmrTrig(SEQID_0); - } - } - } - - AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); - AppIMPDataProcess((int32_t*)pBuff, &FifoCnt); - - // Discard extra data points if they exceed the requested count - if (AppIMPCfg.SweepCfg.SweepEn && AppIMPCfg.RealDataCount > 0) { - if (AppIMPCfg.FifoDataCount > AppIMPCfg.RealDataCount) { - *pCount = 0; // Discard - } else { - *pCount = FifoCnt; - } - } else { - *pCount = FifoCnt; - } - - if (status == AD5940ERR_STOP) return AD5940ERR_STOP; - } - else - { - AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); - *pCount = 0; - } - return 0; - } - AD5940_INTCClrFlag(AFEINTSRC_ALLINT); AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); return 0; diff --git a/Measurement_Core.c b/Measurement_Core.c index 104db64..53183d7 100644 --- a/Measurement_Core.c +++ b/Measurement_Core.c @@ -2,359 +2,367 @@ #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(); + 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; + 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 = SWT_SE0LOAD; // Restoring Legacy Config (Commit + // 4266c4b). Connects SE0 to T-Node. + + 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); + 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; + 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); + 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; + 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); + 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; + 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; + // 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); - } + 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); + 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); + 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_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_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_1; + AD5940_HSDACCal(&hsdac_cal); - hsdac_cal.ExcitBufGain = EXCITBUFGAIN_0P25; - hsdac_cal.HsDacGain = HSDACGAIN_0P2; - 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; + 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); + 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)); + 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; + 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); + 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; + 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; + 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); - } + 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); + 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.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); + 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); + 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; + // --- 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); + 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); + 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); - 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); + // 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); } \ No newline at end of file diff --git a/Measurement_Routines.c b/Measurement_Routines.c index fa980f8..42f881f 100644 --- a/Measurement_Routines.c +++ b/Measurement_Routines.c @@ -2,201 +2,231 @@ #include "App_Common.h" void Routine_CalibrateLFO(void) { - printf(">> Calibrating LFOSC...\n"); - if (CurrentMode == MODE_IMPEDANCE) AppIMPCleanup(); - else if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0); - else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0); - - LFOSCMeasure_Type cal_cfg; - cal_cfg.CalDuration = 1000.0; - cal_cfg.CalSeqAddr = 0; - cal_cfg.SystemClkFreq = 16000000.0; - - if(AD5940_LFOSCMeasure(&cal_cfg, &LFOSCFreq) == AD5940ERR_OK) { - printf(">> LFOSC Calibrated: %.2f Hz\n", LFOSCFreq); - } else { - printf(">> LFOSC Calibration Failed.\n"); - } + printf(">> Calibrating LFOSC...\n"); + if (CurrentMode == MODE_IMPEDANCE) + AppIMPCleanup(); + else if (CurrentMode == MODE_AMPEROMETRIC) + AppAMPCtrl(AMPCTRL_SHUTDOWN, 0); + else if (CurrentMode == MODE_RAMP) + AppRAMPCtrl(APPCTRL_SHUTDOWN, 0); + + LFOSCMeasure_Type cal_cfg; + cal_cfg.CalDuration = 1000.0; + cal_cfg.CalSeqAddr = 0; + cal_cfg.SystemClkFreq = 16000000.0; + + if (AD5940_LFOSCMeasure(&cal_cfg, &LFOSCFreq) == AD5940ERR_OK) { + printf(">> LFOSC Calibrated: %.2f Hz\n", LFOSCFreq); + } else { + printf(">> LFOSC Calibration Failed.\n"); + } } void Routine_Measure(float freq) { - if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0); - else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0); - CurrentMode = MODE_IMPEDANCE; + if (CurrentMode == MODE_AMPEROMETRIC) + AppAMPCtrl(AMPCTRL_SHUTDOWN, 0); + else if (CurrentMode == MODE_RAMP) + AppRAMPCtrl(APPCTRL_SHUTDOWN, 0); + CurrentMode = MODE_IMPEDANCE; - AppIMPCfg_Type *pCfg; - AppIMPGetCfg(&pCfg); - AppIMPCleanup(); - - AD5940ImpedanceStructInit(); // Reload config with current HP settings - - pCfg->WuptClkFreq = LFOSCFreq; - pCfg->SweepCfg.SweepEn = bFALSE; - pCfg->SinFreq = freq; - pCfg->NumOfData = -1; - pCfg->RealDataCount = -1; - pCfg->bParaChanged = bTRUE; - - if(AppIMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { - AppIMPCtrl(IMPCTRL_START, 0); - } else { - printf("ERROR: Init Failed\n"); - } + AppIMPCfg_Type *pCfg; + AppIMPGetCfg(&pCfg); + AppIMPCleanup(); + + AD5940ImpedanceStructInit(); // Reload config with current HP settings + + pCfg->WuptClkFreq = LFOSCFreq; + pCfg->SweepCfg.SweepEn = bFALSE; + pCfg->SinFreq = freq; + pCfg->NumOfData = -1; + pCfg->RealDataCount = -1; + + // Apply Global Settings + pCfg->ShortRe0Se0 = GlobalShortRe0Se0; + pCfg->HstiaRtiaSel = GetHSTIARtia(ConfigHstiaVal); + pCfg->RtiaVal = (float)ConfigHstiaVal; + + pCfg->bParaChanged = bTRUE; + + if (AppIMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { + AppIMPCtrl(IMPCTRL_START, 0); + } else { + printf("ERROR: Init Failed\n"); + } } void Routine_Sweep(float start, float end, int steps) { - if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0); - else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0); - CurrentMode = MODE_IMPEDANCE; + if (CurrentMode == MODE_AMPEROMETRIC) + AppAMPCtrl(AMPCTRL_SHUTDOWN, 0); + else if (CurrentMode == MODE_RAMP) + AppRAMPCtrl(APPCTRL_SHUTDOWN, 0); + CurrentMode = MODE_IMPEDANCE; - AppIMPCfg_Type *pCfg; - AppIMPGetCfg(&pCfg); - AppIMPCleanup(); - - AD5940ImpedanceStructInit(); // Reload config with current HP settings - - pCfg->WuptClkFreq = LFOSCFreq; - pCfg->SweepCfg.SweepEn = bTRUE; - pCfg->SweepCfg.SweepStart = start; - pCfg->SweepCfg.SweepStop = end; - pCfg->SweepCfg.SweepPoints = steps + 1; - pCfg->NumOfData = steps + 1; - pCfg->RealDataCount = steps; - pCfg->SweepCfg.SweepLog = bTRUE; - pCfg->bParaChanged = bTRUE; - - if(AppIMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { - AppIMPCtrl(IMPCTRL_START, 0); - } else { - printf("ERROR: Init Failed\n"); - } + AppIMPCfg_Type *pCfg; + AppIMPGetCfg(&pCfg); + AppIMPCleanup(); + + AD5940ImpedanceStructInit(); // Reload config with current HP settings + + pCfg->WuptClkFreq = LFOSCFreq; + pCfg->SweepCfg.SweepEn = bTRUE; + pCfg->SweepCfg.SweepStart = start; + pCfg->SweepCfg.SweepStop = end; + pCfg->SweepCfg.SweepPoints = steps + 1; + pCfg->NumOfData = steps + 1; + pCfg->RealDataCount = steps; + pCfg->SweepCfg.SweepLog = bTRUE; + + // Apply Global Settings + pCfg->ShortRe0Se0 = GlobalShortRe0Se0; + pCfg->HstiaRtiaSel = GetHSTIARtia(ConfigHstiaVal); + pCfg->RtiaVal = (float)ConfigHstiaVal; + + pCfg->bParaChanged = bTRUE; + + if (AppIMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { + AppIMPCtrl(IMPCTRL_START, 0); + } else { + printf("ERROR: Init Failed\n"); + } } void Routine_Amperometric(float bias_mv) { - if (CurrentMode == MODE_IMPEDANCE) AppIMPCleanup(); - else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0); - CurrentMode = MODE_AMPEROMETRIC; - - printf(">> Starting Amperometry (Bias: %.1f mV, LP Range: %d)...\n", bias_mv, ConfigLptiaVal); + if (CurrentMode == MODE_IMPEDANCE) + AppIMPCleanup(); + else if (CurrentMode == MODE_RAMP) + AppRAMPCtrl(APPCTRL_SHUTDOWN, 0); + CurrentMode = MODE_AMPEROMETRIC; - AppAMPCfg_Type *pCfg; - AppAMPGetCfg(&pCfg); - AD5940AMPStructInit(); // Reload config with current LP settings - pCfg->SensorBias = bias_mv; - pCfg->ReDoRtiaCal = bFALSE; // Use pre-calibrated value - - if(AppAMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { - AppAMPCtrl(AMPCTRL_START, 0); - } else { - printf("ERROR: AMP Init Failed\n"); - } + printf(">> Starting Amperometry (Bias: %.1f mV, LP Range: %d)...\n", bias_mv, + ConfigLptiaVal); + + AppAMPCfg_Type *pCfg; + AppAMPGetCfg(&pCfg); + AD5940AMPStructInit(); // Reload config with current LP settings + pCfg->SensorBias = bias_mv; + pCfg->ReDoRtiaCal = bFALSE; // Use pre-calibrated value + + if (AppAMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { + AppAMPCtrl(AMPCTRL_START, 0); + } else { + printf("ERROR: AMP Init Failed\n"); + } } void Routine_LSV(float start_mv, float end_mv, int steps, int duration_ms) { - if (CurrentMode == MODE_IMPEDANCE) AppIMPCleanup(); - else if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0); - CurrentMode = MODE_RAMP; + if (CurrentMode == MODE_IMPEDANCE) + AppIMPCleanup(); + else if (CurrentMode == MODE_AMPEROMETRIC) + AppAMPCtrl(AMPCTRL_SHUTDOWN, 0); + CurrentMode = MODE_RAMP; - printf(">> Starting LSV (%.1f to %.1f mV, %d steps, %d ms, LP Range: %d)...\n", start_mv, end_mv, steps, duration_ms, ConfigLptiaVal); + printf( + ">> Starting LSV (%.1f to %.1f mV, %d steps, %d ms, LP Range: %d)...\n", + start_mv, end_mv, steps, duration_ms, ConfigLptiaVal); - AppRAMPCfg_Type *pCfg; - AppRAMPGetCfg(&pCfg); - AD5940RampStructInit(); // Reload config with current LP settings + AppRAMPCfg_Type *pCfg; + AppRAMPGetCfg(&pCfg); + AD5940RampStructInit(); // Reload config with current LP settings - pCfg->RampStartVolt = start_mv; - pCfg->RampPeakVolt = end_mv; - pCfg->StepNumber = steps; - pCfg->RampDuration = duration_ms; - pCfg->bRampOneDir = bTRUE; - pCfg->bParaChanged = bTRUE; + pCfg->RampStartVolt = start_mv; + pCfg->RampPeakVolt = end_mv; + pCfg->StepNumber = steps; + pCfg->RampDuration = duration_ms; + pCfg->bRampOneDir = bTRUE; + pCfg->bParaChanged = bTRUE; - if(AppRAMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { - AppRAMPCtrl(APPCTRL_START, 0); - } else { - printf("ERROR: RAMP Init Failed\n"); - } + if (AppRAMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { + AppRAMPCtrl(APPCTRL_START, 0); + } else { + printf("ERROR: RAMP Init Failed\n"); + } } void Routine_CalibrateSystem(void) { - if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0); - else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0); - CurrentMode = MODE_IMPEDANCE; + if (CurrentMode == MODE_AMPEROMETRIC) + AppAMPCtrl(AMPCTRL_SHUTDOWN, 0); + else if (CurrentMode == MODE_RAMP) + AppRAMPCtrl(APPCTRL_SHUTDOWN, 0); + CurrentMode = MODE_IMPEDANCE; - AppIMPCfg_Type *pCfg; - AppIMPGetCfg(&pCfg); - AppIMPCleanup(); - - ADCPGACal_Type adcpga_cal; - adcpga_cal.AdcClkFreq = 16000000.0; - adcpga_cal.SysClkFreq = 16000000.0; - adcpga_cal.ADCSinc3Osr = ADCSINC3OSR_4; - adcpga_cal.ADCSinc2Osr = ADCSINC2OSR_22; - adcpga_cal.ADCPga = ADCPGA_1P5; - adcpga_cal.PGACalType = PGACALTYPE_OFFSET; - adcpga_cal.TimeOut10us = 1000; - adcpga_cal.VRef1p11 = 1.11; - adcpga_cal.VRef1p82 = 1.82; - printf(">> Calibrating ADC Offset...\n"); - AD5940_ADCPGACal(&adcpga_cal); + AppIMPCfg_Type *pCfg; + AppIMPGetCfg(&pCfg); + AppIMPCleanup(); - // --- 1. Calibrate LPTIA (Low Power Loop) --- - LPRTIACal_Type lprtia_cal; - fImpPol_Type LpRes; - memset(&lprtia_cal, 0, sizeof(lprtia_cal)); - lprtia_cal.AdcClkFreq = 16000000.0; - lprtia_cal.SysClkFreq = 16000000.0; - lprtia_cal.ADCSinc3Osr = ADCSINC3OSR_4; - lprtia_cal.ADCSinc2Osr = ADCSINC2OSR_22; - lprtia_cal.bPolarResult = bTRUE; - lprtia_cal.fRcal = 100.0; - lprtia_cal.LpTiaRtia = GetLPTIARtia(ConfigLptiaVal); - lprtia_cal.LpAmpPwrMod = LPAMPPWR_NORM; - lprtia_cal.bWithCtia = bFALSE; - // Use a low frequency for LPTIA calibration - lprtia_cal.fFreq = 100.0f; - lprtia_cal.DftCfg.DftNum = DFTNUM_2048; - lprtia_cal.DftCfg.DftSrc = DFTSRC_SINC3; - lprtia_cal.DftCfg.HanWinEn = bTRUE; + ADCPGACal_Type adcpga_cal; + adcpga_cal.AdcClkFreq = 16000000.0; + adcpga_cal.SysClkFreq = 16000000.0; + adcpga_cal.ADCSinc3Osr = ADCSINC3OSR_4; + adcpga_cal.ADCSinc2Osr = ADCSINC2OSR_22; + adcpga_cal.ADCPga = ADCPGA_1P5; + adcpga_cal.PGACalType = PGACALTYPE_OFFSET; + adcpga_cal.TimeOut10us = 1000; + adcpga_cal.VRef1p11 = 1.11; + adcpga_cal.VRef1p82 = 1.82; + printf(">> Calibrating ADC Offset...\n"); + AD5940_ADCPGACal(&adcpga_cal); - printf(">> Calibrating LPTIA %d Ohm...\n", ConfigLptiaVal); - if (AD5940_LPRtiaCal(&lprtia_cal, &LpRes) == AD5940ERR_OK) { - printf("Calibrated LPTIA: Mag = %f Ohm, Phase = %f\n", LpRes.Magnitude, LpRes.Phase); - CalibratedLptiaVal = LpRes.Magnitude; - } else { - printf("LPTIA Calibration Failed\n"); - } + // --- 1. Calibrate LPTIA (Low Power Loop) --- + LPRTIACal_Type lprtia_cal; + fImpPol_Type LpRes; + memset(&lprtia_cal, 0, sizeof(lprtia_cal)); + lprtia_cal.AdcClkFreq = 16000000.0; + lprtia_cal.SysClkFreq = 16000000.0; + lprtia_cal.ADCSinc3Osr = ADCSINC3OSR_4; + lprtia_cal.ADCSinc2Osr = ADCSINC2OSR_22; + lprtia_cal.bPolarResult = bTRUE; + lprtia_cal.fRcal = 100.0; + lprtia_cal.LpTiaRtia = GetLPTIARtia(ConfigLptiaVal); + lprtia_cal.LpAmpPwrMod = LPAMPPWR_NORM; + lprtia_cal.bWithCtia = bFALSE; + // Use a low frequency for LPTIA calibration + lprtia_cal.fFreq = 100.0f; + lprtia_cal.DftCfg.DftNum = DFTNUM_2048; + lprtia_cal.DftCfg.DftSrc = DFTSRC_SINC3; + lprtia_cal.DftCfg.HanWinEn = bTRUE; - // --- 2. Calibrate HSTIA (High Speed Loop) --- - HSDACCfg_Type hsdac_cfg; - hsdac_cfg.ExcitBufGain = EXCITBUFGAIN_0P25; - hsdac_cfg.HsDacGain = HSDACGAIN_0P2; - hsdac_cfg.HsDacUpdateRate = 7; - AD5940_HSDacCfgS(&hsdac_cfg); + printf(">> Calibrating LPTIA %d Ohm...\n", ConfigLptiaVal); + if (AD5940_LPRtiaCal(&lprtia_cal, &LpRes) == AD5940ERR_OK) { + printf("Calibrated LPTIA: Mag = %f Ohm, Phase = %f\n", LpRes.Magnitude, + LpRes.Phase); + CalibratedLptiaVal = LpRes.Magnitude; + } else { + printf("LPTIA Calibration Failed\n"); + } - HSRTIACal_Type hsrtia_cal; - fImpPol_Type HsRes; - memset(&hsrtia_cal, 0, sizeof(hsrtia_cal)); - hsrtia_cal.fFreq = 1000.0f; - hsrtia_cal.AdcClkFreq = 16000000.0; - hsrtia_cal.SysClkFreq = 16000000.0; - hsrtia_cal.ADCSinc3Osr = ADCSINC3OSR_4; - hsrtia_cal.ADCSinc2Osr = ADCSINC2OSR_22; - hsrtia_cal.bPolarResult = bTRUE; - hsrtia_cal.fRcal = 100.0; - hsrtia_cal.HsTiaCfg.DiodeClose = bFALSE; - hsrtia_cal.HsTiaCfg.HstiaBias = HSTIABIAS_1P1; - hsrtia_cal.HsTiaCfg.HstiaCtia = 31; - hsrtia_cal.HsTiaCfg.HstiaRtiaSel = GetHSTIARtia(ConfigHstiaVal); - hsrtia_cal.HsTiaCfg.HstiaDeRtia = HSTIADERTIA_OPEN; - hsrtia_cal.HsTiaCfg.HstiaDeRload = HSTIADERLOAD_OPEN; - hsrtia_cal.DftCfg.DftNum = DFTNUM_16384; - hsrtia_cal.DftCfg.DftSrc = DFTSRC_SINC3; + // --- 2. Calibrate HSTIA (High Speed Loop) --- + HSDACCfg_Type hsdac_cfg; + hsdac_cfg.ExcitBufGain = EXCITBUFGAIN_0P25; + hsdac_cfg.HsDacGain = HSDACGAIN_0P2; + hsdac_cfg.HsDacUpdateRate = 7; + AD5940_HSDacCfgS(&hsdac_cfg); - printf(">> Calibrating HSTIA %d Ohm...\n", ConfigHstiaVal); - if (AD5940_HSRtiaCal(&hsrtia_cal, &HsRes) == AD5940ERR_OK) { - printf("Calibrated HSTIA: Mag = %f Ohm, Phase = %f\n", HsRes.Magnitude, HsRes.Phase); - CalibratedHstiaVal = HsRes.Magnitude; - } else { - printf("HSTIA Calibration Failed\n"); - } + HSRTIACal_Type hsrtia_cal; + fImpPol_Type HsRes; + memset(&hsrtia_cal, 0, sizeof(hsrtia_cal)); + hsrtia_cal.fFreq = 1000.0f; + hsrtia_cal.AdcClkFreq = 16000000.0; + hsrtia_cal.SysClkFreq = 16000000.0; + hsrtia_cal.ADCSinc3Osr = ADCSINC3OSR_4; + hsrtia_cal.ADCSinc2Osr = ADCSINC2OSR_22; + hsrtia_cal.bPolarResult = bTRUE; + hsrtia_cal.fRcal = 100.0; + hsrtia_cal.HsTiaCfg.DiodeClose = bFALSE; + hsrtia_cal.HsTiaCfg.HstiaBias = HSTIABIAS_1P1; + hsrtia_cal.HsTiaCfg.HstiaCtia = 31; + hsrtia_cal.HsTiaCfg.HstiaRtiaSel = GetHSTIARtia(ConfigHstiaVal); + hsrtia_cal.HsTiaCfg.HstiaDeRtia = HSTIADERTIA_OPEN; + hsrtia_cal.HsTiaCfg.HstiaDeRload = HSTIADERLOAD_OPEN; + hsrtia_cal.DftCfg.DftNum = DFTNUM_16384; + hsrtia_cal.DftCfg.DftSrc = DFTSRC_SINC3; + + printf(">> Calibrating HSTIA %d Ohm...\n", ConfigHstiaVal); + if (AD5940_HSRtiaCal(&hsrtia_cal, &HsRes) == AD5940ERR_OK) { + printf("Calibrated HSTIA: Mag = %f Ohm, Phase = %f\n", HsRes.Magnitude, + HsRes.Phase); + CalibratedHstiaVal = HsRes.Magnitude; + } else { + printf("HSTIA Calibration Failed\n"); + } } \ No newline at end of file diff --git a/ad5940.h.shortlist.md b/ad5940.h.shortlist.md new file mode 100644 index 0000000..9ff53a4 --- /dev/null +++ b/ad5940.h.shortlist.md @@ -0,0 +1,415 @@ +# Call Graph: ad5940 + +## Common Infrastructure +> Functions called > 5 times. Shown once here. + +### AD5940_ReadAfeResult +└── AD5940_ReadAfeResult + └── #FF4500 **AD5940_ReadReg** ->> + +### __AD5940_TakeMeasurement +└── #00FFFF **__AD5940_TakeMeasurement** + ├── #008000 **AD5940_AFECtrlS** ->> + ├── #FFD700 **AD5940_Delay10us** ->> + ├── AD5940_INTCClrFlag ->> + ├── AD5940_INTCTestFlag ->> + └── AD5940_ReadAfeResult ->> + +### AD5940_HSLoopCfgS +└── AD5940_HSLoopCfgS + ├── AD5940_HSDacCfgS + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_HSTIACfgS + │ ├── #FF0000 **AD5940_WriteReg** ->> + │ └── __AD5940_SetDExRTIA + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_SWMatrixCfgS + │ └── #FF0000 **AD5940_WriteReg** ->> + └── AD5940_WGCfgS + └── #FF0000 **AD5940_WriteReg** ->> + +### AD5940_ADCFilterCfgS +└── AD5940_ADCFilterCfgS + ├── #008000 **AD5940_AFECtrlS** ->> + ├── #FF4500 **AD5940_ReadReg** ->> + └── #FF0000 **AD5940_WriteReg** ->> + +### AD5940_ReadReg +└── #FF4500 **AD5940_ReadReg** + ├── AD5940_D2DReadReg + ├── AD5940_SEQReadReg + │ ├── AD5940_SEQGenGetRegDefault + │ │ ├── AD5940_D2DReadReg + │ │ └── AD5940_SPIReadReg + │ │ ├── AD5940_CsClr ->> + │ │ ├── AD5940_CsSet ->> + │ │ ├── AD5940_ReadWrite16B ->> + │ │ ├── AD5940_ReadWrite32B ->> + │ │ └── AD5940_ReadWrite8B ->> + │ ├── AD5940_SEQGenSearchReg + │ └── AD5940_SEQRegInfoInsert + └── AD5940_SPIReadReg + ├── AD5940_CsClr ->> + ├── AD5940_CsSet ->> + ├── AD5940_ReadWrite16B ->> + ├── AD5940_ReadWrite32B ->> + └── AD5940_ReadWrite8B ->> + +### AD5940_WriteReg +└── #FF0000 **AD5940_WriteReg** + ├── AD5940_D2DWriteReg + ├── AD5940_SEQWriteReg + │ ├── AD5940_SEQGenInsert + │ ├── AD5940_SEQGenSearchReg + │ └── AD5940_SEQRegInfoInsert + └── AD5940_SPIWriteReg + ├── AD5940_CsClr ->> + ├── AD5940_CsSet ->> + ├── AD5940_ReadWrite16B ->> + ├── AD5940_ReadWrite32B ->> + └── AD5940_ReadWrite8B ->> + +### AD5940_ADCMuxCfgS +└── AD5940_ADCMuxCfgS + ├── #FF4500 **AD5940_ReadReg** ->> + └── #FF0000 **AD5940_WriteReg** ->> + +### AD5940_INTCGetCfg +└── AD5940_INTCGetCfg + └── #FF4500 **AD5940_ReadReg** ->> + +### AD5940_AFECtrlS +└── #008000 **AD5940_AFECtrlS** + ├── #FF4500 **AD5940_ReadReg** ->> + └── #FF0000 **AD5940_WriteReg** ->> + +### AD5940_INTCCfg +└── #0000FF **AD5940_INTCCfg** + ├── #FF4500 **AD5940_ReadReg** ->> + └── #FF0000 **AD5940_WriteReg** ->> + +### AD5940_ReadWrite16B +└── AD5940_ReadWrite16B + └── AD5940_ReadWriteNBytes + +### AD5940_ReadWrite8B +└── AD5940_ReadWrite8B + └── AD5940_ReadWriteNBytes + +### __AD5940_ReferenceON +└── __AD5940_ReferenceON + └── AD5940_REFCfgS + ├── #FF4500 **AD5940_ReadReg** ->> + └── #FF0000 **AD5940_WriteReg** ->> + +### AD5940_INTCTestFlag +└── AD5940_INTCTestFlag + └── #FF4500 **AD5940_ReadReg** ->> + +### AD5940_INTCClrFlag +└── AD5940_INTCClrFlag + └── #FF0000 **AD5940_WriteReg** ->> + +### AD5940_ADCBaseCfgS +└── #8B00FF **AD5940_ADCBaseCfgS** + └── #FF0000 **AD5940_WriteReg** ->> + +### AD5940_ReadWrite32B +└── AD5940_ReadWrite32B + └── AD5940_ReadWriteNBytes + +## Execution Tree +└── AD5940_ADCPGACal + ├── #8B00FF **AD5940_ADCBaseCfgS** ->> + ├── #008000 **AD5940_AFECtrlS** ->> + ├── #FFD700 **AD5940_Delay10us** ->> + ├── #0000FF **AD5940_INTCCfg** ->> + ├── #FF4500 **AD5940_ReadReg** ->> + ├── #FF0000 **AD5940_WriteReg** ->> + ├── #00FFFF **__AD5940_TakeMeasurement** ->> + ├── AD5940_ADCConvtCtrlS + │ ├── #FF4500 **AD5940_ReadReg** ->> + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_ADCFilterCfgS ->> + ├── AD5940_HSLoopCfgS ->> + ├── AD5940_INTCGetCfg ->> + └── __AD5940_ReferenceON ->> +└── AD5940_ADCPowerCtrlS + ├── #FF4500 **AD5940_ReadReg** ->> + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_ADCRepeatCfgS + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_AGPIOCfg + ├── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_AGPIOFuncCfg + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_AGPIOIen + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_AGPIOOen + │ └── #FF0000 **AD5940_WriteReg** ->> + └── AD5940_AGPIOPen + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_AGPIOClr + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_AGPIOIn + └── #FF4500 **AD5940_ReadReg** ->> +└── AD5940_AGPIOSet + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_AGPIOToggle + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_ClksCalculate + ├── AD5940_Notch50HzAvailable + │ └── _is_value_in_table ->> + └── AD5940_Notch60HzAvailable + └── _is_value_in_table ->> +└── AD5940_FIFOCfg + ├── #FF4500 **AD5940_ReadReg** ->> + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_FIFOCtrlS + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_FIFOGetCfg + └── #FF4500 **AD5940_ReadReg** ->> +└── AD5940_FIFOGetCnt + └── #FF4500 **AD5940_ReadReg** ->> +└── AD5940_FIFORd + ├── AD5940_CsClr ->> + ├── AD5940_CsSet ->> + ├── AD5940_ReadWrite16B ->> + ├── AD5940_ReadWrite32B ->> + └── AD5940_ReadWrite8B ->> +└── AD5940_FIFOThrshSet + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_GetADIID + └── #FF4500 **AD5940_ReadReg** ->> +└── AD5940_GetChipID + └── #FF4500 **AD5940_ReadReg** ->> +└── AD5940_HPModeEn + ├── #FF4500 **AD5940_ReadReg** ->> + ├── AD5940_AFEPwrBW + │ └── #FF0000 **AD5940_WriteReg** ->> + └── AD5940_CLKCfg + ├── #FFD700 **AD5940_Delay10us** ->> + ├── #FF4500 **AD5940_ReadReg** ->> + ├── #FF0000 **AD5940_WriteReg** ->> + └── AD5940_HFOSC32MHzCtrl + ├── #FF4500 **AD5940_ReadReg** ->> + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_HSDACCal + ├── #8B00FF **AD5940_ADCBaseCfgS** ->> + ├── #008000 **AD5940_AFECtrlS** ->> + ├── #FFD700 **AD5940_Delay10us** ->> + ├── #0000FF **AD5940_INTCCfg** ->> + ├── #FF0000 **AD5940_WriteReg** ->> + ├── #00FFFF **__AD5940_TakeMeasurement** ->> + ├── AD5940_ADCCode2Volt + ├── AD5940_ADCConvtCtrlS + │ ├── #FF4500 **AD5940_ReadReg** ->> + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_ADCFilterCfgS ->> + ├── AD5940_HSLoopCfgS ->> + ├── AD5940_LPLoopCfgS + │ ├── AD5940_LPAMPCfgS + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ └── AD5940_LPDACCfgS + │ ├── #FF0000 **AD5940_WriteReg** ->> + │ ├── AD5940_LPDAC0WriteS + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ └── AD5940_LPDAC1WriteS + │ └── #FF0000 **AD5940_WriteReg** ->> + └── __AD5940_ReferenceON ->> +└── AD5940_HSRTIACfgS + ├── #FF4500 **AD5940_ReadReg** ->> + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_HSRtiaCal + ├── #008000 **AD5940_AFECtrlS** ->> + ├── #FFD700 **AD5940_Delay10us** ->> + ├── #0000FF **AD5940_INTCCfg** ->> + ├── AD5940_ADCMuxCfgS ->> + ├── AD5940_ComplexDivInt + ├── AD5940_ComplexMag + ├── AD5940_ComplexPhase + ├── AD5940_DSPCfgS + │ ├── #8B00FF **AD5940_ADCBaseCfgS** ->> + │ ├── AD5940_ADCDigCompCfgS + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ ├── AD5940_ADCFilterCfgS ->> + │ ├── AD5940_DFTCfgS + │ │ ├── #FF4500 **AD5940_ReadReg** ->> + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ └── AD5940_StatisticCfgS + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_HSLoopCfgS ->> + ├── AD5940_INTCClrFlag ->> + ├── AD5940_INTCGetCfg ->> + ├── AD5940_INTCTestFlag ->> + ├── AD5940_REFCfgS + │ ├── #FF4500 **AD5940_ReadReg** ->> + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_ReadAfeResult ->> + ├── AD5940_StructInit ->> + └── AD5940_WGFreqWordCal +└── AD5940_HWReset + ├── #FFD700 **AD5940_Delay10us** ->> + ├── AD5940_RstClr + └── AD5940_RstSet +└── AD5940_INTCGetFlag + └── #FF4500 **AD5940_ReadReg** ->> +└── AD5940_Initialize + ├── #FF4500 **AD5940_ReadReg** ->> + ├── #FF0000 **AD5940_WriteReg** ->> + └── AD5940_CsSet ->> +└── AD5940_LFOSCMeasure + ├── #0000FF **AD5940_INTCCfg** ->> + ├── AD5940_INTCClrFlag ->> + ├── AD5940_INTCGetCfg ->> + ├── AD5940_INTCTestFlag ->> + ├── AD5940_SEQCfg + │ ├── #FF4500 **AD5940_ReadReg** ->> + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_SEQCtrlS + │ ├── #FF4500 **AD5940_ReadReg** ->> + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_SEQGetCfg + │ └── #FF4500 **AD5940_ReadReg** ->> + ├── AD5940_SEQInfoCfg + │ ├── #FF0000 **AD5940_WriteReg** ->> + │ └── AD5940_SEQCmdWrite + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_SEQTimeOutRd + │ └── #FF4500 **AD5940_ReadReg** ->> + ├── AD5940_WUPTCfg + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_WUPTCtrl + │ ├── #FF4500 **AD5940_ReadReg** ->> + │ └── #FF0000 **AD5940_WriteReg** ->> + └── AD5940_WUPTTime + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_LPDACCal + ├── #8B00FF **AD5940_ADCBaseCfgS** ->> + ├── #008000 **AD5940_AFECtrlS** ->> + ├── #FFD700 **AD5940_Delay10us** ->> + ├── #0000FF **AD5940_INTCCfg** ->> + ├── #00FFFF **__AD5940_TakeMeasurement** ->> + ├── AD5940_ADCConvtCtrlS + │ ├── #FF4500 **AD5940_ReadReg** ->> + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_ADCFilterCfgS ->> + ├── AD5940_ADCMuxCfgS ->> + ├── AD5940_INTCGetCfg ->> + ├── AD5940_LPDACCfgS + │ ├── #FF0000 **AD5940_WriteReg** ->> + │ ├── AD5940_LPDAC0WriteS + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ └── AD5940_LPDAC1WriteS + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_LPDACWriteS + │ └── #FF0000 **AD5940_WriteReg** ->> + └── __AD5940_ReferenceON ->> +└── AD5940_LPModeClkS + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_LPModeCtrlS + ├── #FF4500 **AD5940_ReadReg** ->> + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_LPModeEnS + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_LPRtiaCal + ├── #8B00FF **AD5940_ADCBaseCfgS** ->> + ├── #008000 **AD5940_AFECtrlS** ->> + ├── #FFD700 **AD5940_Delay10us** ->> + ├── #0000FF **AD5940_INTCCfg** ->> + ├── #FF4500 **AD5940_ReadReg** ->> + ├── #FF0000 **AD5940_WriteReg** ->> + ├── #00FFFF **__AD5940_TakeMeasurement** ->> + ├── AD5940_ComplexDivInt + ├── AD5940_ComplexMag + ├── AD5940_ComplexPhase + ├── AD5940_DSPCfgS + │ ├── #8B00FF **AD5940_ADCBaseCfgS** ->> + │ ├── AD5940_ADCDigCompCfgS + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ ├── AD5940_ADCFilterCfgS ->> + │ ├── AD5940_DFTCfgS + │ │ ├── #FF4500 **AD5940_ReadReg** ->> + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ └── AD5940_StatisticCfgS + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_HSLoopCfgS ->> + ├── AD5940_INTCClrFlag ->> + ├── AD5940_INTCGetCfg ->> + ├── AD5940_INTCTestFlag ->> + ├── AD5940_LPLoopCfgS + │ ├── AD5940_LPAMPCfgS + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ └── AD5940_LPDACCfgS + │ ├── #FF0000 **AD5940_WriteReg** ->> + │ ├── AD5940_LPDAC0WriteS + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ └── AD5940_LPDAC1WriteS + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_ReadAfeResult ->> + ├── AD5940_SWMatrixCfgS + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_StructInit ->> + ├── AD5940_WGDACCodeS + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_WGFreqWordCal + └── __AD5940_ReferenceON ->> +└── AD5940_LPTIAOffsetCal + ├── #8B00FF **AD5940_ADCBaseCfgS** ->> + ├── #008000 **AD5940_AFECtrlS** ->> + ├── #FFD700 **AD5940_Delay10us** ->> + ├── #0000FF **AD5940_INTCCfg** ->> + ├── #FF0000 **AD5940_WriteReg** ->> + ├── #00FFFF **__AD5940_TakeMeasurement** ->> + ├── AD5940_ADCConvtCtrlS + │ ├── #FF4500 **AD5940_ReadReg** ->> + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_ADCFilterCfgS ->> + ├── AD5940_INTCGetCfg ->> + ├── AD5940_LPLoopCfgS + │ ├── AD5940_LPAMPCfgS + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ └── AD5940_LPDACCfgS + │ ├── #FF0000 **AD5940_WriteReg** ->> + │ ├── AD5940_LPDAC0WriteS + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ └── AD5940_LPDAC1WriteS + │ └── #FF0000 **AD5940_WriteReg** ->> + └── __AD5940_ReferenceON ->> +└── AD5940_SEQGpioCtrlS + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_SEQGpioTrigCfg + ├── #FF4500 **AD5940_ReadReg** ->> + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_SEQHaltS + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_SEQInfoGet + └── #FF4500 **AD5940_ReadReg** ->> +└── AD5940_SEQMmrTrig + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_ShutDownS + ├── AD5940_EnterSleepS + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_LPLoopCfgS + │ ├── AD5940_LPAMPCfgS + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ └── AD5940_LPDACCfgS + │ ├── #FF0000 **AD5940_WriteReg** ->> + │ ├── AD5940_LPDAC0WriteS + │ │ └── #FF0000 **AD5940_WriteReg** ->> + │ └── AD5940_LPDAC1WriteS + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_REFCfgS + │ ├── #FF4500 **AD5940_ReadReg** ->> + │ └── #FF0000 **AD5940_WriteReg** ->> + ├── AD5940_SleepKeyCtrlS + │ └── #FF0000 **AD5940_WriteReg** ->> + └── AD5940_StructInit ->> +└── AD5940_SoftRst + ├── #FFD700 **AD5940_Delay10us** ->> + └── #FF0000 **AD5940_WriteReg** ->> +└── AD5940_WGFreqCtrlS + ├── #FF0000 **AD5940_WriteReg** ->> + └── AD5940_WGFreqWordCal +└── AD5940_WakeUp + └── #FF4500 **AD5940_ReadReg** ->> diff --git a/examples/AD5940_ADC/AD5940_ADCMeanFIFO.c b/examples/AD5940_ADC/AD5940_ADCMeanFIFO.c deleted file mode 100644 index ecff7bc..0000000 --- a/examples/AD5940_ADC/AD5940_ADCMeanFIFO.c +++ /dev/null @@ -1,103 +0,0 @@ -/*! - ***************************************************************************** - @file: AD5940_ADCMeanFIFO.c - @author: $Author: nxu2 $ - @brief: Use FIFO to read statistic block mean result. - @version: $Revision: 766 $ - @date: $Date: 2017-08-21 14:09:35 +0100 (Mon, 21 Aug 2017) $ - ----------------------------------------------------------------------------- - -Copyright (c) 2017-2019 Analog Devices, Inc. All Rights Reserved. - -This software is proprietary to Analog Devices, Inc. and its licensors. -By using this software you agree to the terms of the associated -Analog Devices Software License Agreement. - -*****************************************************************************/ -/** @addtogroup AD5940_Standard_Examples - * @{ - @defgroup ADC_MEAN_FIFO_Example - @{ - */ - -#include "ad5940.h" -#include - -uint32_t ADCBuff[256]; -void AD5940_Main(void) -{ - ADCBaseCfg_Type adc_base; - ADCFilterCfg_Type adc_filter; - StatCfg_Type stat_cfg; - FIFOCfg_Type fifo_cfg; - - /* Use hardware reset */ - AD5940_HWReset(); - /* Firstly call this function after reset to initialize AFE registers. */ - AD5940_Initialize(); - /* Configure AFE power mode and bandwidth */ - AD5940_AFEPwrBW(AFEPWR_LP, AFEBW_250KHZ); - /* Initialize ADC basic function */ - adc_base.ADCMuxP = ADCMUXP_AVDD_2; - adc_base.ADCMuxN = ADCMUXN_VSET1P1; - adc_base.ADCPga = ADCPGA_1; - AD5940_ADCBaseCfgS(&adc_base); - - /* Initialize ADC filters ADCRawData-->SINC3-->SINC2+NOTCH-->StatisticBlock */ - adc_filter.ADCSinc3Osr = ADCSINC3OSR_4; - adc_filter.ADCSinc2Osr = ADCSINC2OSR_1333; - adc_filter.ADCAvgNum = ADCAVGNUM_2; /* Don't care about it. Average function is only used for DFT */ - adc_filter.ADCRate = ADCRATE_800KHZ; /* If ADC clock is 32MHz, then set it to ADCRATE_1P6MHZ. Default is 16MHz, use ADCRATE_800KHZ. */ - adc_filter.BpNotch = bTRUE; /* SINC2+Notch is one block, when bypass notch filter, we can get fresh data from SINC2 filter. */ - adc_filter.BpSinc3 = bFALSE; /* We use SINC3 filter. */ - adc_filter.Sinc2NotchEnable = bTRUE; /* Enable the SINC2+Notch block. You can also use function AD5940_AFECtrlS */ - AD5940_ADCFilterCfgS(&adc_filter); - - /** - * Statistic block receive data from SINC2+Notch block. Note the diagram in datasheet page 51 PrM. - * The SINC3 can be bypassed optionally. SINC2 cannot be bypassed. - * */ - stat_cfg.StatDev = STATDEV_1; /* Not used. */ - stat_cfg.StatEnable = bTRUE; - stat_cfg.StatSample = STATSAMPLE_128; /* Sample 128 points and calculate mean. */ - AD5940_StatisticCfgS(&stat_cfg); - fifo_cfg.FIFOEn = bTRUE; - fifo_cfg.FIFOMode = FIFOMODE_FIFO; - fifo_cfg.FIFOSize = FIFOSIZE_4KB; - fifo_cfg.FIFOSrc = FIFOSRC_MEAN; - fifo_cfg.FIFOThresh = 2; - AD5940_FIFOCfg(&fifo_cfg); - - /* Enable all interrupt at Interrupt Controller 1. So we can check the interrupt flag */ - AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ALLINT, bTRUE); - AD5940_INTCCfg(AFEINTC_0, AFEINTSRC_DATAFIFOTHRESH, bTRUE); /* Enable FIFO threshold interrupt. */ - AD5940_INTCClrFlag(AFEINTSRC_ALLINT); - AD5940_ClrMCUIntFlag(); /* Clear the MCU interrupt flag which will be set in ISR. */ - - AD5940_AFECtrlS(AFECTRL_ADCPWR|AFECTRL_SINC2NOTCH, bTRUE); - AD5940_AFECtrlS(AFECTRL_ADCCNV, bTRUE); - while(1) - { - uint32_t FifoCnt; - if(AD5940_GetMCUIntFlag()) - { - AD5940_ClrMCUIntFlag(); /* Clear this flag */ - if(AD5940_INTCTestFlag(AFEINTC_0, AFEINTSRC_DATAFIFOTHRESH) == bTRUE) - { - FifoCnt = AD5940_FIFOGetCnt(); - AD5940_FIFORd((uint32_t *)ADCBuff, FifoCnt); - AD5940_INTCClrFlag(AFEINTSRC_DATAFIFOTHRESH); - printf("Get %d data, ADC Code[0]:%d\n",FifoCnt, ADCBuff[0]&0xffff); - /*!!!!!NOTE!!!!!*/ - /* The mean result already removed 32768. So to calculate the voltage, assume mean result is n, use below equation. - Voltage = n/32768*Vref - */ - } - } - } -} - -/** - * @} - * @} - * */ diff --git a/examples/AD5940_ADC/AD5940_ADCNotchTest.c b/examples/AD5940_ADC/AD5940_ADCNotchTest.c deleted file mode 100644 index 0140dae..0000000 --- a/examples/AD5940_ADC/AD5940_ADCNotchTest.c +++ /dev/null @@ -1,205 +0,0 @@ -/*! - ***************************************************************************** - @file: AD5940_ADCNotchTest.c - @author: Neo Xu - @brief: Notch filter test. - ----------------------------------------------------------------------------- - -Copyright (c) 2017-2019 Analog Devices, Inc. All Rights Reserved. - -This software is proprietary to Analog Devices, Inc. and its licensors. -By using this software you agree to the terms of the associated -Analog Devices Software License Agreement. - -*****************************************************************************/ -/** @addtogroup AD5940_Standard_Examples - * @{ - @defgroup ADC_Notch_Test_Example - @{ - */ - -#include "ad5940.h" -#include - -#ifdef ADI_DEBUG -#undef ADI_DEBUG -#endif - -void ad5940_sequencer_init(uint8_t adc_rate, uint8_t sinc3osr, uint8_t sinc2osr){ - FIFOCfg_Type fifo_cfg; - SEQCfg_Type seq_cfg; - /* Step2. Configure FIFO and Sequencer*/ - fifo_cfg.FIFOEn = bFALSE; - fifo_cfg.FIFOMode = FIFOMODE_FIFO; - fifo_cfg.FIFOSize = FIFOSIZE_4KB; /* 4kB for FIFO, The reset 2kB for sequencer */ - fifo_cfg.FIFOSrc = FIFOSRC_SINC2NOTCH; - fifo_cfg.FIFOThresh = 1; - AD5940_FIFOCfg(&fifo_cfg); /* Disable to reset FIFO. */ - fifo_cfg.FIFOEn = bTRUE; - AD5940_FIFOCfg(&fifo_cfg); /* Enable FIFO here */ - /* Configure sequencer and stop it */ - seq_cfg.SeqMemSize = SEQMEMSIZE_2KB; - seq_cfg.SeqBreakEn = bFALSE; - seq_cfg.SeqIgnoreEn = bFALSE; - seq_cfg.SeqCntCRCClr = bTRUE; - seq_cfg.SeqEnable = bFALSE; - seq_cfg.SeqWrTimer = 0; - AD5940_SEQCfg(&seq_cfg); - - uint32_t WaitClks; - uint8_t dl_60, dl_50, dl=0; - ADCFilterCfg_Type filter; - filter.ADCSinc3Osr = sinc3osr; - filter.ADCSinc2Osr = sinc2osr; - filter.ADCRate = adc_rate; - const uint32_t sinc2osr_table[] = {22,44,89,178,267,533,640,667,800,889,1067,1333,0}; - const uint32_t sinc3osr_table[] = {5,4,2,0}; - printf("SINC3:OSR%d, SINC2:OSR%d, ", sinc3osr_table[sinc3osr], sinc2osr_table[sinc2osr]); - if(AD5940_Notch50HzAvailable(&filter, &dl_50)){ - printf("NOTCH50: DL:%d, %dHz ", dl_50, (uint32_t)((adc_rate==ADCRATE_1P6MHZ?1.6e6:800000.0)/sinc3osr_table[sinc3osr]/sinc2osr_table[sinc2osr]/dl_50 + .5)); - dl += dl_50-1; - } - if(AD5940_Notch60HzAvailable(&filter, &dl_60)){ - printf("NOTCH60: DL:%d, %dHz ", dl_60, (uint32_t)((adc_rate==ADCRATE_1P6MHZ?1.6e6:800000.0)/sinc3osr_table[sinc3osr]/sinc2osr_table[sinc2osr]/dl_60 + .5)); - dl += dl_60-1; - } - ClksCalInfo_Type clks_cal; - clks_cal.DataType = DATATYPE_NOTCH; - clks_cal.ADCRate = adc_rate; - clks_cal.DataCount = 1; /* Sample one data when wakeup */ - clks_cal.ADCSinc2Osr = sinc2osr; - clks_cal.ADCSinc3Osr = sinc3osr; - clks_cal.ADCAvgNum = 0; - clks_cal.RatioSys2AdcClk = adc_rate==ADCRATE_1P6MHZ?.5:1; - AD5940_ClksCalculate(&clks_cal, &WaitClks); - - static uint32_t buff[128]; - AD5940_SEQGenInit(buff, 128); - AD5940_SEQGenCtrl(bTRUE); - - AD5940_SEQGpioCtrlS(AGPIO_Pin1); - AD5940_AFECtrlS(AFECTRL_ADCPWR, bTRUE); - AD5940_SEQGenInsert(SEQ_WAIT(16*250)); - AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_SINC2NOTCH, bTRUE); /* Start ADC convert */ - AD5940_SEQGenInsert(SEQ_WAIT(WaitClks)); - //wait for first data ready - AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_ADCPWR|AFECTRL_SINC2NOTCH, bFALSE); /* Stop ADC convert and DFT */ - AD5940_SEQGpioCtrlS(0); - AD5940_SEQGenCtrl(bFALSE); /* Stop sequencer generator */ - - SEQInfo_Type seqinfo; - AD5940_SEQGenFetchSeq(&seqinfo.pSeqCmd, &seqinfo.SeqLen); - seqinfo.SeqId = SEQID_0; - seqinfo.SeqRamAddr = 0; - seqinfo.WriteSRAM = bTRUE; - AD5940_SEQInfoCfg(&seqinfo); - - AGPIOCfg_Type gpio_cfg; - gpio_cfg.FuncSet = GP6_SYNC|GP5_SYNC|GP2_TRIG|GP1_SYNC|GP0_INT; - gpio_cfg.InputEnSet = AGPIO_Pin2; - gpio_cfg.OutputEnSet = AGPIO_Pin0|AGPIO_Pin1|AGPIO_Pin5|AGPIO_Pin6; - gpio_cfg.OutVal = 0; - gpio_cfg.PullEnSet = AGPIO_Pin2; - AD5940_AGPIOCfg(&gpio_cfg); -} - -uint32_t ad5940_notch_test(uint8_t adc_rate, uint8_t sinc3osr, uint8_t sinc2osr){ - ADCBaseCfg_Type adc_base; - ADCFilterCfg_Type adc_filter; - - /* Use hardware reset */ - AD5940_HWReset(); - - /* Firstly call this function after reset to initialize AFE registers. */ - AD5940_Initialize(); - - CLKCfg_Type clk_cfg; - clk_cfg.ADCClkDiv = ADCCLKDIV_1; - clk_cfg.ADCCLkSrc = ADCCLKSRC_HFOSC; - clk_cfg.SysClkDiv = adc_rate==ADCRATE_1P6MHZ?SYSCLKDIV_2:SYSCLKDIV_1; - clk_cfg.SysClkSrc = SYSCLKSRC_HFOSC; - clk_cfg.HfOSC32MHzMode = adc_rate==ADCRATE_1P6MHZ?bTRUE:bFALSE; - clk_cfg.HFOSCEn = bTRUE; - clk_cfg.HFXTALEn = bFALSE; - clk_cfg.LFOSCEn = bTRUE; - AD5940_CLKCfg(&clk_cfg); - - /* Configure AFE power mode and bandwidth */ - AD5940_AFEPwrBW(AFEPWR_LP, AFEBW_250KHZ); - - /* Initialize ADC basic function */ - adc_base.ADCMuxP = ADCMUXP_VREF1P8DAC; - adc_base.ADCMuxN = ADCMUXN_VSET1P1; - adc_base.ADCPga = ADCPGA_1P5; - AD5940_ADCBaseCfgS(&adc_base); - AD5940_AFECtrlS(AFECTRL_DACREFPWR|AFECTRL_HSDACPWR, bTRUE); - /* Initialize ADC filters ADCRawData-->SINC3-->SINC2+NOTCH */ - adc_filter.ADCSinc3Osr = sinc3osr; - adc_filter.ADCSinc2Osr = sinc2osr; - adc_filter.ADCAvgNum = ADCAVGNUM_2; /* Don't care about it. Average function is only used for DFT */ - adc_filter.ADCRate = adc_rate; /* If ADC clock is 32MHz, then set it to ADCRATE_1P6MHZ. Default is 16MHz, use ADCRATE_800KHZ. */ - adc_filter.BpNotch = bFALSE; /* SINC2+Notch is one block, when bypass notch filter, we can get fresh data from SINC2 filter. */ - adc_filter.BpSinc3 = bFALSE; /* We use SINC3 filter. */ - adc_filter.Sinc2NotchEnable = bTRUE; /* Enable the SINC2+Notch block. You can also use function AD5940_AFECtrlS */ - AD5940_ADCFilterCfgS(&adc_filter); - - /* Enable all interrupt at Interrupt Controller 1. So we can check the interrupt flag */ - AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ALLINT, bTRUE); - AD5940_INTCCfg(AFEINTC_0, AFEINTSRC_DATAFIFOTHRESH, bTRUE); - - ad5940_sequencer_init(adc_rate, sinc3osr, sinc2osr); - AD5940_INTCClrFlag(AFEINTSRC_ALLINT); - AD5940_SEQCtrlS(bTRUE); - AD5940_ClrMCUIntFlag(); - AD5940_SEQMmrTrig(SEQID_0); - while(1) - { - {int32_t i = 1000000;while(i--);} - if(AD5940_GetMCUIntFlag()) - { - AD5940_ClrMCUIntFlag(); - uint32_t fifo_count = AD5940_FIFOGetCnt(); - if(fifo_count == 1){ - int32_t rd; - AD5940_FIFORd((uint32_t*)&rd, 1); - rd &= 0xffff; - float volt = AD5940_ADCCode2Volt(rd, ADCPGA_1P5, 1.82)+1.11; - volt -= 1.82; - if(volt < 0) volt = -volt; - if(volt > 0.0005){ - printf("FAILED:CODE:rd:%d\n", rd); - return 1; - } - printf("PASS\n"); - return 0; - } - else{ - printf("FAILED:%d\n", fifo_count); - return 1; - } - } - } -} - -void AD5940_Main(void) -{ - uint32_t failed = 0; - uint8_t sinc3=0, sinc2=0; - uint8_t adc_rate=0; - for(;adc_rate<=1;adc_rate++){ - sinc3=0; - for(;sinc3<=ADCSINC3OSR_2;sinc3++){ - sinc2=0; - for(;sinc2<=ADCSINC2OSR_1333;sinc2++){ - failed |= ad5940_notch_test(adc_rate, sinc3, sinc2); - } - } - } - printf("Test Done with status: %s\n",failed?"FAILED":"SUCCEED"); - while(1); -} - -/** - * @} - * @} - * */ diff --git a/examples/AD5940_ADC/AD5940_ADCPolling.c b/examples/AD5940_ADC/AD5940_ADCPolling.c deleted file mode 100644 index 42def98..0000000 --- a/examples/AD5940_ADC/AD5940_ADCPolling.c +++ /dev/null @@ -1,110 +0,0 @@ -/*! - ***************************************************************************** - @file: AD5940_ADCPolling.c - @author: $Author: nxu2 $ - @brief: ADC Polling mode example - @version: $Revision: 766 $ - @date: $Date: 2017-08-21 14:09:35 +0100 (Mon, 21 Aug 2017) $ - ----------------------------------------------------------------------------- - -Copyright (c) 2017-2019 Analog Devices, Inc. All Rights Reserved. - -This software is proprietary to Analog Devices, Inc. and its licensors. -By using this software you agree to the terms of the associated -Analog Devices Software License Agreement. - -*****************************************************************************/ -/** @addtogroup AD5940_Standard_Examples - * @{ - @defgroup ADC_Polling_Example - @{ - */ - -#include "ad5940.h" -#include - -#define ADCPGA_GAIN_SEL ADCPGA_1P5 -static void AD5940_PGA_Calibration(void){ - AD5940Err err; - ADCPGACal_Type pgacal; - pgacal.AdcClkFreq = 16e6; - pgacal.ADCSinc2Osr = ADCSINC2OSR_178; - pgacal.ADCSinc3Osr = ADCSINC3OSR_4; - pgacal.SysClkFreq = 16e6; - pgacal.TimeOut10us = 1000; - pgacal.VRef1p11 = 1.11f; - pgacal.VRef1p82 = 1.82f; - pgacal.PGACalType = PGACALTYPE_OFFSETGAIN; - pgacal.ADCPga = ADCPGA_GAIN_SEL; - err = AD5940_ADCPGACal(&pgacal); - if(err != AD5940ERR_OK){ - printf("AD5940 PGA calibration failed."); - } -} - -void AD5940_Main(void) -{ - ADCBaseCfg_Type adc_base; - ADCFilterCfg_Type adc_filter; - - /* Use hardware reset */ - AD5940_HWReset(); - - /* Firstly call this function after reset to initialize AFE registers. */ - AD5940_Initialize(); - - AD5940_PGA_Calibration(); - /* Configure AFE power mode and bandwidth */ - AD5940_AFEPwrBW(AFEPWR_LP, AFEBW_250KHZ); - - /* Initialize ADC basic function */ - AD5940_AFECtrlS(AFECTRL_DACREFPWR|AFECTRL_HSDACPWR, bTRUE); //We are going to measure DAC 1.82V reference. - adc_base.ADCMuxP = ADCMUXP_VREF1P8DAC; - adc_base.ADCMuxN = ADCMUXN_VSET1P1; - adc_base.ADCPga = ADCPGA_GAIN_SEL; - AD5940_ADCBaseCfgS(&adc_base); - - /* Initialize ADC filters ADCRawData-->SINC3-->SINC2+NOTCH */ - adc_filter.ADCSinc3Osr = ADCSINC3OSR_4; - adc_filter.ADCSinc2Osr = ADCSINC2OSR_1333; - adc_filter.ADCAvgNum = ADCAVGNUM_2; /* Don't care about it. Average function is only used for DFT */ - adc_filter.ADCRate = ADCRATE_800KHZ; /* If ADC clock is 32MHz, then set it to ADCRATE_1P6MHZ. Default is 16MHz, use ADCRATE_800KHZ. */ - adc_filter.BpNotch = bTRUE; /* SINC2+Notch is one block, when bypass notch filter, we can get fresh data from SINC2 filter. */ - adc_filter.BpSinc3 = bFALSE; /* We use SINC3 filter. */ - adc_filter.Sinc2NotchEnable = bTRUE; /* Enable the SINC2+Notch block. You can also use function AD5940_AFECtrlS */ - AD5940_ADCFilterCfgS(&adc_filter); - - //AD5940_ADCMuxCfgS(ADCMUXP_AIN2, ADCMUXN_VSET1P1); /* Optionally, you can change ADC MUX with this function */ - - /* Enable all interrupt at Interrupt Controller 1. So we can check the interrupt flag */ - AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ALLINT, bTRUE); - - //AD5940_AFECtrlS(AFECTRL_ADCPWR|AFECTRL_SINC2NOTCH, bTRUE); - //AD5940_AFECtrlS(AFECTRL_ADCCNV, bTRUE); - AD5940_ADCPowerCtrlS(bTRUE); - AD5940_ADCConvtCtrlS(bTRUE); - - while(1) - { - uint32_t rd; - if(AD5940_INTCTestFlag(AFEINTC_1,AFEINTSRC_SINC2RDY)) - { - static uint32_t count; - AD5940_INTCClrFlag(AFEINTSRC_SINC2RDY); - rd = AD5940_ReadAfeResult(AFERESULT_SINC2); - count ++; - /* ADC Sample rate is 800kSPS. SINC3 OSR is 4, SINC2 OSR is 1333. So the final output data rate is 800kSPS/4/1333 = 150.0375Hz */ - if(count == 150) /* Print data @1Hz */ - { - count = 0; - float diff_volt = AD5940_ADCCode2Volt(rd, ADCPGA_GAIN_SEL, 1.82); - printf("ADC Code:%d, diff-volt: %.4f, volt:%.4f\n",rd, diff_volt, diff_volt+1.11); - } - } - } -} - -/** - * @} - * @} - * */ diff --git a/examples/AD5940_ECSns_EIS/AD5940Main.c b/examples/AD5940_ECSns_EIS/AD5940Main.c deleted file mode 100644 index 8e06cc0..0000000 --- a/examples/AD5940_ECSns_EIS/AD5940Main.c +++ /dev/null @@ -1,151 +0,0 @@ -/*! - ***************************************************************************** - @file: AD5940Main.c - @author: Neo Xu - @brief: Electrochemical impedance spectroscopy based on example AD5940_Impedance - This project is optomized for 3-lead electrochemical sensors that typically have - an impedance <200ohm. For optimum performance RCAL should be close to - impedance of the sensor. - ----------------------------------------------------------------------------- - -Copyright (c) 2017-2019 Analog Devices, Inc. All Rights Reserved. - -This software is proprietary to Analog Devices, Inc. and its licensors. -By using this software you agree to the terms of the associated -Analog Devices Software License Agreement. - -*****************************************************************************/ -#include "Impedance.h" - -#define APPBUFF_SIZE 512 -uint32_t AppBuff[APPBUFF_SIZE]; - -int32_t ImpedanceShowResult(uint32_t *pData, uint32_t DataCount) -{ - float freq; - - fImpPol_Type *pImp = (fImpPol_Type*)pData; - AppIMPCtrl(IMPCTRL_GETFREQ, &freq); - - printf("Freq:%.2f ", freq); - /*Process data*/ - for(int i=0;iSeqStartAddr = 0; - pImpedanceCfg->MaxSeqLen = 512; /* @todo add checker in function */ - - pImpedanceCfg->RcalVal = 200.0; - pImpedanceCfg->FifoThresh = 6; - pImpedanceCfg->SinFreq = 1000.0; - - /* Configure Excitation Waveform - * - * Output waveform = DacVoltPP * ExcitBufGain * HsDacGain - * - * = 300 * 0.25 * 0.2 = 15mV pk-pk - * - */ - pImpedanceCfg->DacVoltPP = 300; /* Maximum value is 600mV*/ - pImpedanceCfg->ExcitBufGain = EXCITBUFGAIN_0P25; - pImpedanceCfg->HsDacGain = HSDACGAIN_0P2; - - /* Set switch matrix to onboard(EVAL-AD5940ELECZ) gas sensor. */ - pImpedanceCfg->DswitchSel = SWD_CE0; - pImpedanceCfg->PswitchSel = SWP_RE0; - pImpedanceCfg->NswitchSel = SWN_SE0LOAD; - pImpedanceCfg->TswitchSel = SWT_SE0LOAD; - /* The dummy sensor is as low as 5kOhm. We need to make sure RTIA is small enough that HSTIA won't be saturated. */ - pImpedanceCfg->HstiaRtiaSel = HSTIARTIA_200; - pImpedanceCfg->BiasVolt = 0.0; - /* Configure the sweep function. */ - pImpedanceCfg->SweepCfg.SweepEn = bFALSE; - pImpedanceCfg->SweepCfg.SweepStart = 100.0f; /* Start from 1kHz */ - pImpedanceCfg->SweepCfg.SweepStop = 100e3f; /* Stop at 100kHz */ - pImpedanceCfg->SweepCfg.SweepPoints = 101; /* Points is 101 */ - pImpedanceCfg->SweepCfg.SweepLog = bTRUE; - /* Configure Power Mode. Use HP mode if frequency is higher than 80kHz. */ - pImpedanceCfg->PwrMod = AFEPWR_LP; - /* Configure filters if necessary */ - pImpedanceCfg->ADCSinc3Osr = ADCSINC3OSR_4; /* Sample rate is 800kSPS/2 = 400kSPS */ - pImpedanceCfg->DftNum = DFTNUM_16384; - pImpedanceCfg->DftSrc = DFTSRC_SINC3; -} - -void AD5940_Main(void) -{ - uint32_t temp; - AD5940PlatformCfg(); - AD5940ImpedanceStructInit(); - - AppIMPInit(AppBuff, APPBUFF_SIZE); /* Initialize IMP application. Provide a buffer, which is used to store sequencer commands */ - AppIMPCtrl(IMPCTRL_START, 0); /* Control IMP measurement to start. Second parameter has no meaning with this command. */ - - while(1) - { - if(AD5940_GetMCUIntFlag()) - { - AD5940_ClrMCUIntFlag(); - temp = APPBUFF_SIZE; - AppIMPISR(AppBuff, &temp); - ImpedanceShowResult(AppBuff, temp); - } - } -} - diff --git a/examples/AD5940_HSDACCal/AD5940_HSDACCal.c b/examples/AD5940_HSDACCal/AD5940_HSDACCal.c deleted file mode 100644 index 130bd7a..0000000 --- a/examples/AD5940_HSDACCal/AD5940_HSDACCal.c +++ /dev/null @@ -1,95 +0,0 @@ -/*! -***************************************************************************** -@file: AD5940_HSDACCal.c -@author: $Author: nxu2 $ -@brief: HSDAC Offset Calibration Demo calibration demo. -@version: $Revision: 766 $ -@date: $Date: 2017-08-21 14:09:35 +0100 (Mon, 21 Aug 2017) $ ------------------------------------------------------------------------------ - -Copyright (c) 2017-2019 Analog Devices, Inc. All Rights Reserved. - -This software is proprietary to Analog Devices, Inc. and its licensors. -By using this software you agree to the terms of the associated -Analog Devices Software License Agreement. - -*****************************************************************************/ - -#include "ad5940.h" -#include -#include "string.h" - -/* The HSDAC has a number of different gain settings shown in table below. -The HSDAC needs to be calibrated seperately for each gain setting. HSDAC has two powe -modes. There are seperate offset registers for both, DACOFFSET and DACOFFSETHP. The -HSDAC needs to be calibrated for each mode. - -HSDACCON[12] | HSDACCON[0] | Output Range | -0 | 0 | +-607mV | -1 | 0 | +-75mV | -1 | 1 | +-15.14mV | -0 | 1 | +-121.2mV | - -*/ -void AD5940_Main(void){ - HSDACCal_Type hsdac_cal; - ADCPGACal_Type adcpga_cal; - CLKCfg_Type clk_cfg; - /* Use hardware reset */ - AD5940_HWReset(); - AD5940_Initialize(); - - AD5940_AFEPwrBW(AFEPWR_LP, AFEBW_250KHZ); - - clk_cfg.ADCClkDiv = ADCCLKDIV_1; - clk_cfg.ADCCLkSrc = ADCCLKSRC_HFOSC; - clk_cfg.SysClkDiv = SYSCLKDIV_1; - clk_cfg.SysClkSrc = SYSCLKSRC_HFOSC; - clk_cfg.HfOSC32MHzMode = bTRUE; - clk_cfg.HFOSCEn = bTRUE; - clk_cfg.HFXTALEn = bFALSE; - clk_cfg.LFOSCEn = bTRUE; - AD5940_CLKCfg(&clk_cfg); - - - printf("ADC Offset Cal\n"); - adcpga_cal.AdcClkFreq=16000000; - adcpga_cal.ADCPga = ADCPGA_1; - 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); - - printf("\n 607mV Range Cal\n"); - hsdac_cal.ExcitBufGain = EXCITBUFGAIN_2; /**< Select from EXCITBUFGAIN_2, EXCITBUFGAIN_0P25 */ - hsdac_cal.HsDacGain = HSDACGAIN_1; /**< Select from HSDACGAIN_1, HSDACGAIN_0P2 */ - hsdac_cal.AfePwrMode = AFEPWR_LP; - hsdac_cal.ADCSinc2Osr = ADCSINC2OSR_1333; - hsdac_cal.ADCSinc3Osr = ADCSINC3OSR_4; - AD5940_HSDACCal(&hsdac_cal); - - printf("\nADC GN 4 Offset Cal\n"); - adcpga_cal.ADCPga = ADCPGA_4; - AD5940_ADCPGACal(&adcpga_cal); - - printf("\n 125mV Range Cal\n"); - hsdac_cal.ExcitBufGain = EXCITBUFGAIN_2; /**< Select from EXCITBUFGAIN_2, EXCITBUFGAIN_0P25 */ - hsdac_cal.HsDacGain = HSDACGAIN_0P2; /**< Select from HSDACGAIN_1, HSDACGAIN_0P2 */ - AD5940_HSDACCal(&hsdac_cal); - - printf("\n 75mV Range Cal\n"); - hsdac_cal.ExcitBufGain = EXCITBUFGAIN_0P25; /**< Select from EXCITBUFGAIN_2, EXCITBUFGAIN_0P25 */ - hsdac_cal.HsDacGain = HSDACGAIN_1; /**< Select from HSDACGAIN_1, HSDACGAIN_0P2 */ - AD5940_HSDACCal(&hsdac_cal); - - printf("\n 15mV Range Cal\n"); - hsdac_cal.ExcitBufGain = EXCITBUFGAIN_0P25; /**< Select from EXCITBUFGAIN_2, EXCITBUFGAIN_0P25 */ - hsdac_cal.HsDacGain = HSDACGAIN_0P2; /**< Select from HSDACGAIN_1, HSDACGAIN_0P2 */ - AD5940_HSDACCal(&hsdac_cal); - - printf("HSDAC Cal Complete!\n"); -} - diff --git a/examples/AD5940_Impedance_Adjustable_with_frequency/AD5940Main.c b/examples/AD5940_Impedance_Adjustable_with_frequency/AD5940Main.c deleted file mode 100644 index fa9680e..0000000 --- a/examples/AD5940_Impedance_Adjustable_with_frequency/AD5940Main.c +++ /dev/null @@ -1,142 +0,0 @@ -/*! - ***************************************************************************** - @file: AD5940Main.c - @author: Neo Xu - @brief: Standard 4-wire or 2-wire impedance measurement example. - ----------------------------------------------------------------------------- - -Copyright (c) 2017-2019 Analog Devices, Inc. All Rights Reserved. - -This software is proprietary to Analog Devices, Inc. and its licensors. -By using this software you agree to the terms of the associated -Analog Devices Software License Agreement. - -*****************************************************************************/ -#include "Impedance.h" - -/** - User could configure following parameters -**/ - -#define APPBUFF_SIZE 512 -uint32_t AppBuff[APPBUFF_SIZE]; - -int32_t ImpedanceShowResult(uint32_t *pData, uint32_t DataCount) -{ - float freq; - - fImpPol_Type *pImp = (fImpPol_Type*)pData; - AppIMPCtrl(IMPCTRL_GETFREQ, &freq); - - printf("Freq:%.2f ", freq); - /*Process data*/ - for(int i=0;iSeqStartAddr = 0; - pImpedanceCfg->MaxSeqLen = 512; /* @todo add checker in function */ - - pImpedanceCfg->RcalVal = 10000.0; - pImpedanceCfg->SinFreq = 60000.0; - pImpedanceCfg->FifoThresh = 4; - - /* Set switch matrix to onboard(EVAL-AD5940ELECZ) dummy sensor. */ - /* Note the RCAL0 resistor is 10kOhm. */ - pImpedanceCfg->DswitchSel = SWD_CE0; - pImpedanceCfg->PswitchSel = SWP_RE0; - pImpedanceCfg->NswitchSel = SWN_SE0; - pImpedanceCfg->TswitchSel = SWT_SE0LOAD; - /* The dummy sensor is as low as 5kOhm. We need to make sure RTIA is small enough that HSTIA won't be saturated. */ - pImpedanceCfg->HstiaRtiaSel = HSTIARTIA_5K; - - /* Configure the sweep function. */ - pImpedanceCfg->SweepCfg.SweepEn = bTRUE; - pImpedanceCfg->SweepCfg.SweepStart = 1.0f; /* Start from 1kHz */ - pImpedanceCfg->SweepCfg.SweepStop = 200e3f; /* Stop at 100kHz */ - pImpedanceCfg->SweepCfg.SweepPoints = 101; /* Points is 101 */ - pImpedanceCfg->SweepCfg.SweepLog = bTRUE; - /* Configure Power Mode. Use HP mode if frequency is higher than 80kHz. */ - pImpedanceCfg->PwrMod = AFEPWR_LP; - /* Configure filters if necessary */ - pImpedanceCfg->ADCSinc3Osr = ADCSINC3OSR_2; /* Sample rate is 800kSPS/2 = 400kSPS */ - pImpedanceCfg->DftNum = DFTNUM_16384; - pImpedanceCfg->DftSrc = DFTSRC_SINC3; -} - -void AD5940_Main(void) -{ - uint32_t temp; - AD5940PlatformCfg(); - AD5940ImpedanceStructInit(); - - AppIMPInit(AppBuff, APPBUFF_SIZE); /* Initialize IMP application. Provide a buffer, which is used to store sequencer commands */ - AppIMPCtrl(IMPCTRL_START, 0); /* Control IMP measurement to start. Second parameter has no meaning with this command. */ - - while(1) - { - if(AD5940_GetMCUIntFlag()) - { - AD5940_ClrMCUIntFlag(); - temp = APPBUFF_SIZE; - AppIMPISR(AppBuff, &temp); - ImpedanceShowResult(AppBuff, temp); - } - } -} - diff --git a/examples/sequencer/AD5940_Sequencer.c b/examples/sequencer/AD5940_Sequencer.c deleted file mode 100644 index 539a6b3..0000000 --- a/examples/sequencer/AD5940_Sequencer.c +++ /dev/null @@ -1,320 +0,0 @@ -/*! - ***************************************************************************** - @file: AD5940_Sequencer.c - @author: Neo Xu - @brief: Basic usage of sequencer. - ----------------------------------------------------------------------------- - -Copyright (c) 2017-2019 Analog Devices, Inc. All Rights Reserved. - -This software is proprietary to Analog Devices, Inc. and its licensors. -By using this software you agree to the terms of the associated -Analog Devices Software License Agreement. - -*****************************************************************************/ - -/** - * Sequencer is used to control the AFE automatically. It can execute commands that - * is pre-loaded to SRAM. There are 6kB SRAM available while you can choose to use - * 2kB or 4kB of it and use reset of SRAM for data FIFO. - * There are 3 commands available. We mainly use only two commands: - * - Write register - * - Wait - * We control the AFE by registers, so with sequencer, we can do almost everything. - * - * Once sequencer is enabled, it starts to wait valid trigger signal. Sequencer can - * manage 4sequences at same time. You can choose which sequence you want to trigger. - * To make the AFE can manage measurement automatically, there are three method to - * trigger sequence. - * - MMR. You can trigger any sequence by register write. Or call function @ref AD5940_SEQMmrTrig - * - GPIO. You can trigger any sequence by GPIO. To use this, you must firstly set - * GPIO function to GPx_TRIG. Where x is the GPIO number. GPIO0 is used to trigger - * Sequence0 and GPIO3 is used to trigger Sequence3. Check the macro definition to - * Check the details (or below table). - * |GPIO|WhichSequence| - * |GP0|SEQUENCE0| - * |GP1|SEQUENCE1| - * |GP2|SEQUENCE2| - * |GP3|SEQUENCE3| - * |GP4|SEQUENCE0| - * |GP5|SEQUENCE1| - * |GP6|SEQUENCE2| - * |GP7|SEQUENCE3| - * - WakeupTimer. Wakeuptimer can automatically wakeup AFE from hibernate state and trigger selected - * sequence in register SEQORDER. This register defines the order of sequence that - * Wakeuptimer will trigger. There are 8 slots in this register. You can fill in any - * of the four sequences. Also, you can choose not to use all these 8 slots, just simply - * specify the end slot. We call the 8 slots are A/B/C/D/E/F/G/H. For example you can - * choose the end slot as C. So wakeup timer will trigger the sequence in below order: - * A->B->C->A->B->C->A->B->C->... until you stop Wakeuptimer. - * If you fill in slot A with sequence0, B with Sequence3, C with sequence1, the sequence - * will be executed in the order defined above(A-B-C-A-B-C...) - * SEQ0->SEQ3->SEQ1->SEQ0->SEQ3->SEQ1->... - * For each sequence, there is a sleep timer and a wakeup timer. The timer will automatically - * load corresponding value. - * The structure @ref WUPTCfg_Type can be used to initialize all above settings. - * - * In this example, we use both three kinds of trigger source. - * We firstly use Wakeup Timer to trigger sequence 0/1/2. The sequence is used to write registers and - * generate a custom-interrupt. We detect the interrupt to identify which sequence is running. - * Finally, we use GPIO to trigger sequence3. - * - * When there is conflict between trigger signals, for example, GPIO triggered one sequence that is running, - * current strategy is ignore this trigger. - * Use @reg SEQCfg_Type to configure sequencer. - * - * @note: connect GP2 and GP1 together. This demo show how to use GPIO to trigger sequencer. GP2 is the trigger input. - * We use GP1 to generate the trigger signal, while in real case, it should be the MCU's GPIO. -*/ -#include "ad5940.h" -#include -#include "string.h" - -int32_t SeqISR(void); -BoolFlag bSeqEnd = bFALSE; -static const uint32_t Seq0Commands[]= -{ - SEQ_WR(REG_AFE_SWCON, 0x0000), - SEQ_INT0(), /* generate custom-interrupt 0. We can generate any custom interrupt(SEQ_INT0/1/2/3()) by sequencer. */ -}; - -static const uint32_t Seq1Commands[]= -{ - SEQ_WR(REG_AFE_SWCON, 0x1111), - SEQ_INT1(), /* generate custom-interrupt 0 */ - SEQ_STOP(), /* Disable sequencer */ -}; - -static const uint32_t Seq2Commands[]= -{ - SEQ_WR(REG_AFE_SWCON, 0x2222), - SEQ_INT2(), /* generate custom-interrupt 1 */ -}; - -static const uint32_t Seq3Commands[]= -{ - SEQ_WR(REG_AFE_SWCON, 0x3333), - SEQ_INT3(), /* generate custom-interrupt 1 */ -}; - -static int32_t AD5940PlatformCfg(void) -{ - CLKCfg_Type clk_cfg; - FIFOCfg_Type fifo_cfg; - AGPIOCfg_Type gpio_cfg; - - /* Use hardware reset */ - AD5940_HWReset(); - AD5940_Initialize(); /* Call this right after AFE reset */ - /* Platform configuration */ - /* Step1. Configure clock */ - clk_cfg.ADCClkDiv = ADCCLKDIV_1; - clk_cfg.ADCCLkSrc = ADCCLKSRC_HFOSC; - clk_cfg.SysClkDiv = SYSCLKDIV_1; - clk_cfg.SysClkSrc = SYSCLKSRC_HFOSC; - clk_cfg.HfOSC32MHzMode = bFALSE; - clk_cfg.HFOSCEn = bTRUE; - clk_cfg.HFXTALEn = bFALSE; - clk_cfg.LFOSCEn = bTRUE; - AD5940_CLKCfg(&clk_cfg); - /* Step2. Configure FIFO and Sequencer*/ - fifo_cfg.FIFOEn = bFALSE; - fifo_cfg.FIFOMode = FIFOMODE_FIFO; - fifo_cfg.FIFOSize = FIFOSIZE_4KB; /* 4kB for FIFO, The reset 2kB for sequencer */ - fifo_cfg.FIFOSrc = FIFOSRC_DFT; - fifo_cfg.FIFOThresh = 4;//AppIMPCfg.FifoThresh; /* DFT result. One pair for RCAL, another for Rz. One DFT result have real part and imaginary part */ - AD5940_FIFOCfg(&fifo_cfg); - fifo_cfg.FIFOEn = bTRUE; - AD5940_FIFOCfg(&fifo_cfg); - - /* Step3. Interrupt controller */ - AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ALLINT, bTRUE); /* Enable all interrupt in INTC1, so we can check INTC flags */ - AD5940_INTCClrFlag(AFEINTSRC_ALLINT); - AD5940_INTCCfg(AFEINTC_0, AFEINTSRC_ENDSEQ|AFEINTSRC_CUSTOMINT0|AFEINTSRC_CUSTOMINT1|AFEINTSRC_CUSTOMINT2|AFEINTSRC_CUSTOMINT3, bTRUE); - AD5940_INTCClrFlag(AFEINTSRC_ALLINT); - /* Step4: Reconfigure GPIO */ - /* GP0: the interrupt output. - GP1: normal GPIO - GP2: used as trigger to sequence2. If valid trigger signal detected, sequencer will try to run sequence2. - GP3: not used. - GP4: controlled by sequencer. - Others: not used. The default function is mode0. - */ - gpio_cfg.FuncSet = GP0_INT|GP1_GPIO|GP2_TRIG|GP4_SYNC; - gpio_cfg.InputEnSet = AGPIO_Pin2; - gpio_cfg.OutputEnSet = AGPIO_Pin0|AGPIO_Pin1|AGPIO_Pin2|AGPIO_Pin4; - gpio_cfg.OutVal = 0; - gpio_cfg.PullEnSet = 0; - AD5940_AGPIOCfg(&gpio_cfg); - return 0; -} - -#define SEQ0ADDR 0 -#define SEQ1ADDR 16 -#define SEQ2ADDR 32 -#define SEQ3ADDR 48 - -void AD5940_Main(void) -{ - SEQCfg_Type seq_cfg; - FIFOCfg_Type fifo_cfg; - WUPTCfg_Type wupt_cfg; - SEQInfo_Type seqinfo0, seqinfo1, seqinfo2, seqinfo3; - SeqGpioTrig_Cfg seqgpiotrig_cfg; - AD5940PlatformCfg(); - - /* Configure sequencer and stop it */ - seq_cfg.SeqMemSize = SEQMEMSIZE_2KB; /* 2kB SRAM is used for sequencer, others for data FIFO */ - seq_cfg.SeqBreakEn = bFALSE; - seq_cfg.SeqIgnoreEn = bTRUE; - seq_cfg.SeqCntCRCClr = bTRUE; - seq_cfg.SeqEnable = bTRUE; - seq_cfg.SeqWrTimer = 0; - AD5940_SEQCfg(&seq_cfg); - - /* Reconfigure FIFO */ - AD5940_FIFOCtrlS(FIFOSRC_DFT, bFALSE); /* Disable FIFO firstly */ - fifo_cfg.FIFOEn = bTRUE; - fifo_cfg.FIFOMode = FIFOMODE_FIFO; - fifo_cfg.FIFOSize = FIFOSIZE_4KB; /* 4kB for FIFO, The reset 2kB for sequencer */ - fifo_cfg.FIFOSrc = FIFOSRC_SINC3; - fifo_cfg.FIFOThresh = 4; - AD5940_FIFOCfg(&fifo_cfg); - AD5940_INTCClrFlag(AFEINTSRC_ALLINT); - - seqinfo0.pSeqCmd = Seq0Commands; - seqinfo0.SeqId = SEQID_0; - seqinfo0.SeqLen = SEQ_LEN(Seq0Commands); - seqinfo0.SeqRamAddr = SEQ0ADDR; - seqinfo0.WriteSRAM = bTRUE; - AD5940_SEQInfoCfg(&seqinfo0); /* Configure sequence0 info and write commands to SRAM */ - - seqinfo1.pSeqCmd = Seq1Commands; - seqinfo1.SeqId = SEQID_1; - seqinfo1.SeqLen = SEQ_LEN(Seq1Commands); - seqinfo1.SeqRamAddr = SEQ1ADDR; - seqinfo1.WriteSRAM = bTRUE; - AD5940_SEQInfoCfg(&seqinfo1); - - seqinfo2.pSeqCmd = Seq2Commands; - seqinfo2.SeqId = SEQID_2; - seqinfo2.SeqLen = SEQ_LEN(Seq2Commands); - seqinfo2.SeqRamAddr = SEQ2ADDR; - seqinfo2.WriteSRAM = bTRUE; - AD5940_SEQInfoCfg(&seqinfo2); - - seqinfo3.pSeqCmd = Seq3Commands; - seqinfo3.SeqId = SEQID_3; - seqinfo3.SeqLen = SEQ_LEN(Seq3Commands); - seqinfo3.SeqRamAddr = SEQ3ADDR; - seqinfo3.WriteSRAM = bTRUE; - AD5940_SEQInfoCfg(&seqinfo3); - - /* Configure wakeup timer */ - wupt_cfg.WuptEn = bFALSE; /* Don't start it right now. */ - wupt_cfg.WuptEndSeq = WUPTENDSEQ_C; /* A->B->C->A->B-C */ - wupt_cfg.WuptOrder[0] = SEQID_0; /* Put SEQ0 to slotA */ - wupt_cfg.WuptOrder[1] = SEQID_3; /* Put SEQ3 to slotB */ - wupt_cfg.WuptOrder[2] = SEQID_1; /* Put SEQ1 to slotC */ - /* There is no need to init slot DEFGH, that's WuptOrder[3] to WuptOrder[7], becaue we don't use it. EndofSeq is C.*/ - wupt_cfg.SeqxSleepTime[SEQID_0] = 10; - wupt_cfg.SeqxWakeupTime[SEQID_0] = (uint32_t)(32000.0f*500/1000.0f) - 10 - 2; /* 500ms after, wakeup and trigger seq0 */ - wupt_cfg.SeqxSleepTime[SEQID_3] = 10; - wupt_cfg.SeqxWakeupTime[SEQID_3] = (uint32_t)(32000.0f*1000/1000.0f)- 10 -2; /* 1000ms after, trigger seq2 */ - wupt_cfg.SeqxSleepTime[SEQID_1] = 10; - wupt_cfg.SeqxWakeupTime[SEQID_1] = (uint32_t)(32000.0f*2000/1000.0f)- 10 -2; /* 2000ms after, trigger seq2 */ - AD5940_WUPTCfg(&wupt_cfg); - - printf("Test0: trigger sequencer by wakeup timer.\n"); - AD5940_WUPTCtrl(bTRUE); /* Enable wakeup timer. */ - while(1) - { - if(AD5940_GetMCUIntFlag()) - { - AD5940_ClrMCUIntFlag(); - SeqISR(); - if(bSeqEnd) - break; - } - } - AD5940_WUPTCtrl(bFALSE); /* Wakeup timer is still running and triggering. Trigger is not accepted because sequencer - is disabled in last sequence(SEQ1) command. */ - AD5940_SEQCtrlS(bTRUE); /* Enable sequencer again, because we disabled it in seq3 last command. */ - - /* Test MMR trigger */ - printf("\nTest1: trigger sequence2 manually by register write.\n"); - AD5940_SEQMmrTrig(SEQID_2); /* Trigger sequence2 manually. */ - /* Wait until CUSTMINT2 is set. We generate this interrupt in SEQ2 */ - while(AD5940_INTCTestFlag(AFEINTC_1, AFEINTSRC_CUSTOMINT2) == bFALSE); /* Test INTC1, we enabled all interrupts in INTC1. */ - AD5940_INTCClrFlag(AFEINTSRC_CUSTOMINT2); - printf("sequence2 has been executed\n"); - printf("SWCON:0x%08x\n", AD5940_ReadReg(REG_AFE_SWCON)); - AD5940_INTCClrFlag(AFEINTSRC_ALLINT); - - /* Toggle GPIO to trigger sequencer2 */ - printf("\nTest2: trigger sequence2 manually by GPIO\n"); - printf("Please connect GP2 and GP1 together. We will set GP2 function to TRIG.\n" - "GP1 is set to GPIO function and is in output state. We use GP1 to toggle GP2.\n"); - AD5940_Delay10us(100*1000*2); - printf("Toggle GPIO now\n"); - - /* Allow GP2 falling edge to trigger sequence2 */ - seqgpiotrig_cfg.bEnable = bTRUE; - seqgpiotrig_cfg.PinSel = AGPIO_Pin2; - seqgpiotrig_cfg.SeqPinTrigMode = SEQPINTRIGMODE_FALLING; - AD5940_SEQGpioTrigCfg(&seqgpiotrig_cfg); - /* GP2 is connected to GP1 by user. - We generate falling edge on GP1(gpio, output) to control GP2(trigger, input). - */ - AD5940_AGPIOSet(AGPIO_Pin1); - AD5940_AGPIOClr(AGPIO_Pin1); - while(AD5940_INTCTestFlag(AFEINTC_1, AFEINTSRC_CUSTOMINT2) == bFALSE); /* Test INTC1, we enabled all interrupts in INTC1. */ - - printf("Trigger received and sequence2 has been executed\n\n"); - printf("Sequencer test done!\n"); - while(1); -} - -int32_t SeqISR(void) -{ - uint32_t IntFlag, temp; - - IntFlag = AD5940_INTCGetFlag(AFEINTC_0); - - if(IntFlag & AFEINTSRC_CUSTOMINT0) - { - AD5940_INTCClrFlag(AFEINTSRC_CUSTOMINT0); - printf("Custom INT0!\n"); - temp = AD5940_ReadReg(REG_AFE_SWCON); - printf("SWCON:0x%08x\n", temp); - } - if(IntFlag & AFEINTSRC_CUSTOMINT1) - { - AD5940_INTCClrFlag(AFEINTSRC_CUSTOMINT1); - printf("Custom INT1!\n"); - temp = AD5940_ReadReg(REG_AFE_SWCON); - printf("SWCON:0x%08x\n", temp); - } - if(IntFlag & AFEINTSRC_CUSTOMINT2) - { - AD5940_INTCClrFlag(AFEINTSRC_CUSTOMINT2); - printf("Custom INT2!\n"); - temp = AD5940_ReadReg(REG_AFE_SWCON); - printf("SWCON:0x%08x\n", temp); - } - if(IntFlag & AFEINTSRC_CUSTOMINT3) - { - AD5940_INTCClrFlag(AFEINTSRC_CUSTOMINT3); - printf("Custom INT3!\n"); - temp = AD5940_ReadReg(REG_AFE_SWCON); - printf("SWCON:0x%08x\n", temp); - } - if(IntFlag & AFEINTSRC_ENDSEQ) /* This interrupt is generated when Sequencer is disabled. */ - { - AD5940_INTCClrFlag(AFEINTSRC_ENDSEQ); - printf("End of Sequence\n"); - bSeqEnd = bTRUE; - } - return AD5940ERR_OK; -} - diff --git a/examples/sequencer/NUCLEOF411Port.c b/examples/sequencer/NUCLEOF411Port.c deleted file mode 100644 index c78dd97..0000000 --- a/examples/sequencer/NUCLEOF411Port.c +++ /dev/null @@ -1,190 +0,0 @@ -/** - * @file NUCLEOF411Port.c - * @brief ST NUCLEOF411 board port file. - * @version V0.2.0 - * @author ADI - * @date March 2019 - * @par Revision History: - * - * Copyright (c) 2017-2019 Analog Devices, Inc. All Rights Reserved. - * - * This software is proprietary to Analog Devices, Inc. and its licensors. - * By using this software you agree to the terms of the associated - * Analog Devices Software License Agreement. -**/ -#include "ad5940.h" -#include "stdio.h" -#include "stm32f4xx_hal.h" - -/* Definition for STM32 SPI clock resources */ -#define AD5940SPI SPI1 -#define AD5940_CLK_ENABLE() __HAL_RCC_SPI1_CLK_ENABLE() -#define AD5940_SCK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define AD5940_MISO_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define AD5940_MOSI_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define AD5940_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() -#define AD5940_RST_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() -#define AD5940_GP0INT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() - -#define AD5940SPI_FORCE_RESET() __HAL_RCC_SPI1_FORCE_RESET() -#define AD5940SPI_RELEASE_RESET() __HAL_RCC_SPI1_RELEASE_RESET() - -/* Definition for AD5940 Pins */ -#define AD5940_SCK_PIN GPIO_PIN_5 -#define AD5940_SCK_GPIO_PORT GPIOA -#define AD5940_SCK_AF GPIO_AF5_SPI1 -#define AD5940_MISO_PIN GPIO_PIN_6 -#define AD5940_MISO_GPIO_PORT GPIOA -#define AD5940_MISO_AF GPIO_AF5_SPI1 -#define AD5940_MOSI_PIN GPIO_PIN_7 -#define AD5940_MOSI_GPIO_PORT GPIOA -#define AD5940_MOSI_AF GPIO_AF5_SPI1 - -#define AD5940_CS_PIN GPIO_PIN_6 -#define AD5940_CS_GPIO_PORT GPIOB - -#define AD5940_RST_PIN GPIO_PIN_0 //A3 -#define AD5940_RST_GPIO_PORT GPIOB - -#define AD5940_GP0INT_PIN GPIO_PIN_10 //A3 -#define AD5940_GP0INT_GPIO_PORT GPIOA -#define AD5940_GP0INT_IRQn EXTI15_10_IRQn - -SPI_HandleTypeDef SpiHandle; - -#define SYSTICK_MAXCOUNT ((1L<<24)-1) /* we use Systick to complete function Delay10uS(). This value only applies to NUCLEOF411 board. */ -#define SYSTICK_CLKFREQ 100000000L /* Systick clock frequency in Hz. This only appies to NUCLEOF411 board */ -volatile static uint8_t ucInterrupted = 0; /* Flag to indicate interrupt occurred */ - -/** - @brief Using SPI to transmit N bytes and return the received bytes. This function targets to - provide a more efficent way to transmit/receive data. - @param pSendBuffer :{0 - 0xFFFFFFFF} - - Pointer to the data to be sent. - @param pRecvBuff :{0 - 0xFFFFFFFF} - - Pointer to the buffer used to store received data. - @param length :{0 - 0xFFFFFFFF} - - Data length in SendBuffer. - @return None. -**/ -void AD5940_ReadWriteNBytes(unsigned char *pSendBuffer,unsigned char *pRecvBuff,unsigned long length) -{ - HAL_SPI_TransmitReceive(&SpiHandle, pSendBuffer, pRecvBuff, length, (uint32_t)-1); -} - -void AD5940_CsClr(void) -{ - HAL_GPIO_WritePin(AD5940_CS_GPIO_PORT, AD5940_CS_PIN, GPIO_PIN_RESET); -} - -void AD5940_CsSet(void) -{ - HAL_GPIO_WritePin(AD5940_CS_GPIO_PORT, AD5940_CS_PIN, GPIO_PIN_SET); -} - -void AD5940_RstSet(void) -{ - HAL_GPIO_WritePin(AD5940_RST_GPIO_PORT, AD5940_RST_PIN, GPIO_PIN_SET); -} - -void AD5940_RstClr(void) -{ - HAL_GPIO_WritePin(AD5940_RST_GPIO_PORT, AD5940_RST_PIN, GPIO_PIN_RESET); -} - -void AD5940_Delay10us(uint32_t time) -{ - time/=100; - if(time == 0) time =1; - HAL_Delay(time); -} - -uint32_t AD5940_GetMCUIntFlag(void) -{ - return ucInterrupted; -} - -uint32_t AD5940_ClrMCUIntFlag(void) -{ - ucInterrupted = 0; - return 1; -} - -uint32_t AD5940_MCUResourceInit(void *pCfg) -{ - GPIO_InitTypeDef GPIO_InitStruct; - - /* Step1, initialize SPI peripheral and its GPIOs for CS/RST */ - AD5940_SCK_GPIO_CLK_ENABLE(); - AD5940_MISO_GPIO_CLK_ENABLE(); - AD5940_MOSI_GPIO_CLK_ENABLE(); - AD5940_CS_GPIO_CLK_ENABLE(); - AD5940_RST_GPIO_CLK_ENABLE(); - /* Enable SPI clock */ - AD5940_CLK_ENABLE(); - - GPIO_InitStruct.Pin = AD5940_SCK_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_PULLDOWN; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = AD5940_SCK_AF; - HAL_GPIO_Init(AD5940_SCK_GPIO_PORT, &GPIO_InitStruct); - - /* SPI MISO GPIO pin configuration */ - GPIO_InitStruct.Pin = AD5940_MISO_PIN; - GPIO_InitStruct.Alternate = AD5940_MISO_AF; - HAL_GPIO_Init(AD5940_MISO_GPIO_PORT, &GPIO_InitStruct); - - /* SPI MOSI GPIO pin configuration */ - GPIO_InitStruct.Pin = AD5940_MOSI_PIN; - GPIO_InitStruct.Alternate = AD5940_MOSI_AF; - HAL_GPIO_Init(AD5940_MOSI_GPIO_PORT, &GPIO_InitStruct); - /* SPI CS GPIO pin configuration */ - GPIO_InitStruct.Pin = AD5940_CS_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - HAL_GPIO_Init(AD5940_CS_GPIO_PORT, &GPIO_InitStruct); - - /* SPI RST GPIO pin configuration */ - GPIO_InitStruct.Pin = AD5940_RST_PIN; - HAL_GPIO_Init(AD5940_RST_GPIO_PORT, &GPIO_InitStruct); - - AD5940_CsSet(); - AD5940_RstSet(); - - /* Set the SPI parameters */ - SpiHandle.Instance = AD5940SPI; - SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; //SPI clock should be < AD5940_SystemClock - SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; - SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; - SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; - SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; - SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; - SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE; - SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - SpiHandle.Init.CRCPolynomial = 7; - SpiHandle.Init.NSS = SPI_NSS_SOFT; - SpiHandle.Init.Mode = SPI_MODE_MASTER; - HAL_SPI_Init(&SpiHandle); - - /* Step 2: Configure external interrupot line */ - AD5940_GP0INT_GPIO_CLK_ENABLE(); - GPIO_InitStruct.Pin = AD5940_GP0INT_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = 0; - HAL_GPIO_Init(AD5940_GP0INT_GPIO_PORT, &GPIO_InitStruct); - - /* Enable and set EXTI Line0 Interrupt to the lowest priority */ - HAL_NVIC_EnableIRQ(AD5940_GP0INT_IRQn); -// HAL_NVIC_SetPriority(AD5940_GP0INT_IRQn, 0, 0); - return 0; -} - -/* MCU related external line interrupt service routine */ -void EXTI15_10_IRQHandler() -{ - ucInterrupted = 1; - __HAL_GPIO_EXTI_CLEAR_IT(AD5940_GP0INT_PIN); -} - diff --git a/examples/sequencer/main.c b/examples/sequencer/main.c deleted file mode 100644 index 049abeb..0000000 --- a/examples/sequencer/main.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - -Copyright (c) 2017-2019 Analog Devices, Inc. All Rights Reserved. - -This software is proprietary to Analog Devices, Inc. and its licensors. -By using this software you agree to the terms of the associated -Analog Devices Software License Agreement. - -*/ - -#include "stdio.h" -#include "ADuCM3029.h" -#include "AD5940.h" - -/* Functions that used to initialize MCU platform */ -uint32_t MCUPlatformInit(void *pCfg); - -int main(void) -{ - void AD5940_Main(void); - MCUPlatformInit(0); - AD5940_MCUResourceInit(0); - printf("Hello AD5940-Build Time:%s\n",__TIME__); - AD5940_Main(); -} - -/* Below functions are used to initialize MCU Platform */ -uint32_t MCUPlatformInit(void *pCfg) -{ - int UrtCfg(int iBaud); - - /*Stop watch dog timer(ADuCM3029)*/ - pADI_WDT0->CTL = 0xC9; - /* Clock Configure */ - pADI_CLKG0_OSC->KEY = 0xCB14; // Select HFOSC as system clock. - pADI_CLKG0_OSC->CTL = // Int 32khz LFOSC selected in LFMUX - BITM_CLKG_OSC_CTL_HFOSCEN|BITM_CLKG_OSC_CTL_HFXTALEN; - - while((pADI_CLKG0_OSC->CTL&BITM_CLKG_OSC_CTL_HFXTALOK) == 0); - - pADI_CLKG0_OSC->KEY = 0xCB14; - pADI_CLKG0_CLK->CTL0 = 0x201; /* Select XTAL as system clock */ - pADI_CLKG0_CLK->CTL1 = 0; // ACLK,PCLK,HCLK divided by 1 - pADI_CLKG0_CLK->CTL5 = 0x00; // Enable clock to all peripherals - no clock gating - - UrtCfg(230400);/*Baud rate: 230400*/ - return 1; -} - -/** - @brief int UrtCfg(int iBaud, int iBits, int iFormat) - ==========Configure the UART. - @param iBaud :{B1200,B2200,B2400,B4800,B9600,B19200,B38400,B57600,B115200,B230400,B430800} \n - Set iBaud to the baudrate required: - Values usually: 1200, 2200 (for HART), 2400, 4800, 9600, - 19200, 38400, 57600, 115200, 230400, 430800, or type in baud-rate directly - @note - - Powers up UART if not powered up. - - Standard baudrates are accurate to better than 0.1% plus clock error.\n - - Non standard baudrates are accurate to better than 1% plus clock error. - @warning - If an external clock is used for the system the ullRtClk must be modified with \n - the speed of the clock used. -**/ - -int UrtCfg(int iBaud) -{ - int iBits = 3;//8bits, - int iFormat = 0;//, int iBits, int iFormat - int i1; - int iDiv; - int iRtC; - int iOSR; - int iPllMulValue; - unsigned long long ullRtClk = 16000000; // The root clock speed - - - /*Setup P0[11:10] as UART pins*/ - pADI_GPIO0->CFG = (1<<22)|(1<<20)|(pADI_GPIO0->CFG&(~((3<<22)|(3<<20)))); - - iDiv = (pADI_CLKG0_CLK->CTL1& BITM_CLKG_CLK_CTL1_PCLKDIVCNT); // Read UART clock as set by CLKCON1[10:8] - iDiv = iDiv>>8; - if (iDiv == 0) - iDiv = 1; - iRtC = (pADI_CLKG0_CLK->CTL0& BITM_CLKG_CLK_CTL0_CLKMUX); // Check what is the root clock - - switch (iRtC) - { - case 0: // HFOSC selected - ullRtClk = 26000000; - break; - - case 1: // HFXTAL selected - if ((pADI_CLKG0_CLK->CTL0 & 0x200)==0x200) // 26Mhz XTAL used - ullRtClk = 26000000; - else - ullRtClk = 16000000; // Assume 16MHz XTAL - break; - - case 2: // SPLL output - iPllMulValue = (pADI_CLKG0_CLK->CTL3 & // Check muliplication factor in PLL settings - BITM_CLKG_CLK_CTL3_SPLLNSEL); // bits[4:0]. Assume div value of 0xD in bits [14:11] - ullRtClk = (iPllMulValue *1000000); // Assume straight multiplication by pADI_CLKG0_CLK->CTL3[4:0] - break; - - case 3: - ullRtClk = 26000000; //External clock is assumed to be 26MhZ, if different - break; //clock speed is used, this should be changed - - default: - break; - } - // iOSR = (pADI_UART0->COMLCR2 & 0x3); - // iOSR = 2^(2+iOSR); - pADI_UART0->COMLCR2 = 0x3; - iOSR = 32; - //i1 = (ullRtClk/(iOSR*iDiv))/iBaud; // UART baud rate clock source is PCLK divided by OSR - i1 = (ullRtClk/(iOSR*iDiv))/iBaud-1; //for bigger M and N value - pADI_UART0->COMDIV = i1; - - pADI_UART0->COMFBR = 0x8800|(((((2048/(iOSR*iDiv))*ullRtClk)/i1)/iBaud)-2048); - pADI_UART0->COMIEN = 0; - pADI_UART0->COMLCR = (iFormat&0x3c)|(iBits&3); - - - pADI_UART0->COMFCR = (BITM_UART_COMFCR_RFTRIG & 0/*RX_FIFO_1BYTE*/ ) |BITM_UART_COMFCR_FIFOEN; - pADI_UART0->COMFCR |= BITM_UART_COMFCR_RFCLR|BITM_UART_COMFCR_TFCLR; // Clear the UART FIFOs - pADI_UART0->COMFCR &= ~(BITM_UART_COMFCR_RFCLR|BITM_UART_COMFCR_TFCLR); // Disable clearing mechanism - - NVIC_EnableIRQ(UART_EVT_IRQn); // Enable UART interrupt source in NVIC - pADI_UART0->COMIEN = BITM_UART_COMIEN_ERBFI|BITM_UART_COMIEN_ELSI; /* Rx Interrupt */ - return pADI_UART0->COMLSR; -} -#include "stdio.h" -#ifdef __ICCARM__ -int putchar(int c) -#else -int fputc(int c, FILE *f) -#endif -{ - pADI_UART0->COMTX = c; - while((pADI_UART0->COMLSR&0x20) == 0);// tx fifo empty - return c; -} diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 2e55c53..410385f 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -31,6 +31,9 @@ endif() # --- FFTW3 CONFIGURATION --- # ========================================== + +# --- FFTW3 Configuration (Double Precision) --- + if(WIN32) # Windows: Expects FFTW3 to be installed/found via Config find_package(FFTW3 CONFIG REQUIRED) @@ -51,6 +54,7 @@ elseif(APPLE AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" AND NOT BUILD_IOS) IMPORTED_LOCATION "${FFTW3_LIB}" INTERFACE_INCLUDE_DIRECTORIES "${FFTW3_INCLUDE_DIR}" ) + else() message(STATUS "Building FFTW3 from source (Double Precision)...") @@ -65,15 +69,17 @@ else() set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build Static Libs" FORCE) set(BUILD_TESTS OFF CACHE BOOL "Disable Tests" FORCE) - # Enable NEON for Android ARM64 / iOS + # Enhanced NEON detection for Windows on Arm as well if(ANDROID_ABI STREQUAL "arm64-v8a") message(STATUS "Enabling NEON for Android ARM64") set(ENABLE_NEON ON CACHE BOOL "Enable NEON" FORCE) elseif(BUILD_IOS) set(ENABLE_NEON ON CACHE BOOL "Enable NEON" FORCE) + elseif(MSVC AND CMAKE_SYSTEM_PROCESSOR MATCHES "(ARM64|arm64|aarch64)") + set(ENABLE_NEON ON CACHE BOOL "Enable NEON" FORCE) endif() - # Patch for older CMake versions inside the tarball if needed + # Only apply sed patch on UNIX-like systems if(UNIX) set(PATCH_CMD sed -i.bak "s/cmake_minimum_required.*/cmake_minimum_required(VERSION 3.16)/" /CMakeLists.txt) else() @@ -208,8 +214,10 @@ if(BUILD_ANDROID) target_link_libraries(EISConfigurator PRIVATE Qt6::Widgets Qt6::SerialPort Qt6::AndroidExtras) else() - add_executable(EISConfigurator ${PROJECT_SOURCES}) - target_link_libraries(EISConfigurator PRIVATE Qt6::Widgets Qt6::SerialPort) + target_link_libraries(EISConfigurator PRIVATE Qt6::Widgets Qt6::SerialPort Qt6::PrintSupport) + if(APPLE) + target_link_libraries(EISConfigurator PRIVATE ${FFTW_TARGET}) + endif() endif() @@ -253,5 +261,5 @@ elseif(WIN32) endif() -# CRITICAL: Triggers androiddeployqt to build the APK + qt_finalize_executable(EISConfigurator) \ No newline at end of file diff --git a/host/ios/Assets.xcassets/AppIcon.appiconset/Contents.json b/host/ios/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..e9b5a67 --- /dev/null +++ b/host/ios/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,27 @@ +{ + "images" : [ + { "size" : "20x20", "idiom" : "iphone", "filename" : "Icon-20@2x.png", "scale" : "2x" }, + { "size" : "20x20", "idiom" : "iphone", "filename" : "Icon-20@3x.png", "scale" : "3x" }, + { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-29.png", "scale" : "1x" }, + { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-29@2x.png", "scale" : "2x" }, + { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-29@3x.png", "scale" : "3x" }, + { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-40@2x.png", "scale" : "2x" }, + { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-40@3x.png", "scale" : "3x" }, + { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-60@2x.png", "scale" : "2x" }, + { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-60@3x.png", "scale" : "3x" }, + { "size" : "20x20", "idiom" : "ipad", "filename" : "Icon-20.png", "scale" : "1x" }, + { "size" : "20x20", "idiom" : "ipad", "filename" : "Icon-20@2x.png", "scale" : "2x" }, + { "size" : "29x29", "idiom" : "ipad", "filename" : "Icon-29.png", "scale" : "1x" }, + { "size" : "29x29", "idiom" : "ipad", "filename" : "Icon-29@2x.png", "scale" : "2x" }, + { "size" : "40x40", "idiom" : "ipad", "filename" : "Icon-40.png", "scale" : "1x" }, + { "size" : "40x40", "idiom" : "ipad", "filename" : "Icon-40@2x.png", "scale" : "2x" }, + { "size" : "76x76", "idiom" : "ipad", "filename" : "Icon-76.png", "scale" : "1x" }, + { "size" : "76x76", "idiom" : "ipad", "filename" : "Icon-76@2x.png", "scale" : "2x" }, + { "size" : "83.5x83.5", "idiom" : "ipad", "filename" : "Icon-83.5@2x.png", "scale" : "2x" }, + { "size" : "1024x1024", "idiom" : "ios-marketing", "filename" : "Icon-1024.png", "scale" : "1x" } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/host/ios/Assets.xcassets/Contents.json b/host/ios/Assets.xcassets/Contents.json new file mode 100644 index 0000000..2d92bd5 --- /dev/null +++ b/host/ios/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/host/scripts/generate_icons.bat b/host/scripts/generate_icons.bat new file mode 100644 index 0000000..7befa1c --- /dev/null +++ b/host/scripts/generate_icons.bat @@ -0,0 +1,52 @@ +@echo off +setlocal + +:: Arguments passed from CMake: +:: %1 = Path to magick.exe +:: %2 = Source Image +:: %3 = Destination Icon + +set "MAGICK_EXE=%~1" +set "SOURCE_IMG=%~2" +set "DEST_ICO=%~3" + +:: -- FOR MISSING DELEGATES / REGISTRY ERRORS --- +for %%I in ("%MAGICK_EXE%") do set "MAGICK_DIR=%%~dpI" +if "%MAGICK_DIR:~-1%"=="\" set "MAGICK_DIR=%MAGICK_DIR:~0,-1%" +set "MAGICK_HOME=%MAGICK_DIR%" +set "MAGICK_CONFIGURE_PATH=%MAGICK_DIR%" +set "MAGICK_CODER_MODULE_PATH=%MAGICK_DIR%\modules\coders" +:: --------------------------------------------------- + +:: 1. Validate Source +if not exist "%SOURCE_IMG%" ( + echo [ERROR] Icon source not found at: %SOURCE_IMG% + exit /b 1 +) + +:: 2. Ensure Destination Directory Exists +if not exist "%~dp3" mkdir "%~dp3" + +:: 3. Generate the .ico (Nearest Neighbor / Pixel Art Mode) +echo [ICONS] Generating Pixel-Perfect Windows Icon: %DEST_ICO% + +:: We use -sample (Nearest Neighbor) explicitly for each standard icon size. +:: We clone the original (index 0) for every resize to ensure maximum accuracy from the source. +"%MAGICK_EXE%" "%SOURCE_IMG%" ^ + -background none -alpha on ^ + ( -clone 0 -sample 256x256 ) ^ + ( -clone 0 -sample 128x128 ) ^ + ( -clone 0 -sample 64x64 ) ^ + ( -clone 0 -sample 48x48 ) ^ + ( -clone 0 -sample 32x32 ) ^ + ( -clone 0 -sample 16x16 ) ^ + -delete 0 ^ + "%DEST_ICO%" + +if %errorlevel% neq 0 ( + echo [ERROR] ImageMagick failed to generate icon. + exit /b %errorlevel% +) + +echo [SUCCESS] Icon generated. +exit /b 0 \ No newline at end of file diff --git a/host/scripts/generate_icons.sh b/host/scripts/generate_icons.sh index 31c3bc0..78c434f 100755 --- a/host/scripts/generate_icons.sh +++ b/host/scripts/generate_icons.sh @@ -1,21 +1,18 @@ -# host/scripts/generate_icons.sh - #!/bin/bash -# Resolve the directory where the script is located -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" -# Project Root is two levels up (host/scripts -> host -> root) -PROJECT_ROOT="$SCRIPT_DIR/../.." - +# Argument 1: Path to magick executable MAGICK_BIN="$1" -if [ -z "$MAGICK_BIN" ]; then MAGICK_BIN="magick"; fi -SOURCE="$PROJECT_ROOT/assets/icon_source.png" -OUT_DIR="$PROJECT_ROOT/assets/icons" -ANDROID_RES_DIR="$PROJECT_ROOT/host/android/res" +# Fallback if not provided +if [ -z "$MAGICK_BIN" ]; then + MAGICK_BIN="magick" +fi + +# Assumes running from Project Root +SOURCE="assets/icon_source.png" if [ ! -f "$SOURCE" ]; then - echo "Error: Source image '$SOURCE' not found." + echo "Error: Source image '$SOURCE' not found in $(pwd)" exit 1 fi @@ -26,56 +23,66 @@ if [ $? -ne 0 ]; then exit 1 fi -mkdir -p "$OUT_DIR" - -# macOS -ICONSET="$OUT_DIR/icon.iconset" +# --- macOS --- +# Keep macOS icons in assets/icons as they are linked explicitly +MACOS_OUT_DIR="assets/icons" +mkdir -p "$MACOS_OUT_DIR" +ICONSET="$MACOS_OUT_DIR/icon.iconset" mkdir -p "$ICONSET" -"$MAGICK_BIN" "$SOURCE" -scale 16x16 "$ICONSET/icon_16x16.png" -"$MAGICK_BIN" "$SOURCE" -scale 32x32 "$ICONSET/icon_16x16@2x.png" -"$MAGICK_BIN" "$SOURCE" -scale 32x32 "$ICONSET/icon_32x32.png" -"$MAGICK_BIN" "$SOURCE" -scale 64x64 "$ICONSET/icon_32x32@2x.png" -"$MAGICK_BIN" "$SOURCE" -scale 128x128 "$ICONSET/icon_128x128.png" -"$MAGICK_BIN" "$SOURCE" -scale 256x256 "$ICONSET/icon_128x128@2x.png" -"$MAGICK_BIN" "$SOURCE" -scale 256x256 "$ICONSET/icon_256x256.png" -"$MAGICK_BIN" "$SOURCE" -scale 512x512 "$ICONSET/icon_256x256@2x.png" -"$MAGICK_BIN" "$SOURCE" -scale 512x512 "$ICONSET/icon_512x512.png" -"$MAGICK_BIN" "$SOURCE" -scale 1024x1024 "$ICONSET/icon_512x512@2x.png" +echo "[ICONS] Generating macOS iconset (Pixel Perfect)..." +"$MAGICK_BIN" "$SOURCE" -sample 16x16 "$ICONSET/icon_16x16.png" +"$MAGICK_BIN" "$SOURCE" -sample 32x32 "$ICONSET/icon_16x16@2x.png" +"$MAGICK_BIN" "$SOURCE" -sample 32x32 "$ICONSET/icon_32x32.png" +"$MAGICK_BIN" "$SOURCE" -sample 64x64 "$ICONSET/icon_32x32@2x.png" +"$MAGICK_BIN" "$SOURCE" -sample 128x128 "$ICONSET/icon_128x128.png" +"$MAGICK_BIN" "$SOURCE" -sample 256x256 "$ICONSET/icon_128x128@2x.png" +"$MAGICK_BIN" "$SOURCE" -sample 256x256 "$ICONSET/icon_256x256.png" +"$MAGICK_BIN" "$SOURCE" -sample 512x512 "$ICONSET/icon_256x256@2x.png" +"$MAGICK_BIN" "$SOURCE" -sample 512x512 "$ICONSET/icon_512x512.png" +"$MAGICK_BIN" "$SOURCE" -sample 1024x1024 "$ICONSET/icon_512x512@2x.png" -iconutil -c icns "$ICONSET" -o "$OUT_DIR/app_icon.icns" +iconutil -c icns "$ICONSET" -o "$MACOS_OUT_DIR/app_icon.icns" rm -rf "$ICONSET" -# Windows +# --- Windows --- +echo "[ICONS] Generating Windows .ico (Pixel Perfect)..." +# Updated to match the high-quality logic from the Windows Batch file +# (Removed -alpha off and -colors 256 which would ruin transparency) "$MAGICK_BIN" "$SOURCE" \ - \( -clone 0 -scale 256x256 \) \ - \( -clone 0 -scale 128x128 \) \ - \( -clone 0 -scale 64x64 \) \ - \( -clone 0 -scale 48x48 \) \ - \( -clone 0 -scale 32x32 \) \ - \( -clone 0 -scale 16x16 \) \ - -delete 0 -alpha off -colors 256 "$OUT_DIR/app_icon.ico" + -background none -alpha on \ + \( -clone 0 -sample 256x256 \) \ + \( -clone 0 -sample 128x128 \) \ + \( -clone 0 -sample 64x64 \) \ + \( -clone 0 -sample 48x48 \) \ + \( -clone 0 -sample 32x32 \) \ + \( -clone 0 -sample 16x16 \) \ + -delete 0 "$MACOS_OUT_DIR/app_icon.ico" -# Android -echo "Generating Android Icons into $ANDROID_RES_DIR..." +# --- Android --- +# Output directly to android/res so QT_ANDROID_PACKAGE_SOURCE_DIR picks it up +echo "[ICONS] Generating Android mipmaps (Pixel Perfect)..." +ANDROID_DIR="android/res" -mkdir -p "$ANDROID_RES_DIR/mipmap-mdpi" -"$MAGICK_BIN" "$SOURCE" -scale 48x48 "$ANDROID_RES_DIR/mipmap-mdpi/ic_launcher.png" +mkdir -p "$ANDROID_DIR/mipmap-mdpi" +"$MAGICK_BIN" "$SOURCE" -sample 48x48 "$ANDROID_DIR/mipmap-mdpi/ic_launcher.png" -mkdir -p "$ANDROID_RES_DIR/mipmap-hdpi" -"$MAGICK_BIN" "$SOURCE" -scale 72x72 "$ANDROID_RES_DIR/mipmap-hdpi/ic_launcher.png" +mkdir -p "$ANDROID_DIR/mipmap-hdpi" +"$MAGICK_BIN" "$SOURCE" -sample 72x72 "$ANDROID_DIR/mipmap-hdpi/ic_launcher.png" -mkdir -p "$ANDROID_RES_DIR/mipmap-xhdpi" -"$MAGICK_BIN" "$SOURCE" -scale 96x96 "$ANDROID_RES_DIR/mipmap-xhdpi/ic_launcher.png" +mkdir -p "$ANDROID_DIR/mipmap-xhdpi" +"$MAGICK_BIN" "$SOURCE" -sample 96x96 "$ANDROID_DIR/mipmap-xhdpi/ic_launcher.png" -mkdir -p "$ANDROID_RES_DIR/mipmap-xxhdpi" -"$MAGICK_BIN" "$SOURCE" -scale 144x144 "$ANDROID_RES_DIR/mipmap-xxhdpi/ic_launcher.png" +mkdir -p "$ANDROID_DIR/mipmap-xxhdpi" +"$MAGICK_BIN" "$SOURCE" -sample 144x144 "$ANDROID_DIR/mipmap-xxhdpi/ic_launcher.png" -mkdir -p "$ANDROID_RES_DIR/mipmap-xxxhdpi" -"$MAGICK_BIN" "$SOURCE" -scale 192x192 "$ANDROID_RES_DIR/mipmap-xxxhdpi/ic_launcher.png" +mkdir -p "$ANDROID_DIR/mipmap-xxxhdpi" +"$MAGICK_BIN" "$SOURCE" -sample 192x192 "$ANDROID_DIR/mipmap-xxxhdpi/ic_launcher.png" -# iOS -XCASSETS_DIR="$OUT_DIR/ios/Assets.xcassets" +# --- iOS --- +# Output directly to ios/Assets.xcassets +echo "[ICONS] Generating iOS AppIcon (Pixel Perfect)..." +XCASSETS_DIR="ios/Assets.xcassets" IOS_DIR="$XCASSETS_DIR/AppIcon.appiconset" mkdir -p "$IOS_DIR" @@ -88,21 +95,21 @@ cat > "$XCASSETS_DIR/Contents.json" < "$IOS_DIR/Contents.json" < "$IOS_DIR/Contents.json" < +#include "string.h" +#include "math.h" +#include "Impedance.h" + +/* Default LPDAC resolution (2.5V internal reference) */ +#define DAC12BITVOLT_1LSB (2200.0f/4095) // mV +#define DAC6BITVOLT_1LSB (DAC12BITVOLT_1LSB*64) // mV + +/* Forward declaration */ +AD5940Err AppIMPCheckFreq(float freq); + +AppIMPCfg_Type AppIMPCfg = +{ + .bParaChanged = bFALSE, + .SeqStartAddr = 0, + .MaxSeqLen = 0, + + .SeqStartAddrCal = 0, + .MaxSeqLenCal = 0, + + .ImpODR = 20.0, /* Output Data Rate: 20.0 Hz */ + .NumOfData = 101, /* Default to 101 points (matches default sweep) */ + .RealDataCount = -1, + .SysClkFreq = 16000000.0, + .WuptClkFreq = 32000.0, /* Low Frequency Oscillator (LFO) typically 32kHz */ + .AdcClkFreq = 16000000.0, + .RcalVal = 100.0, /* Calibration Resistor Value (Ohms) */ + .RtiaVal = 200.0, /* TIA Gain Resistor Value (Ohms) */ + + .DswitchSel = SWD_CE0, + .PswitchSel = SWP_CE0, + .NswitchSel = SWN_SE0, + .TswitchSel = SWT_TRTIA, + + .PwrMod = AFEPWR_HP, + + .HstiaRtiaSel = HSTIARTIA_200, + .ExtRtia = 0, + .ExcitBufGain = EXCITBUFGAIN_0P25, + .HsDacGain = HSDACGAIN_0P2, + .HsDacUpdateRate = 7, + .DacVoltPP = 600.0, /* Excitation Amplitude (mV peak-to-peak) */ + .BiasVolt = -0.0f, /* DC Bias Voltage */ + + .SinFreq = 1000.0, /* Fixed Frequency (Hz) */ + + .DftNum = DFTNUM_16384, /* DFT Point Count */ + .DftSrc = DFTSRC_SINC3, + .HanWinEn = bTRUE, /* Hanning Window for spectral leakage reduction */ + + .AdcPgaGain = ADCPGA_1P5, + .ADCSinc3Osr = ADCSINC3OSR_2, + .ADCSinc2Osr = ADCSINC2OSR_22, + + .ADCAvgNum = ADCAVGNUM_16, + + /* Default Sweep: 1kHz to 100kHz, 50 Points Per Decade (Log) */ + /* Decades = log10(100k) - log10(1k) = 2. Points = 2 * 50 + 1 = 101 */ + .SweepCfg.SweepEn = bTRUE, + .SweepCfg.SweepStart = 1000.0, + .SweepCfg.SweepStop = 100000.0, + .SweepCfg.SweepPoints = 101, + .SweepCfg.SweepLog = bTRUE, + .SweepCfg.SweepIndex = 0, + + .FifoThresh = 6, /* Threshold: 3 measurements * 2 (Real/Imag) = 6 words */ + .IMPInited = bFALSE, + .StopRequired = bFALSE, +}; + +/* ----------------------------------------------------------------------- */ +/* Helper Functions */ +/* ----------------------------------------------------------------------- */ + +/** + * @brief Configures the Impedance Sweep parameters. + * @param start Start Frequency in Hz + * @param stop Stop Frequency in Hz + * @param ppd Points Per Decade (Resolution) + */ +void AppIMPConfigureSweep(float start, float stop, float ppd) { + if (start <= 0 || stop <= 0 || ppd <= 0) return; + + AppIMPCfg.SweepCfg.SweepEn = bTRUE; + AppIMPCfg.SweepCfg.SweepStart = start; + AppIMPCfg.SweepCfg.SweepStop = stop; + AppIMPCfg.SweepCfg.SweepLog = bTRUE; + + // Calculate total points based on decades and PPD + // Formula: Points = (Decades * PPD) + 1 + float decades = log10f(stop) - log10f(start); + if (decades < 0) decades = -decades; // Handle sweep down if needed + + uint32_t points = (uint32_t)(decades * ppd) + 1; + AppIMPCfg.SweepCfg.SweepPoints = points; + + // Set NumOfData to stop the sequencer automatically after the sweep + AppIMPCfg.NumOfData = points; + + // Reset Sweep State + AppIMPCfg.FifoDataCount = 0; + AppIMPCfg.SweepCfg.SweepIndex = 0; + AppIMPCfg.SweepCurrFreq = start; + AppIMPCfg.SweepNextFreq = start; +} + +void AppIMPCleanup(void) { + // Ensure chip is awake before sending commands + if(AD5940_WakeUp(10) > 10) return; + + // Stop Sequencer and Wakeup Timer + AD5940_WUPTCtrl(bFALSE); + AD5940_SEQCtrlS(bFALSE); + + // Stop active conversions and Waveform Generator, keep Reference/LDOs on + AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT|AFECTRL_WG, bFALSE); + + // Reset FIFO configuration + FIFOCfg_Type fifo_cfg; + fifo_cfg.FIFOEn = bFALSE; + AD5940_FIFOCfg(&fifo_cfg); + + fifo_cfg.FIFOEn = bTRUE; + fifo_cfg.FIFOMode = FIFOMODE_FIFO; + fifo_cfg.FIFOSize = FIFOSIZE_4KB; + fifo_cfg.FIFOSrc = FIFOSRC_DFT; + fifo_cfg.FIFOThresh = 6; + AD5940_FIFOCfg(&fifo_cfg); + + // Clear all interrupt flags + AD5940_INTCClrFlag(AFEINTSRC_ALLINT); +} + +void AppIMPCalibrateLFO(void) { + LFOSCMeasure_Type cal_cfg; + cal_cfg.CalDuration = 1000.0; // 1000ms for high accuracy + cal_cfg.CalSeqAddr = 0; // Use start of SRAM for calibration sequence + cal_cfg.SystemClkFreq = 16000000.0; + + float freq; + // Measure LFOSC frequency to calibrate Wakeup Timer + if(AD5940_LFOSCMeasure(&cal_cfg, &freq) == AD5940ERR_OK) { + AppIMPCfg.WuptClkFreq = freq; + } +} + +/* ----------------------------------------------------------------------- */ + +int32_t AppIMPGetCfg(void *pCfg) +{ + if(pCfg) + { + *(AppIMPCfg_Type**)pCfg = &AppIMPCfg; + return AD5940ERR_OK; + } + return AD5940ERR_PARA; +} + +int32_t AppIMPCtrl(uint32_t Command, void *pPara) +{ + switch (Command) + { + case IMPCTRL_START: + { + // Configure interrupts and trigger the first sequence manually + AD5940_WUPTCtrl(bFALSE); + + AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ENDSEQ, bTRUE); + AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_DATAFIFOTHRESH, bFALSE); + AD5940_INTCClrFlag(AFEINTSRC_ALLINT); + + AppIMPCfg.FifoDataCount = 0; + AppIMPCfg.StopRequired = bFALSE; + + // 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); + break; + } + case IMPCTRL_STOPNOW: + { + if(AD5940_WakeUp(10) > 10) return AD5940ERR_WAKEUP; + AD5940_WUPTCtrl(bFALSE); + AD5940_SEQCtrlS(bFALSE); + break; + } + case IMPCTRL_STOPSYNC: + { + AppIMPCfg.StopRequired = bTRUE; + break; + } + case IMPCTRL_GETFREQ: + { + if(pPara == 0) return AD5940ERR_PARA; + if(AppIMPCfg.SweepCfg.SweepEn == bTRUE) + *(float*)pPara = AppIMPCfg.FreqofData; + else + *(float*)pPara = AppIMPCfg.SinFreq; + break; + } + case IMPCTRL_SHUTDOWN: + { + AppIMPCtrl(IMPCTRL_STOPNOW, 0); + AFERefCfg_Type aferef_cfg; + LPLoopCfg_Type lp_loop; + memset(&aferef_cfg, 0, sizeof(aferef_cfg)); + AD5940_REFCfgS(&aferef_cfg); + memset(&lp_loop, 0, sizeof(lp_loop)); + AD5940_LPLoopCfgS(&lp_loop); + AD5940_EnterSleepS(); + break; + } + default: + break; + } + return AD5940ERR_OK; +} + +float AppIMPGetCurrFreq(void) +{ + if(AppIMPCfg.SweepCfg.SweepEn == bTRUE) + return AppIMPCfg.FreqofData; + else + return AppIMPCfg.SinFreq; +} + +/* Generate Initialization Sequence */ +static AD5940Err AppIMPSeqCfgGen(void) +{ + AD5940Err error = AD5940ERR_OK; + const uint32_t *pSeqCmd; + uint32_t SeqLen; + AFERefCfg_Type aferef_cfg; + HSLoopCfg_Type HsLoopCfg; + DSPCfg_Type dsp_cfg; + float sin_freq; + + AD5940_SEQGenCtrl(bTRUE); + AD5940_AFECtrlS(AFECTRL_ALL, bFALSE); + + // Configure Reference System (High Power and Low Power Buffers) + 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); + + // Configure High Speed Loop (DAC and TIA) + HsLoopCfg.HsDacCfg.ExcitBufGain = AppIMPCfg.ExcitBufGain; + HsLoopCfg.HsDacCfg.HsDacGain = AppIMPCfg.HsDacGain; + HsLoopCfg.HsDacCfg.HsDacUpdateRate = AppIMPCfg.HsDacUpdateRate; + + HsLoopCfg.HsTiaCfg.DiodeClose = bFALSE; + HsLoopCfg.HsTiaCfg.HstiaBias = HSTIABIAS_1P1; + HsLoopCfg.HsTiaCfg.HstiaCtia = 31; + HsLoopCfg.HsTiaCfg.HstiaDeRload = HSTIADERLOAD_OPEN; + HsLoopCfg.HsTiaCfg.HstiaDeRtia = HSTIADERTIA_OPEN; + HsLoopCfg.HsTiaCfg.HstiaRtiaSel = AppIMPCfg.HstiaRtiaSel; + HsLoopCfg.HsTiaCfg.ExtRtia = AppIMPCfg.ExtRtia; + + // Configure Switch Matrix + HsLoopCfg.SWMatCfg.Dswitch = AppIMPCfg.DswitchSel; + HsLoopCfg.SWMatCfg.Pswitch = AppIMPCfg.PswitchSel; + HsLoopCfg.SWMatCfg.Nswitch = AppIMPCfg.NswitchSel; + HsLoopCfg.SWMatCfg.Tswitch = SWT_TRTIA|AppIMPCfg.TswitchSel; + + // Configure Waveform Generator (Sine Wave) + HsLoopCfg.WgCfg.WgType = WGTYPE_SIN; + HsLoopCfg.WgCfg.GainCalEn = bTRUE; + HsLoopCfg.WgCfg.OffsetCalEn = bTRUE; + + if(AppIMPCfg.SweepCfg.SweepEn == bTRUE) + { + AppIMPCfg.FreqofData = AppIMPCfg.SweepCfg.SweepStart; + AppIMPCfg.SweepCurrFreq = AppIMPCfg.SweepCfg.SweepStart; + AD5940_SweepNext(&AppIMPCfg.SweepCfg, &AppIMPCfg.SweepNextFreq); + sin_freq = AppIMPCfg.SweepCurrFreq; + } + else + { + sin_freq = AppIMPCfg.SinFreq; + AppIMPCfg.FreqofData = sin_freq; + } + + HsLoopCfg.WgCfg.SinCfg.SinFreqWord = AD5940_WGFreqWordCal(sin_freq, AppIMPCfg.SysClkFreq); + HsLoopCfg.WgCfg.SinCfg.SinAmplitudeWord = (uint32_t)(AppIMPCfg.DacVoltPP/800.0f*2047 + 0.5f); + HsLoopCfg.WgCfg.SinCfg.SinOffsetWord = 0; + HsLoopCfg.WgCfg.SinCfg.SinPhaseWord = 0; + AD5940_HSLoopCfgS(&HsLoopCfg); + + // Configure DSP and ADC + dsp_cfg.ADCBaseCfg.ADCMuxN = ADCMUXN_HSTIA_N; + dsp_cfg.ADCBaseCfg.ADCMuxP = ADCMUXP_HSTIA_P; + dsp_cfg.ADCBaseCfg.ADCPga = AppIMPCfg.AdcPgaGain; + + memset(&dsp_cfg.ADCDigCompCfg, 0, sizeof(dsp_cfg.ADCDigCompCfg)); + + dsp_cfg.ADCFilterCfg.ADCAvgNum = AppIMPCfg.ADCAvgNum; + dsp_cfg.ADCFilterCfg.ADCRate = ADCRATE_800KHZ; + dsp_cfg.ADCFilterCfg.ADCSinc2Osr = AppIMPCfg.ADCSinc2Osr; + dsp_cfg.ADCFilterCfg.ADCSinc3Osr = AppIMPCfg.ADCSinc3Osr; + dsp_cfg.ADCFilterCfg.BpNotch = bTRUE; + dsp_cfg.ADCFilterCfg.BpSinc3 = bFALSE; + dsp_cfg.ADCFilterCfg.Sinc2NotchEnable = bTRUE; + dsp_cfg.DftCfg.DftNum = AppIMPCfg.DftNum; + dsp_cfg.DftCfg.DftSrc = AppIMPCfg.DftSrc; + dsp_cfg.DftCfg.HanWinEn = AppIMPCfg.HanWinEn; + + memset(&dsp_cfg.StatCfg, 0, sizeof(dsp_cfg.StatCfg)); + AD5940_DSPCfgS(&dsp_cfg); + + // Enable Power for AFE blocks + AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\ + AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\ + AFECTRL_SINC2NOTCH, bTRUE); + + AD5940_SEQGenInsert(SEQ_STOP()); + + error = AD5940_SEQGenFetchSeq(&pSeqCmd, &SeqLen); + AD5940_SEQGenCtrl(bFALSE); + if(error == AD5940ERR_OK) + { + AppIMPCfg.InitSeqInfo.SeqId = SEQID_1; + AppIMPCfg.InitSeqInfo.SeqRamAddr = AppIMPCfg.SeqStartAddr; + AppIMPCfg.InitSeqInfo.pSeqCmd = pSeqCmd; + AppIMPCfg.InitSeqInfo.SeqLen = SeqLen; + AD5940_SEQCmdWrite(AppIMPCfg.InitSeqInfo.SeqRamAddr, pSeqCmd, SeqLen); + } + else + return error; + return AD5940ERR_OK; +} + +/* Generate Measurement Sequence */ +static AD5940Err AppIMPSeqMeasureGen(void) +{ + AD5940Err error = AD5940ERR_OK; + const uint32_t *pSeqCmd; + uint32_t SeqLen; + uint32_t WaitClks; + SWMatrixCfg_Type sw_cfg; + ClksCalInfo_Type clks_cal; + + // Calculate settling time (WaitClks) based on DFT/Filter settings + clks_cal.DataType = DATATYPE_DFT; + clks_cal.DftSrc = AppIMPCfg.DftSrc; + clks_cal.DataCount = 1L<<(AppIMPCfg.DftNum+2); + clks_cal.ADCSinc2Osr = AppIMPCfg.ADCSinc2Osr; + clks_cal.ADCSinc3Osr = AppIMPCfg.ADCSinc3Osr; + clks_cal.ADCAvgNum = AppIMPCfg.ADCAvgNum; + clks_cal.RatioSys2AdcClk = AppIMPCfg.SysClkFreq/AppIMPCfg.AdcClkFreq; + AD5940_ClksCalculate(&clks_cal, &WaitClks); + + AD5940_SEQGenCtrl(bTRUE); + AD5940_SEQGpioCtrlS(AGPIO_Pin2); + AD5940_SEQGenInsert(SEQ_WAIT(16*250)); + + /* ----------------------------------------------------------------------- */ + /* Step 1: Measure Current across RCAL (Calibration) */ + /* ----------------------------------------------------------------------- */ + sw_cfg.Dswitch = SWD_RCAL0; + sw_cfg.Pswitch = SWP_RCAL0; + sw_cfg.Nswitch = SWN_RCAL1; + sw_cfg.Tswitch = SWT_RCAL1|SWT_TRTIA; + AD5940_SWMatrixCfgS(&sw_cfg); + + // ADC Mux for Current (HSTIA) + AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N); + + // Enable AFE Power and Waveform Generator + AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\ + AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\ + AFECTRL_SINC2NOTCH, bTRUE); + AD5940_AFECtrlS(AFECTRL_WG|AFECTRL_ADCPWR, bTRUE); + AD5940_SEQGenInsert(SEQ_WAIT(16*2000)); + AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE); + + // Store address to update wait times later during sweep + AD5940_SEQGenFetchSeq(NULL, &AppIMPCfg.SeqWaitAddr[0]); + 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_SEQGenInsert(SEQ_WAIT(16*10)); + AD5940_AFECtrlS(AFECTRL_WG, bFALSE); + + /* ----------------------------------------------------------------------- */ + /* Step 2: Measure Sensor Current (I) */ + /* ----------------------------------------------------------------------- */ + sw_cfg.Dswitch = AppIMPCfg.DswitchSel; + sw_cfg.Pswitch = AppIMPCfg.PswitchSel; + sw_cfg.Nswitch = AppIMPCfg.NswitchSel; + sw_cfg.Tswitch = SWT_TRTIA|AppIMPCfg.TswitchSel; + AD5940_SWMatrixCfgS(&sw_cfg); + + // ADC Mux for Current (HSTIA) + AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N); + + AD5940_AFECtrlS(AFECTRL_ADCPWR|AFECTRL_WG, bTRUE); + AD5940_SEQGenInsert(SEQ_WAIT(16*2000)); + AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE); + + AD5940_SEQGenFetchSeq(NULL, &AppIMPCfg.SeqWaitAddr[1]); + AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); + AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); + + AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bFALSE); + AD5940_SEQGenInsert(SEQ_WAIT(16*10)); + AD5940_AFECtrlS(AFECTRL_WG, bFALSE); + + /* ----------------------------------------------------------------------- */ + /* Step 3: Measure Sensor Voltage (V) */ + /* ----------------------------------------------------------------------- */ + // Switches remain same (Force path active) + + // ADC Mux for Voltage (AIN2/AIN3) + AD5940_ADCMuxCfgS(ADCMUXP_AIN2, ADCMUXN_AIN3); + + AD5940_AFECtrlS(AFECTRL_ADCPWR|AFECTRL_WG, bTRUE); + AD5940_SEQGenInsert(SEQ_WAIT(16*2000)); + AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE); + + AD5940_SEQGenFetchSeq(NULL, &AppIMPCfg.SeqWaitAddr[2]); + AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); + AD5940_SEQGenInsert(SEQ_WAIT(WaitClks/2)); + + // Stop ADC/DFT, wait 10us, then stop WG and ADC Power + AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bFALSE); + AD5940_SEQGenInsert(SEQ_WAIT(16*10)); + AD5940_AFECtrlS(AFECTRL_WG|AFECTRL_ADCPWR, bFALSE); + + // Power down AFE blocks + AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\ + AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\ + AFECTRL_SINC2NOTCH, bFALSE); + AD5940_SEQGpioCtrlS(0); + + AD5940_SEQGenInsert(SEQ_STOP()); + + error = AD5940_SEQGenFetchSeq(&pSeqCmd, &SeqLen); + AD5940_SEQGenCtrl(bFALSE); + + if(error == AD5940ERR_OK) + { + AppIMPCfg.MeasureSeqInfo.SeqId = SEQID_0; + AppIMPCfg.MeasureSeqInfo.SeqRamAddr = AppIMPCfg.InitSeqInfo.SeqRamAddr + AppIMPCfg.InitSeqInfo.SeqLen ; + AppIMPCfg.MeasureSeqInfo.pSeqCmd = pSeqCmd; + AppIMPCfg.MeasureSeqInfo.SeqLen = SeqLen; + AD5940_SEQCmdWrite(AppIMPCfg.MeasureSeqInfo.SeqRamAddr, pSeqCmd, SeqLen); + } + else + return error; + return AD5940ERR_OK; +} + +AD5940Err AppIMPCheckFreq(float freq) +{ + ADCFilterCfg_Type filter_cfg; + DFTCfg_Type dft_cfg; + uint32_t WaitClks; + ClksCalInfo_Type clks_cal; + FreqParams_Type freq_params; + uint32_t SeqCmdBuff[32]; + uint32_t SRAMAddr = 0; + + freq_params = AD5940_GetFreqParameters(freq); + + // Update ADC Filter and DFT settings based on frequency + filter_cfg.ADCAvgNum = ADCAVGNUM_16; + filter_cfg.ADCSinc2Osr = freq_params.ADCSinc2Osr; + filter_cfg.ADCSinc3Osr = freq_params.ADCSinc3Osr; + filter_cfg.BpSinc3 = bFALSE; + filter_cfg.BpNotch = bTRUE; + filter_cfg.Sinc2NotchEnable = bTRUE; + filter_cfg.ADCRate = ADCRATE_800KHZ; // Fixed ADC Rate for stability + + dft_cfg.DftNum = freq_params.DftNum; + dft_cfg.DftSrc = freq_params.DftSrc; + dft_cfg.HanWinEn = AppIMPCfg.HanWinEn; + + AD5940_ADCFilterCfgS(&filter_cfg); + AD5940_DFTCfgS(&dft_cfg); + + // Recalculate settling times (WaitClks) for the new frequency + clks_cal.DataType = DATATYPE_DFT; + clks_cal.DftSrc = freq_params.DftSrc; + clks_cal.DataCount = 1L<<(freq_params.DftNum+2); + clks_cal.ADCSinc2Osr = freq_params.ADCSinc2Osr; + clks_cal.ADCSinc3Osr = freq_params.ADCSinc3Osr; + clks_cal.ADCAvgNum = 0; + clks_cal.RatioSys2AdcClk = AppIMPCfg.SysClkFreq/AppIMPCfg.AdcClkFreq; + AD5940_ClksCalculate(&clks_cal, &WaitClks); + + // Add safety margin + WaitClks += 200; + + // Update Wait Times in SRAM for all 3 measurements + for (int i = 0; i < 3; i++) { + if (AppIMPCfg.SeqWaitAddr[i] == 0) continue; + + SRAMAddr = AppIMPCfg.MeasureSeqInfo.SeqRamAddr + AppIMPCfg.SeqWaitAddr[i]; + + // Split wait time into two commands to handle large values + uint32_t finalWait = WaitClks/2; + + SeqCmdBuff[0] = SEQ_WAIT(finalWait); + SeqCmdBuff[1] = SEQ_WAIT(finalWait); + AD5940_SEQCmdWrite(SRAMAddr, SeqCmdBuff, 2); + } + + return AD5940ERR_OK; +} + +int32_t AppIMPInit(uint32_t *pBuffer, uint32_t BufferSize) +{ + AD5940Err error = AD5940ERR_OK; + SEQCfg_Type seq_cfg; + FIFOCfg_Type fifo_cfg; + + if(AD5940_WakeUp(10) > 10) return AD5940ERR_WAKEUP; + + // Stop timers and sequencer before reconfiguration + AD5940_WUPTCtrl(bFALSE); + AD5940_SEQCtrlS(bFALSE); + + seq_cfg.SeqMemSize = SEQMEMSIZE_2KB; + seq_cfg.SeqBreakEn = bFALSE; + seq_cfg.SeqIgnoreEn = bTRUE; + seq_cfg.SeqCntCRCClr = bTRUE; + seq_cfg.SeqEnable = bFALSE; + seq_cfg.SeqWrTimer = 0; + AD5940_SEQCfg(&seq_cfg); + + AD5940_FIFOCtrlS(FIFOSRC_DFT, bFALSE); + fifo_cfg.FIFOEn = bTRUE; + fifo_cfg.FIFOMode = FIFOMODE_FIFO; + fifo_cfg.FIFOSize = FIFOSIZE_4KB; + fifo_cfg.FIFOSrc = FIFOSRC_DFT; + fifo_cfg.FIFOThresh = AppIMPCfg.FifoThresh; + AD5940_FIFOCfg(&fifo_cfg); + AD5940_INTCClrFlag(AFEINTSRC_ALLINT); + + if((AppIMPCfg.IMPInited == bFALSE)||(AppIMPCfg.bParaChanged == bTRUE)) + { + if(pBuffer == 0) return AD5940ERR_PARA; + if(BufferSize == 0) return AD5940ERR_PARA; + AD5940_SEQGenInit(pBuffer, BufferSize); + + error = AppIMPSeqCfgGen(); + if(error != AD5940ERR_OK) return error; + + error = AppIMPSeqMeasureGen(); + if(error != AD5940ERR_OK) return error; + + AppIMPCfg.bParaChanged = bFALSE; + } + + AppIMPCfg.InitSeqInfo.WriteSRAM = bFALSE; + AD5940_SEQInfoCfg(&AppIMPCfg.InitSeqInfo); + seq_cfg.SeqEnable = bTRUE; + AD5940_SEQCfg(&seq_cfg); + AD5940_SEQMmrTrig(AppIMPCfg.InitSeqInfo.SeqId); + + AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ENDSEQ, bTRUE); + + // Wait for initialization sequence to complete + int timeout = 100000; + while(AD5940_INTCTestFlag(AFEINTC_1, AFEINTSRC_ENDSEQ) == bFALSE) { + if(--timeout <= 0) { + return AD5940ERR_TIMEOUT; + } + } + AD5940_INTCClrFlag(AFEINTSRC_ALLINT); + + AppIMPCfg.MeasureSeqInfo.WriteSRAM = bFALSE; + AD5940_SEQInfoCfg(&AppIMPCfg.MeasureSeqInfo); + + // Set initial frequency parameters + AppIMPCheckFreq(AppIMPCfg.FreqofData); + + seq_cfg.SeqEnable = bTRUE; + AD5940_SEQCfg(&seq_cfg); + AD5940_ClrMCUIntFlag(); + + AppIMPCfg.IMPInited = bTRUE; + return AD5940ERR_OK; +} + +int32_t AppIMPRegModify(int32_t * const pData, uint32_t *pDataCount) +{ + if(AppIMPCfg.NumOfData > 0) + { + AppIMPCfg.FifoDataCount += *pDataCount/6; + if(AppIMPCfg.FifoDataCount >= AppIMPCfg.NumOfData) + { + AD5940_WUPTCtrl(bFALSE); + AD5940_SEQCtrlS(bFALSE); + return AD5940ERR_OK; + } + } + if(AppIMPCfg.StopRequired == bTRUE) + { + AD5940_WUPTCtrl(bFALSE); + return AD5940ERR_OK; + } + if(AppIMPCfg.SweepCfg.SweepEn) + { + // Update Filters and Wait Times in SRAM + AppIMPCheckFreq(AppIMPCfg.SweepNextFreq); + + // Update WG Frequency + AD5940_WGFreqCtrlS(AppIMPCfg.SweepNextFreq, AppIMPCfg.SysClkFreq); + } + return AD5940ERR_OK; +} + +int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount) +{ + uint32_t DataCount = *pDataCount; + uint32_t ImpResCount = DataCount/6; + + fImpPol_Type * const pOut = (fImpPol_Type*)pData; + iImpCar_Type * pSrcData = (iImpCar_Type*)pData; + + *pDataCount = 0; + + for(uint32_t i=0; iReal*pDftI->Real + (float)pDftI->Image*pDftI->Image); + PhaseI = atan2(-pDftI->Image, pDftI->Real); + + MagV = sqrt((float)pDftV->Real*pDftV->Real + (float)pDftV->Image*pDftV->Image); + PhaseV = atan2(-pDftV->Image, pDftV->Real); + + // Calculate Impedance: Z = (V / I) * Rtia + if(MagI > 1e-9) + ZMag = (MagV / MagI) * AppIMPCfg.RtiaVal; + else + ZMag = 0; + + ZPhase = PhaseV - PhaseI + MATH_PI; + + while(ZPhase > MATH_PI) ZPhase -= 2*MATH_PI; + while(ZPhase < -MATH_PI) ZPhase += 2*MATH_PI; + + pOut[i].Magnitude = ZMag; + pOut[i].Phase = ZPhase; + } + *pDataCount = ImpResCount; + AppIMPCfg.FreqofData = AppIMPCfg.SweepCurrFreq; + + if(AppIMPCfg.SweepCfg.SweepEn == bTRUE) + { + AppIMPCfg.FreqofData = AppIMPCfg.SweepCurrFreq; + AppIMPCfg.SweepCurrFreq = AppIMPCfg.SweepNextFreq; + AD5940_SweepNext(&AppIMPCfg.SweepCfg, &AppIMPCfg.SweepNextFreq); + } + + return 0; +} + +int32_t AppIMPISR(void *pBuff, uint32_t *pCount) +{ + uint32_t BuffCount; + uint32_t FifoCnt; + BuffCount = *pCount; + + *pCount = 0; + + if(AD5940_WakeUp(10) > 10) return AD5940ERR_WAKEUP; + AD5940_SleepKeyCtrlS(SLPKEY_LOCK); + + uint32_t IntFlag = AD5940_INTCGetFlag(AFEINTC_1); + + if (IntFlag & (AFEINTSRC_DATAFIFOOF | AFEINTSRC_DATAFIFOUF)) { + AD5940_INTCClrFlag(AFEINTSRC_DATAFIFOOF | AFEINTSRC_DATAFIFOUF); + FIFOCfg_Type fifo_cfg; + fifo_cfg.FIFOEn = bFALSE; + AD5940_FIFOCfg(&fifo_cfg); + fifo_cfg.FIFOEn = bTRUE; + fifo_cfg.FIFOMode = FIFOMODE_FIFO; + fifo_cfg.FIFOSize = FIFOSIZE_4KB; + fifo_cfg.FIFOSrc = FIFOSRC_DFT; + fifo_cfg.FIFOThresh = AppIMPCfg.FifoThresh; + AD5940_FIFOCfg(&fifo_cfg); + + AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); + return AD5940ERR_FIFO; + } + + if(IntFlag & AFEINTSRC_ENDSEQ) + { + int timeout = 200; + while(AD5940_FIFOGetCnt() < 6 && timeout-- > 0) + { + AD5940_Delay10us(10); + } + + FifoCnt = (AD5940_FIFOGetCnt()/6)*6; + if(FifoCnt > BuffCount) FifoCnt = BuffCount; + + AD5940_FIFORd((uint32_t *)pBuff, FifoCnt); + AD5940_INTCClrFlag(AFEINTSRC_ENDSEQ); + + if (FifoCnt > 0) + { + AD5940_SEQCtrlS(bFALSE); + + if (AppIMPRegModify(pBuff, &FifoCnt) == AD5940ERR_OK) + { + if(AppIMPCfg.FifoDataCount < AppIMPCfg.NumOfData || AppIMPCfg.NumOfData == -1) + { + if(AppIMPCfg.StopRequired == bFALSE) + { + AD5940_Delay10us(20); + + AD5940_WriteReg(REG_AFE_SEQCNT, 0); + AD5940_SEQCtrlS(bTRUE); + AD5940_SEQMmrTrig(SEQID_0); + } + } + } + + AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); + AppIMPDataProcess((int32_t*)pBuff, &FifoCnt); + + // Discard extra data points if they exceed the requested count + if (AppIMPCfg.SweepCfg.SweepEn && AppIMPCfg.RealDataCount > 0) { + if (AppIMPCfg.FifoDataCount > AppIMPCfg.RealDataCount) { + *pCount = 0; // Discard + } else { + *pCount = FifoCnt; + } + } else { + *pCount = FifoCnt; + } + } + else + { + AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); + *pCount = 0; + } + return 0; + } + + AD5940_INTCClrFlag(AFEINTSRC_ALLINT); + AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); + return 0; +} \ No newline at end of file diff --git a/temp_legacy_main.c b/temp_legacy_main.c new file mode 100644 index 0000000..a70b824 --- /dev/null +++ b/temp_legacy_main.c @@ -0,0 +1,375 @@ +// File: main.c +#include +#include +#include +#include +#include "pico/stdlib.h" +#include "hardware/spi.h" +#include "hardware/gpio.h" +#include "hardware/watchdog.h" +#include "ad5940.h" +#include "Impedance.h" + +// --------------------------------------------------------------------------- +// Hardware Definitions +// --------------------------------------------------------------------------- +#define PIN_MISO 0 +#define PIN_CS 1 +#define PIN_SCK 2 +#define PIN_MOSI 3 +#define PIN_RST 9 +#define PIN_INT 29 + +#define APPBUFF_SIZE 512 +uint32_t AppBuff[APPBUFF_SIZE]; + +// --------------------------------------------------------------------------- +// Platform Interface Implementation +// --------------------------------------------------------------------------- +void AD5940_CsClr(void) { gpio_put(PIN_CS, 0); } +void AD5940_CsSet(void) { gpio_put(PIN_CS, 1); } +void AD5940_RstClr(void) { gpio_put(PIN_RST, 0); } +void AD5940_RstSet(void) { gpio_put(PIN_RST, 1); } +void AD5940_Delay10us(uint32_t time) { sleep_us(time * 10); } +void AD5940_ReadWriteNBytes(unsigned char *pSendBuffer, unsigned char *pRecvBuff, unsigned long length) { + spi_write_read_blocking(spi0, pSendBuffer, pRecvBuff, length); +} + +uint32_t AD5940_GetMCUIntFlag(void) { + return (gpio_get(PIN_INT) == 0); +} + +uint32_t AD5940_ClrMCUIntFlag(void) { + return 1; +} + +uint32_t AD5940_MCUResourceInit(void *pCfg) { + return 0; +} + +void AD5940_MCUGpioWrite(uint32_t data) { (void)data; } +uint32_t AD5940_MCUGpioRead(uint32_t pin) { (void)pin; return 0; } +void AD5940_MCUGpioCtrl(uint32_t pin, BoolFlag enable) { (void)pin; (void)enable; } + +// --------------------------------------------------------------------------- +// Application Logic +// --------------------------------------------------------------------------- + +void setup_pins(void) { + spi_init(spi0, 4000000); + gpio_set_function(PIN_MISO, GPIO_FUNC_SPI); + gpio_set_function(PIN_SCK, GPIO_FUNC_SPI); + gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI); + + gpio_init(PIN_CS); + gpio_set_dir(PIN_CS, GPIO_OUT); + gpio_put(PIN_CS, 1); + + gpio_init(PIN_RST); + gpio_set_dir(PIN_RST, GPIO_OUT); + gpio_put(PIN_RST, 1); + + gpio_init(PIN_INT); + gpio_set_dir(PIN_INT, GPIO_IN); + gpio_pull_up(PIN_INT); +} + +void AD5940ImpedanceStructInit(void) +{ + AppIMPCfg_Type *pImpedanceCfg; + + AppIMPGetCfg(&pImpedanceCfg); + + pImpedanceCfg->SeqStartAddr = 0; + pImpedanceCfg->MaxSeqLen = 512; + + pImpedanceCfg->RcalVal = 100.0; + pImpedanceCfg->RtiaVal = 200.0; + pImpedanceCfg->SinFreq = 1000.0; + pImpedanceCfg->FifoThresh = 6; + + pImpedanceCfg->DacVoltPP = 600.0; + pImpedanceCfg->ExcitBufGain = EXCITBUFGAIN_0P25; + pImpedanceCfg->HsDacGain = HSDACGAIN_0P2; + + pImpedanceCfg->DswitchSel = SWD_CE0; + pImpedanceCfg->PswitchSel = SWP_CE0; + pImpedanceCfg->NswitchSel = SWN_SE0; + pImpedanceCfg->TswitchSel = SWT_SE0LOAD; + + pImpedanceCfg->HstiaRtiaSel = HSTIARTIA_200; + 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; +} + +static int32_t AD5940PlatformCfg(void) +{ + CLKCfg_Type clk_cfg; + FIFOCfg_Type fifo_cfg; + AGPIOCfg_Type gpio_cfg; + + AD5940_HWReset(); + AD5940_Initialize(); + + // Use HFOSC (16MHz) for stability across all frequencies + clk_cfg.ADCClkDiv = ADCCLKDIV_1; + clk_cfg.ADCCLkSrc = ADCCLKSRC_HFOSC; + clk_cfg.SysClkDiv = SYSCLKDIV_1; + clk_cfg.SysClkSrc = SYSCLKSRC_HFOSC; + clk_cfg.HfOSC32MHzMode = bFALSE; + clk_cfg.HFOSCEn = bTRUE; + clk_cfg.HFXTALEn = bFALSE; + clk_cfg.LFOSCEn = bTRUE; + AD5940_CLKCfg(&clk_cfg); + printf("Clock Configured (HFOSC 16MHz).\n"); + + fifo_cfg.FIFOEn = bFALSE; + fifo_cfg.FIFOMode = FIFOMODE_FIFO; + fifo_cfg.FIFOSize = FIFOSIZE_4KB; + fifo_cfg.FIFOSrc = FIFOSRC_DFT; + fifo_cfg.FIFOThresh = 6; + AD5940_FIFOCfg(&fifo_cfg); + fifo_cfg.FIFOEn = bTRUE; + AD5940_FIFOCfg(&fifo_cfg); + + AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ALLINT, bTRUE); + AD5940_INTCClrFlag(AFEINTSRC_ALLINT); + AD5940_INTCCfg(AFEINTC_0, AFEINTSRC_DATAFIFOTHRESH, bTRUE); + AD5940_INTCClrFlag(AFEINTSRC_ALLINT); + + gpio_cfg.FuncSet = GP0_INT; + gpio_cfg.InputEnSet = 0; + gpio_cfg.OutputEnSet = AGPIO_Pin0; + gpio_cfg.OutVal = 0; + gpio_cfg.PullEnSet = 0; + AD5940_AGPIOCfg(&gpio_cfg); + + AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); + return 0; +} + +void ImpedanceShowResult(uint32_t *pData, uint32_t DataCount) +{ + float freq; + fImpPol_Type *pImp = (fImpPol_Type*)pData; + AppIMPCtrl(IMPCTRL_GETFREQ, &freq); + + for(int i=0;i> Calibrating LFOSC...\n"); + AppIMPCleanup(); + AppIMPCalibrateLFO(); + printf(">> LFOSC Calibrated.\n"); +} + +void Routine_Measure(float freq) { + AppIMPCfg_Type *pCfg; + AppIMPGetCfg(&pCfg); + + AppIMPCleanup(); + AppIMPCalibrateLFO(); + + pCfg->SweepCfg.SweepEn = bFALSE; + pCfg->SinFreq = freq; + pCfg->NumOfData = -1; + pCfg->RealDataCount = -1; // Disable filtering + pCfg->bParaChanged = bTRUE; + + if(AppIMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { + AppIMPCtrl(IMPCTRL_START, 0); + } else { + printf("ERROR: Init Failed\n"); + } +} + +void Routine_Sweep(float start, float end, int steps) { + AppIMPCfg_Type *pCfg; + AppIMPGetCfg(&pCfg); + + AppIMPCleanup(); + AppIMPCalibrateLFO(); + + pCfg->SweepCfg.SweepEn = bTRUE; + pCfg->SweepCfg.SweepStart = start; + pCfg->SweepCfg.SweepStop = end; + + // DUMMY POINT STRATEGY: + // Request steps + 1 from the engine, but tell the ISR to only report 'steps'. + // The artifact will happen on the +1 point, which is discarded. + pCfg->SweepCfg.SweepPoints = steps + 1; + pCfg->NumOfData = steps + 1; + pCfg->RealDataCount = steps; // Stop reporting after this count + + pCfg->SweepCfg.SweepLog = bTRUE; + pCfg->bParaChanged = bTRUE; + + if(AppIMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { + AppIMPCtrl(IMPCTRL_START, 0); + } else { + printf("ERROR: Init Failed\n"); + } +} + +void Routine_CalibrateSystem(void) { + AppIMPCfg_Type *pCfg; + AppIMPGetCfg(&pCfg); + + AppIMPCleanup(); + + // 1. ADC Calibration + ADCPGACal_Type adcpga_cal; + adcpga_cal.AdcClkFreq = 16000000.0; + adcpga_cal.SysClkFreq = 16000000.0; + adcpga_cal.ADCSinc3Osr = ADCSINC3OSR_4; + adcpga_cal.ADCSinc2Osr = ADCSINC2OSR_22; + adcpga_cal.ADCPga = ADCPGA_1P5; + adcpga_cal.PGACalType = PGACALTYPE_OFFSET; + adcpga_cal.TimeOut10us = 1000; + adcpga_cal.VRef1p11 = 1.11; + adcpga_cal.VRef1p82 = 1.82; + printf(">> Calibrating ADC Offset...\n"); + AD5940_ADCPGACal(&adcpga_cal); + + // 2. HSDAC Configuration + HSDACCfg_Type hsdac_cfg; + hsdac_cfg.ExcitBufGain = EXCITBUFGAIN_0P25; + hsdac_cfg.HsDacGain = HSDACGAIN_0P2; + hsdac_cfg.HsDacUpdateRate = 7; + AD5940_HSDacCfgS(&hsdac_cfg); + + // 3. RTIA Calibration + HSRTIACal_Type hsrtia_cal; + fImpPol_Type Res; + memset(&hsrtia_cal, 0, sizeof(hsrtia_cal)); + + hsrtia_cal.fFreq = 1000.0f; + hsrtia_cal.AdcClkFreq = 16000000.0; + hsrtia_cal.SysClkFreq = 16000000.0; + hsrtia_cal.ADCSinc3Osr = ADCSINC3OSR_4; + hsrtia_cal.ADCSinc2Osr = ADCSINC2OSR_22; + hsrtia_cal.bPolarResult = bTRUE; + hsrtia_cal.fRcal = 100.0; + hsrtia_cal.HsTiaCfg.DiodeClose = bFALSE; + hsrtia_cal.HsTiaCfg.HstiaBias = HSTIABIAS_1P1; + hsrtia_cal.HsTiaCfg.HstiaCtia = 31; + hsrtia_cal.HsTiaCfg.HstiaRtiaSel = HSTIARTIA_200; + hsrtia_cal.HsTiaCfg.HstiaDeRtia = HSTIADERTIA_OPEN; + hsrtia_cal.HsTiaCfg.HstiaDeRload = HSTIADERLOAD_OPEN; + hsrtia_cal.DftCfg.DftNum = DFTNUM_16384; + hsrtia_cal.DftCfg.DftSrc = DFTSRC_SINC3; + + printf(">> Calibrating HSTIARTIA_200...\n"); + if (AD5940_HSRtiaCal(&hsrtia_cal, &Res) == AD5940ERR_OK) { + printf("Calibrated Rtia: Mag = %f Ohm, Phase = %f\n", Res.Magnitude, Res.Phase); + pCfg->RtiaVal = Res.Magnitude; + } else { + printf("Calibration Failed\n"); + } +} + +// --------------------------------------------------------------------------- +// Main Loop +// --------------------------------------------------------------------------- + +char input_buffer[64]; +int input_pos = 0; + +void process_command() { + char cmd = input_buffer[0]; + + sleep_ms(10); + + if (cmd == 'v') { + uint32_t id = AD5940_ReadReg(REG_AFECON_CHIPID); + printf("CHIP_ID:0x%04X\n", id); + } + else if (cmd == 'c') { + Routine_CalibrateSystem(); + } + else if (cmd == 'm') { + float freq = 1000.0f; + if (strlen(input_buffer) > 2) freq = atof(input_buffer + 2); + Routine_Measure(freq); + } + else if (cmd == 's') { + float start = 100.0f, end = 100000.0f; + int steps = 50; + if (strlen(input_buffer) > 2) sscanf(input_buffer + 2, "%f %f %d", &start, &end, &steps); + Routine_Sweep(start, end, steps); + } + else if (cmd == 'x') { + AppIMPCleanup(); + printf("STOPPED\n"); + } + else if (cmd == 'z') { + watchdog_reboot(0, 0, 0); + } +} + +int main() { + stdio_init_all(); + sleep_ms(2000); + + setup_pins(); + AD5940PlatformCfg(); + AD5940ImpedanceStructInit(); + + printf("SYSTEM_READY\n"); + + while (true) { + int c = getchar_timeout_us(0); + if (c != PICO_ERROR_TIMEOUT) { + if (c == '\n' || c == '\r') { + input_buffer[input_pos] = 0; + if (input_pos > 0) process_command(); + input_pos = 0; + } else if (input_pos < 63) { + input_buffer[input_pos++] = (char)c; + } + } + + if (gpio_get(PIN_INT) == 0) { + uint32_t temp = APPBUFF_SIZE; + int32_t status = AppIMPISR(AppBuff, &temp); + + if (status == AD5940ERR_FIFO) { + printf("ERROR: FIFO Overflow/Underflow. Stopping.\n"); + AppIMPCleanup(); + } else if(temp > 0) { + ImpedanceShowResult(AppBuff, temp); + } + } + } + return 0; +} \ No newline at end of file