it works (just doesn't work very well) but the measurements are now actually accurate at least

This commit is contained in:
pszsh 2026-01-26 14:07:55 -08:00
parent 5fc4565064
commit 98bd3534ea
6 changed files with 174 additions and 321 deletions

View File

@ -1,262 +0,0 @@
/* Library Version */
AD5940LIB_VER_MAJOR, AD5940LIB_VER_MINOR, AD5940LIB_VER_PATCH, AD5940LIB_VER
/* AGPIO Registers (0x00) */
REG_AGPIO_GP0CON, REG_AGPIO_GP0OEN, REG_AGPIO_GP0PE, REG_AGPIO_GP0IEN
REG_AGPIO_GP0IN, REG_AGPIO_GP0OUT, REG_AGPIO_GP0SET, REG_AGPIO_GP0CLR, REG_AGPIO_GP0TGL
/* AGPIO Bitmasks */
BITP/M_AGPIO_GP0CON_PINxCFG (x=0-7)
BITP/M_AGPIO_GP0OEN_OEN, BITP/M_AGPIO_GP0PE_PE, BITP/M_AGPIO_GP0IEN_IEN
BITP/M_AGPIO_GP0IN_IN, BITP/M_AGPIO_GP0OUT_OUT, BITP/M_AGPIO_GP0SET_SET
BITP/M_AGPIO_GP0CLR_CLR, BITP/M_AGPIO_GP0TGL_TGL
/* AFECON Registers (0x400) */
REG_AFECON_ADIID, REG_AFECON_CHIPID, REG_AFECON_CLKCON0, REG_AFECON_CLKEN1
REG_AFECON_CLKSEL, REG_AFECON_CLKCON0KEY, REG_AFECON_SWRSTCON, REG_AFECON_TRIGSEQ
/* AFECON Bitmasks */
BITP/M_AFECON_ADIID_ADIID, BITP/M_AFECON_CHIPID_PARTID/REVISION
BITP/M_AFECON_CLKCON0_SFFTCLKDIVCNT, ADCCLKDIV, SYSCLKDIV
BITP/M_AFECON_CLKEN1_GPT1DIS, GPT0DIS, ACLKDIS
BITP/M_AFECON_CLKSEL_ADCCLKSEL, SYSCLKSEL
BITP/M_AFECON_CLKCON0KEY_DIVSYSCLK_ULP_EN
BITP/M_AFECON_SWRSTCON_SWRSTL
BITP/M_AFECON_TRIGSEQ_TRIGx (x=0-3)
/* AFEWDT Registers (0x900) */
REG_AFEWDT_WDTLD, REG_AFEWDT_WDTVALS, REG_AFEWDT_WDTCON, REG_AFEWDT_WDTCLRI
REG_AFEWDT_WDTSTA, REG_AFEWDT_WDTMINLD
/* AFEWDT Bitmasks */
BITP/M_AFEWDT_WDTLD_LOAD, BITP/M_AFEWDT_WDTVALS_CCOUNT
BITP/M_AFEWDT_WDTCON_WDTIRQEN, MINLOAD_EN, CLKDIV2, MDE, EN, PRE, IRQ, PDSTOP
ENUM_AFEWDT_WDTCON_RESET, INTERRUPT, CONTINUE, STOP
BITP/M_AFEWDT_WDTCLRI_CLRWDG
BITP/M_AFEWDT_WDTSTA_TMINLD, OTPWRDONE, LOCK, CON, TLD, CLRI, IRQ
ENUM_AFEWDT_WDTSTA_OPEN, LOCKED, SYNC_COMPLETE, SYNC_IN_PROGRESS, CLEARED, PENDING
BITP/M_AFEWDT_WDTMINLD_MIN_LOAD
/* WUPTMR Registers (0x800) */
REG_WUPTMR_CON, REG_WUPTMR_SEQORDER
REG_WUPTMR_SEQxWUPL/H (x=0-3), REG_WUPTMR_SEQxSLEEPL/H (x=0-3)
/* WUPTMR Bitmasks */
BITP/M_WUPTMR_CON_MSKTRG, CLKSEL, ENDSEQ, EN
ENUM_WUPTMR_CON_SWT32K0, SWTEXT0, SWT32K, SWTEXT, SWTEN, SWTDIS
ENUM_WUPTMR_CON_ENDSEQx (x=A-H)
BITP/M_WUPTMR_SEQORDER_SEQx (x=A-H)
ENUM_WUPTMR_SEQORDER_SEQx0-3
BITP/M_WUPTMR_SEQxWUPL/H_WAKEUPTIMEx, BITP/M_WUPTMR_SEQxSLEEPL/H_SLEEPTIMEx
/* ALLON Registers (0xA00) */
REG_ALLON_PWRMOD, REG_ALLON_PWRKEY, REG_ALLON_OSCKEY, REG_ALLON_OSCCON
REG_ALLON_TMRCON, REG_ALLON_EI0CON, REG_ALLON_EI1CON, REG_ALLON_EI2CON
REG_ALLON_EICLR, REG_ALLON_RSTSTA, REG_ALLON_RSTCONKEY, REG_ALLON_LOSCTST, REG_ALLON_CLKEN0
/* ALLON Bitmasks */
BITP/M_ALLON_PWRMOD_RAMRETEN, ADCRETEN, SEQSLPEN, TMRSLPEN, PWRMOD
BITP/M_ALLON_PWRKEY_PWRKEY, BITP/M_ALLON_OSCKEY_OSCKEY
BITP/M_ALLON_OSCCON_HFXTALOK, HFOSCOK, LFOSCOK, HFXTALEN, HFOSCEN, LFOSCEN
BITP/M_ALLON_TMRCON_TMRINTEN
BITP/M_ALLON_EI0CON_IRQxEN/MDE (x=0-3)
BITP/M_ALLON_EI1CON_IRQxEN/MDE (x=4-7)
BITP/M_ALLON_EI2CON_BUSINTEN, BUSINTMDE
BITP/M_ALLON_EICLR_AUTCLRBUSEN, BUSINT
BITP/M_ALLON_RSTSTA_PINSWRST, MMRSWRST, WDRST, EXTRST, POR
BITP/M_ALLON_RSTCONKEY_KEY
BITP/M_ALLON_LOSCTST_TRIM
BITP/M_ALLON_CLKEN0_TIACHPDIS, SLPWUTDIS, WDTDIS
/* AGPT0 Registers (0xD00) & AGPT1 Registers (0xE00) */
REG_AGPT0_LD0, REG_AGPT0_VAL0, REG_AGPT0_CON0, REG_AGPT0_CLRI0, REG_AGPT0_CAP0
REG_AGPT0_ALD0, REG_AGPT0_AVAL0, REG_AGPT0_STA0, REG_AGPT0_PWMCON0, REG_AGPT0_PWMMAT0, REG_AGPT0_INTEN
REG_AGPT1_LD1, REG_AGPT1_VAL1, REG_AGPT1_CON1, REG_AGPT1_CLRI1, REG_AGPT1_CAP1
REG_AGPT1_ALD1, REG_AGPT1_AVAL1, REG_AGPT1_STA1, REG_AGPT1_PWMCON1, REG_AGPT1_PWMMAT1, REG_AGPT1_INTEN1
/* AGPT Bitmasks */
BITP/M_AGPTx_CONx_SYNCBYP, RSTEN, EVTEN, EVENT, RLD, CLK, ENABLE, MOD, UP, PRE
BITP/M_AGPTx_CLRIx_CAP, TMOUT
BITP/M_AGPTx_STAx_RSTCNT, PDOK, BUSY, CAP, TMOUT
BITP/M_AGPTx_PWMCONx_IDLE, MATCHEN
/* AFECRC Registers (0x1000) */
REG_AFECRC_CTL, REG_AFECRC_IPDATA, REG_AFECRC_RESULT, REG_AFECRC_POLY
REG_AFECRC_IPBITS, REG_AFECRC_IPBYTE, REG_AFECRC_CRC_SIG_COMP, REG_AFECRC_CRCINTEN, REG_AFECRC_INTSTA
/* AFECRC Bitmasks */
BITP/M_AFECRC_CTL_REVID, MON_EN, W16SWP, BYTMIRR, BITMIRR, LSBFIRST, EN
/* AFE Registers (0x2000) */
REG_AFE_AFECON, REG_AFE_SEQCON, REG_AFE_FIFOCON, REG_AFE_SWCON, REG_AFE_HSDACCON
REG_AFE_WGCON, REG_AFE_WGDCLEVEL1/2, REG_AFE_WGDELAY1/2, REG_AFE_WGSLOPE1/2
REG_AFE_WGFCW, REG_AFE_WGPHASE, REG_AFE_WGOFFSET, REG_AFE_WGAMPLITUDE
REG_AFE_ADCFILTERCON, REG_AFE_HSDACDAT, REG_AFE_LPREFBUFCON, REG_AFE_SYNCEXTDEVICE
REG_AFE_SEQCRC, REG_AFE_SEQCNT, REG_AFE_SEQTIMEOUT, REG_AFE_DATAFIFORD, REG_AFE_CMDFIFOWRITE
REG_AFE_ADCDAT, REG_AFE_DFTREAL, REG_AFE_DFTIMAG, REG_AFE_SINC2DAT, REG_AFE_TEMPSENSDAT
REG_AFE_AFEGENINTSTA, REG_AFE_ADCMIN/SM, REG_AFE_ADCMAX/SMEN, REG_AFE_ADCDELTA
REG_AFE_HPOSCCON, REG_AFE_DFTCON
REG_AFE_LPTIASW0/1, REG_AFE_LPTIACON0/1
REG_AFE_HSRTIACON, REG_AFE_DE0/1RESCON, REG_AFE_HSTIACON
REG_AFE_LPMODEKEY, REG_AFE_LPMODECLKSEL, REG_AFE_LPMODECON
REG_AFE_SEQSLPLOCK, REG_AFE_SEQTRGSLP
REG_AFE_LPDACDAT0/1, REG_AFE_LPDACSW0/1, REG_AFE_LPDACCON0/1
REG_AFE_DSWFULLCON, REG_AFE_NSWFULLCON, REG_AFE_PSWFULLCON, REG_AFE_TSWFULLCON
REG_AFE_TEMPSENS, REG_AFE_BUFSENCON, REG_AFE_ADCCON
REG_AFE_DSWSTA, REG_AFE_PSWSTA, REG_AFE_NSWSTA, REG_AFE_TSWSTA
REG_AFE_STATSVAR, REG_AFE_STATSCON, REG_AFE_STATSMEAN
REG_AFE_SEQ0/1/2/3INFO, REG_AFE_CMDFIFOWADDR, REG_AFE_CMDDATACON, REG_AFE_DATAFIFOTHRES
REG_AFE_REPEATADCCNV, REG_AFE_FIFOCNTSTA, REG_AFE_CALDATLOCK
REG_AFE_ADCOFFSETHSTIA, REG_AFE_ADCGAINTEMPSENS0, REG_AFE_ADCOFFSETTEMPSENS0/1
REG_AFE_ADCGAINGN1/1P5/2/4/9, REG_AFE_ADCOFFSETGN1/1P5/2/4/9
REG_AFE_DACGAIN, REG_AFE_DACOFFSET, REG_AFE_DACOFFSETATTEN/HP
REG_AFE_ADCPGAOFFSETCANCEL, REG_AFE_ADCGNHSTIA, REG_AFE_ADCPGAGN4OFCAL
REG_AFE_ADCOFFSETLPTIA0/1, REG_AFE_ADCGNLPTIA0/1, REG_AFE_ADCGAINDIOTEMPSENS
REG_AFE_PMBW, REG_AFE_SWMUX, REG_AFE_AFE_TEMPSEN_DIO, REG_AFE_ADCBUFCON
/* AFE Bitmasks & Enums */
BITP/M_AFE_AFECON_DACBUFEN, DACREFEN, ALDOILIMITEN, SINC2EN, DFTEN, WAVEGENEN
BITP/M_AFE_AFECON_TEMPCONVEN, TEMPSENSEN, TIAEN, INAMPEN, EXBUFEN, ADCCONVEN, ADCEN, DACEN, HPREFDIS
ENUM_AFE_AFECON_OFF, ENUM_AFE_AFECON_ON
BITP/M_AFE_SEQCON_SEQWRTMR, SEQHALT, SEQHALTFIFOEMPTY, SEQEN
BITP/M_AFE_FIFOCON_DATAFIFOSRCSEL, DATAFIFOEN
BITP/M_AFE_SWCON_TxCON, SWSOURCESEL, TMUXCON, NMUXCON, PMUXCON, DMUXCON
BITP/M_AFE_HSDACCON_INAMPGNMDE, RATE, ATTENEN
BITP/M_AFE_WGCON_DACGAINCAL, DACOFFSETCAL, TYPESEL, TRAPRSTEN
BITP/M_AFE_ADCFILTERCON_AVRGNUM, SINC3OSR, SINC2OSR, AVRGEN, SINC3BYP, LPFBYPEN, ADCCLK
BITP/M_AFE_LPREFBUFCON_BOOSTCURRENT, LPBUF2P5DIS, LPREFDIS
BITP/M_AFE_CMDFIFOWRITE_CMDFIFOIN
BITP/M_AFE_CMDDATACON_DATAMEMMDE, DATA_MEM_SEL, CMDMEMMDE, CMD_MEM_SEL
ENUM_AFE_CMDDATACON_DFIFO, DSTM, DMEM32B, DMEM2K, DMEM4K, DMEM6K, CMEM, CFIFO, CSTM, CMEM32B, CMEM2K, CMEM4K, CMEM6K
BITP/M_AFE_DFTCON_DFTINSEL, DFTNUM, HANNINGEN
BITP/M_AFE_LPTIASWx_TIABIASSEL, PABIASSEL, TIASWCON
ENUM_AFE_LPTIASWx_CAPA_LP, NORM, DIO, SHORTSW, LOWNOISE, CAPA_RAMP_H, BUFDIS, BUFEN/2, TWOLEAD, SESHORTRE
BITP/M_AFE_LPTIACONx_CHOPEN, TIARF, TIARL, TIAGAIN, IBOOST, HALFPWR, PAPDEN, TIAPDEN
ENUM_AFE_LPTIACONx_DISCONRF, BYPRF, RF20K, RF100K, RF200K, RF400K, RF600K, RF1MOHM
ENUM_AFE_LPTIACONx_RL0, RL10, RL30, RL50, RL100, RL1P6K, RL3P1K, RL3P5K
ENUM_AFE_LPTIACONx_DISCONTIA, TIAGAIN200, 1K, 2K...512K
BITP/M_AFE_HSRTIACON_CTIACON, TIASW6CON, RTIACON
BITP/M_AFE_DExRESCON_DExRCON
BITP/M_AFE_HSTIACON_VBIASSEL
BITP/M_AFE_DACDCBUFCON_CHANSEL, CHAN0, CHAN1
BITP/M_AFE_LPMODECON_ALDOEN, V1P1HPADCEN, V1P8HPADCEN, PTATEN, ZTATEN, REPEATADCCNVEN_P, ADCCONVEN, HPREFDIS, HFOSCPD
BITP/M_AFE_LPDACSWx_LPMODEDIS, LPDACSW, DACCONBIT5, OVRRIDE
BITP/M_AFE_LPDACCONx_WAVETYPE, DACMDE, VZEROMUX, VBIASMUX, REFSEL, PWDEN, RSTEN
ENUM_AFE_LPDACCONx_MMR, WAVEGEN, NORM, DIAG, BITS6, BITS12, 12BIT, EN, ULPREF, AVDD, PWREN, PWRDIS, WRITEDIS, WRITEEN
BITP/M_AFE_DSWFULLCON_Dx (x=2-8), DR0
BITP/M_AFE_NSWFULLCON_NL2, NL, NR1, Nx (x=1-9)
BITP/M_AFE_PSWFULLCON_PL2, PL, Px (x=2-12), PR0
BITP/M_AFE_TSWFULLCON_TR1, Tx (x=1-11)
BITP/M_AFE_TEMPSENS_CHOPFRESEL, CHOPCON, ENABLE
BITP/M_AFE_BUFSENCON_V1P8THERMSTEN, V1P1LPADCCHGDIS, V1P1LPADCEN, V1P1HPADCEN, V1P8HPADCCHGDIS, V1P8LPADCEN, V1P8HPADCILIMITEN, V1P8HPADCEN
BITP/M_AFE_ADCCON_GNPGA, GNOFSELPGA, GNOFFSEL, MUXSELN, MUXSELP
BITP/M_AFE_STATSCON_STDDEV, SAMPLENUM, RESRVED, STATSEN
BITP/M_AFE_PMBW_SYSBW, SYSHP, BWNA, BW50, BW100, BW250, LP, HP
/* INTC Registers (0x3000) */
REG_INTC_INTCPOL, REG_INTC_INTCCLR, REG_INTC_INTCSEL0/1, REG_INTC_INTCFLAG0/1
/* SPI Commands */
SPICMD_SETADDR, SPICMD_READREG, SPICMD_WRITEREG, SPICMD_READFIFO
/* Interrupt Controller Constants */
AFEINTC_0, AFEINTC_1
AFEINTSRC_ADCRDY, DFTRDY, SINC2RDY, TEMPRDY, ADCMINERR, ADCMAXERR, ADCDIFFERR, MEANRDY, VARRDY
AFEINTSRC_CUSTOMINTx (x=0-3), BOOTLDDONE, WAKEUP, ENDSEQ, SEQTIMEOUT, SEQTIMEOUTERR
AFEINTSRC_CMDFIFOFULL, CMDFIFOEMPTY, CMDFIFOTHRESH, CMDFIFOOF, CMDFIFOUF
AFEINTSRC_DATAFIFOFULL, DATAFIFOEMPTY, DATAFIFOTHRESH, DATAFIFOOF, DATAFIFOUF
AFEINTSRC_WDTIRQ, CRC_OUTLIER, GPT0INT_SLPWUT, GPT1INT_TRYBRK, ALLINT
/* Power & Bandwidth */
AFEPWR_LP, AFEPWR_HP
AFEBW_AUTOSET, AFEBW_50KHZ, AFEBW_100KHZ, AFEBW_250KHZ
/* AFE Control Signals (Masks) */
AFECTRL_HPREFPWR, HSDACPWR, ADCPWR, ADCCNV, EXTBUFPWR, INAMPPWR, HSTIAPWR
AFECTRL_TEMPSPWR, TEMPCNV, WG, DFT, SINC2NOTCH, ALDOLIMIT, DACREFPWR, DCBUFPWR, ALL
/* Low Power Mode Control Signals */
LPMODECTRL_HFOSCEN, HPREFPWR, ADCCNV, REPEATEN, GLBBIASZ, GLBBIASP, BUFHP1P8V, BUFHP1P1V, ALDOPWR, ALL, NONE
/* Result Types */
AFERESULT_SINC3, SINC2, TEMPSENSOR, DFTREAL, DFTIMAGE, STATSMEAN, STATSVAR
/* Switch Matrix Definitions */
SWD_OPEN, RCAL0, AIN1, AIN2, AIN3, CE0, CE1, AFE1, SE0, SE1, AFE3
SWP_OPEN, RCAL0, AIN1, AIN2, AIN3, RE0, RE1, AFE2, SE0, DE0, SE1, AFE3, DE1, CE0, CE1, AFE1, PL, PL2
SWN_OPEN, RCAL1, AIN0, AIN1, AIN2, AIN3, SE0LOAD, DE0LOAD, SE1LOAD, AFE3LOAD, DE1LOAD, SE0, NL, NL2
SWT_OPEN, RCAL1, AIN0, AIN1, AIN2, AIN3, SE0LOAD, DE0, SE1LOAD, AFE3LOAD, DE1, TRTIA, DE0LOAD, DE1LOAD
/* Waveform Generator Types */
WGTYPE_MMR, WGTYPE_SIN, WGTYPE_TRAPZ
/* HSDAC Constants */
EXCITBUFGAIN_2, EXCITBUFGAIN_0P25
HSDACGAIN_1, HSDACGAIN_0P2
/* HSTIA Constants */
HSTIABIAS_1P1, VZERO0, VZERO1
HSTIARTIA_200, 1K, 5K, 10K, 20K, 40K, 80K, 160K, OPEN
HSTIADERTIA_50, 100, 200, 1K, 5K, 10K, 20K, 40K, 80K, 160K, TODE, OPEN
HSTIADERLOAD_0R, 10R, 30R, 50R, 100R, OPEN
HSTIAPWRMOE_LP, HP
/* LPDAC Constants */
LPDAC0, LPDAC1
LPDACSRC_MMR, WG
LPDACSW_VBIAS2LPPA, VBIAS2PIN, VZERO2LPTIA, VZERO2PIN, VZERO2HSTIA
LPDACVZERO_6BIT, 12BIT
LPDACVBIAS_6BIT, 12BIT
LPDACREF_2P5, AVDD
/* LPAMP/LPTIA Constants */
LPTIA0, LPTIA1
LPTIARF_OPEN, SHORT, 20K, 100K, 200K, 400K, 600K, 1M
LPTIARLOAD_SHORT, 10R, 30R, 50R, 100R, 1K6, 3K1, 3K6
LPTIARTIA_OPEN, 200R, 1K...512K
LPAMP0, LPAMP1
LPAMPPWR_NORM, BOOST1, BOOST2, BOOST3, HALF
LPTIASW(n)
/* ADC Constants */
ADCPGA_1, 1P5, 2, 4, 9
ADCMUXP_FLOAT, HSTIA_P, AIN0-6, AVDD_2, DVDD_2, AVDDREG, TEMPP/N, VSET1P1, VDE0, VSE0/1, VAFE1-4, VREF2P5, VREF1P8DAC, VZERO0/1, VBIAS0/1, VCE0/1, VRE0/1, VCE0_2, VCE1_2, LPTIA0_P, LPTIA1_P, AGND, P_NODE, IOVDD_2
ADCMUXN_FLOAT, HSTIA_N, LPTIA0_N, LPTIA1_N, AIN0-6, VSET1P1, VREF1P1, TEMPN, VZERO0/1, VBIAS0/1, AFE4, N_NODE
ADCRATE_800KHZ, 1P6MHZ
ADCSINC3OSR_2, 4, 5
ADCSINC2OSR_22, 44...1333
ADCAVGNUM_2, 4, 8, 16
/* DFT & Statistics Constants */
DFTSRC_SINC2NOTCH, SINC3, ADCRAW, AVG
DFTNUM_4, 8...16384
STATSAMPLE_128, 64, 32, 16, 8
STATDEV_1, 4, 9, 16, 25
/* Sequencer & FIFO Constants */
SEQID_0, 1, 2, 3
SEQMEMSIZE_32B, 2KB, 4KB, 6KB
SEQPINTRIGMODE_RISING, FALLING, BOTHEDGE, HIGHL, LOWL
SEQ_WAIT(ClkNum), SEQ_TOUT(ClkNum), SEQ_WR(addr,data)
SEQ_NOP(), SEQ_HALT(), SEQ_STOP(), SEQ_SLP(), SEQ_INTx(), SEQ_LEN(n)
FIFOMODE_FIFO, STREAM
FIFOSRC_SINC3, DFT, SINC2NOTCH, VAR, MEAN
FIFO_SEQID(data), ECC, CHANID
FIFOSIZE_32B, 2KB, 4KB, 6KB
WUPTENDSEQ_A - H
/* Misc Constants */
DATATYPE_ADCRAW, SINC3, SINC2, DFT, NOTCH
SLPKEY_LOCK, UNLOCK
HPOSCOUT_32MHZ, 16MHZ
AGPIO_Pin0 - Pin7
GPx_INT/TRIG/SYNC/GPIO/SLEEP/PORB/EXTCLK
LPMODECLK_HFOSC, LFOSC
SYSCLKSRC_HFOSC, XTAL, LFOSC, EXT
ADCCLKSRC_HFOSC, XTAL, EXT
ADCCLKDIV_1, 2
SYSCLKDIV_1, 2
PGACALTYPE_OFFSET, GAIN, OFFSETGAIN
AD5940ERR_OK, ERROR, PARA, NULLP, BUFF, ADDROR, SEQGEN, SEQREG, SEQLEN, WAKEUP, TIMEOUT, CALOR, APPERROR
MATH_PI, AD5940_ADIID, AD5940_CHIPID, M355_ADIID, M355_CHIPID, AD5940_SWRST
KEY_OSCCON, KEY_CALDATLOCK, KEY_LPMODEKEY

3
.gitignore vendored
View File

@ -6,12 +6,13 @@ build
*.swp
*.cmake
requirements.txt
ad5940.c
ad5940.*
pico_sdk_import.cmake
build*
*.png
icons/
*.pdf
examples/
build/
build_android/

View File

@ -1,4 +1,4 @@
// File: Impedance.c
// Impedance.c
#include "ad5940.h"
#include <stdio.h>
#include "string.h"
@ -370,7 +370,7 @@ AD5940Err AppIMPCheckFreq(float freq)
{
ADCFilterCfg_Type filter_cfg;
DFTCfg_Type dft_cfg;
HSDACCfg_Type hsdac_cfg;
// HSDACCfg_Type hsdac_cfg; // Removed to prevent override
uint32_t WaitClks;
ClksCalInfo_Type clks_cal;
FreqParams_Type freq_params;
@ -379,57 +379,61 @@ AD5940Err AppIMPCheckFreq(float freq)
freq_params = AD5940_GetFreqParameters(freq);
// CRITICAL FIX: Removed HSDAC and HSRTIA overrides.
// The configuration set in AppIMPSeqCfgGen (based on user config) should persist.
// Overriding HSTIARTIA_5K here while RtiaVal remains 200 causes massive math errors.
if(freq < 0.51)
{
hsdac_cfg.ExcitBufGain = EXCITBUFGAIN_2;
hsdac_cfg.HsDacGain = HSDACGAIN_1;
hsdac_cfg.HsDacUpdateRate = 0x1B;
AD5940_HSDacCfgS(&hsdac_cfg);
AD5940_HSRTIACfgS(HSTIARTIA_40K);
// hsdac_cfg.ExcitBufGain = EXCITBUFGAIN_2;
// hsdac_cfg.HsDacGain = HSDACGAIN_1;
// hsdac_cfg.HsDacUpdateRate = 0x1B;
// AD5940_HSDacCfgS(&hsdac_cfg);
// AD5940_HSRTIACfgS(HSTIARTIA_40K);
filter_cfg.ADCRate = ADCRATE_800KHZ;
AppIMPCfg.AdcClkFreq = 16e6;
AD5940_HPModeEn(bFALSE);
}
else if(freq < 5 )
{
hsdac_cfg.ExcitBufGain = EXCITBUFGAIN_2;
hsdac_cfg.HsDacGain = HSDACGAIN_1;
hsdac_cfg.HsDacUpdateRate = 0x1B;
AD5940_HSDacCfgS(&hsdac_cfg);
AD5940_HSRTIACfgS(HSTIARTIA_40K);
// hsdac_cfg.ExcitBufGain = EXCITBUFGAIN_2;
// hsdac_cfg.HsDacGain = HSDACGAIN_1;
// hsdac_cfg.HsDacUpdateRate = 0x1B;
// AD5940_HSDacCfgS(&hsdac_cfg);
// AD5940_HSRTIACfgS(HSTIARTIA_40K);
filter_cfg.ADCRate = ADCRATE_800KHZ;
AppIMPCfg.AdcClkFreq = 16e6;
AD5940_HPModeEn(bFALSE);
}
else if(freq < 450)
{
hsdac_cfg.ExcitBufGain = AppIMPCfg.ExcitBufGain;
hsdac_cfg.HsDacGain = AppIMPCfg.HsDacGain;
hsdac_cfg.HsDacUpdateRate = 0x1B;
AD5940_HSDacCfgS(&hsdac_cfg);
AD5940_HSRTIACfgS(HSTIARTIA_5K);
// hsdac_cfg.ExcitBufGain = AppIMPCfg.ExcitBufGain;
// hsdac_cfg.HsDacGain = AppIMPCfg.HsDacGain;
// hsdac_cfg.HsDacUpdateRate = 0x1B;
// AD5940_HSDacCfgS(&hsdac_cfg);
// AD5940_HSRTIACfgS(HSTIARTIA_5K);
filter_cfg.ADCRate = ADCRATE_800KHZ;
AppIMPCfg.AdcClkFreq = 16e6;
AD5940_HPModeEn(bFALSE);
}
else if(freq<80000)
{
hsdac_cfg.ExcitBufGain = AppIMPCfg.ExcitBufGain;
hsdac_cfg.HsDacGain = AppIMPCfg.HsDacGain;
hsdac_cfg.HsDacUpdateRate = 0x1B;
AD5940_HSDacCfgS(&hsdac_cfg);
AD5940_HSRTIACfgS(HSTIARTIA_5K);
// hsdac_cfg.ExcitBufGain = AppIMPCfg.ExcitBufGain;
// hsdac_cfg.HsDacGain = AppIMPCfg.HsDacGain;
// hsdac_cfg.HsDacUpdateRate = 0x1B;
// AD5940_HSDacCfgS(&hsdac_cfg);
// AD5940_HSRTIACfgS(HSTIARTIA_5K);
filter_cfg.ADCRate = ADCRATE_800KHZ;
AppIMPCfg.AdcClkFreq = 16e6;
AD5940_HPModeEn(bFALSE);
}
if(freq >= 80000)
{
hsdac_cfg.ExcitBufGain = AppIMPCfg.ExcitBufGain;
hsdac_cfg.HsDacGain = AppIMPCfg.HsDacGain;
hsdac_cfg.HsDacUpdateRate = 0x07;
AD5940_HSDacCfgS(&hsdac_cfg);
AD5940_HSRTIACfgS(HSTIARTIA_5K);
// hsdac_cfg.ExcitBufGain = AppIMPCfg.ExcitBufGain;
// hsdac_cfg.HsDacGain = AppIMPCfg.HsDacGain;
// hsdac_cfg.HsDacUpdateRate = 0x07;
// AD5940_HSDacCfgS(&hsdac_cfg);
// AD5940_HSRTIACfgS(HSTIARTIA_5K);
filter_cfg.ADCRate = ADCRATE_1P6MHZ;
AppIMPCfg.AdcClkFreq = 32e6;
AD5940_HPModeEn(bTRUE);

View File

@ -1,4 +1,4 @@
// File: host/src/MainWindow.cpp
// host/src/MainWindow.cpp
#include "MainWindow.h"
#include <QVBoxLayout>
#include <QDebug>
@ -82,11 +82,11 @@ void MainWindow::setupUi() {
// Measurement Control
QLabel *lblFreq = new QLabel(" Freq:", this);
QDoubleSpinBox *spinFreq = new QDoubleSpinBox(this);
spinFreq = new QDoubleSpinBox(this);
spinFreq->setRange(10.0, 200000.0);
spinFreq->setValue(1000.0);
spinFreq->setSuffix(" Hz");
QPushButton *measureBtn = new QPushButton("Measure", this);
measureBtn = new QPushButton("Measure", this);
toolbar->addWidget(lblFreq);
toolbar->addWidget(spinFreq);
@ -95,6 +95,7 @@ void MainWindow::setupUi() {
checkIdBtn->setEnabled(false);
calibrateBtn->setEnabled(false);
sweepBtn->setEnabled(false);
measureBtn->setEnabled(false);
// Signal Connections
connect(connectBtn, &QPushButton::clicked, this, &MainWindow::connectToPort);
@ -102,16 +103,7 @@ void MainWindow::setupUi() {
connect(checkIdBtn, &QPushButton::clicked, this, &MainWindow::checkDeviceId);
connect(calibrateBtn, &QPushButton::clicked, this, &MainWindow::runCalibration);
connect(sweepBtn, &QPushButton::clicked, this, &MainWindow::startSweep);
// Measure Button Logic
connect(measureBtn, &QPushButton::clicked, [this, spinFreq]() {
if (serial->isOpen()) {
double freq = spinFreq->value();
logWidget->append(QString(">> Requesting Measure (m %1)...").arg(freq));
// Send 'm <freq>\n'
serial->write(QString("m %1\n").arg(freq).toUtf8());
}
});
connect(measureBtn, &QPushButton::clicked, this, &MainWindow::toggleMeasurement);
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
toolbar->setIconSize(QSize(32, 32));
@ -131,18 +123,31 @@ void MainWindow::setupUi() {
void MainWindow::refreshPorts() {
portSelector->clear();
const auto infos = QSerialPortInfo::availablePorts();
bool foundTarget = false;
QString targetPort;
for (const QSerialPortInfo &info : infos) {
portSelector->addItem(info.portName());
// Auto-connect to device with 0xCAFE Vendor ID
if (info.hasVendorIdentifier() && info.vendorIdentifier() == 0xCAFE) {
logWidget->append(">> Found EIS Device (0xCAFE) on " + info.portName());
portSelector->setCurrentText(info.portName());
// Check for 0xCAFE or "usbmodem"
bool isCafe = (info.hasVendorIdentifier() && info.vendorIdentifier() == 0xCAFE);
bool isUsbModem = info.portName().contains("usbmodem", Qt::CaseInsensitive);
if ((isCafe || isUsbModem) && !foundTarget) {
targetPort = info.portName();
foundTarget = true;
logWidget->append(">> Found Target Device: " + targetPort);
}
}
// Auto-connect if found and not already connected
if (foundTarget) {
portSelector->setCurrentText(targetPort);
if (!serial->isOpen()) {
connectToPort();
}
}
}
}
void MainWindow::connectToPort() {
if (serial->isOpen()) {
@ -152,6 +157,9 @@ void MainWindow::connectToPort() {
checkIdBtn->setEnabled(false);
calibrateBtn->setEnabled(false);
sweepBtn->setEnabled(false);
measureBtn->setEnabled(false);
isMeasuring = false;
measureBtn->setText("Measure");
return;
}
@ -166,6 +174,7 @@ void MainWindow::connectToPort() {
checkIdBtn->setEnabled(true);
calibrateBtn->setEnabled(true);
sweepBtn->setEnabled(true);
measureBtn->setEnabled(true);
} else {
logWidget->append(">> Connection Error: " + serial->errorString());
}
@ -179,6 +188,9 @@ void MainWindow::onPortError(QSerialPort::SerialPortError error) {
checkIdBtn->setEnabled(false);
calibrateBtn->setEnabled(false);
sweepBtn->setEnabled(false);
measureBtn->setEnabled(false);
isMeasuring = false;
measureBtn->setText("Measure");
}
}
@ -208,6 +220,25 @@ void MainWindow::startSweep() {
serial->write("s 100 200000 50\n");
}
void MainWindow::toggleMeasurement() {
if (!serial->isOpen()) return;
if (isMeasuring) {
// Stop
logWidget->append(">> Stopping Measurement (x)...");
serial->write("x\n");
measureBtn->setText("Measure");
isMeasuring = false;
} else {
// Start
double freq = spinFreq->value();
logWidget->append(QString(">> Requesting Measure (m %1)...").arg(freq));
serial->write(QString("m %1\n").arg(freq).toUtf8());
measureBtn->setText("Stop");
isMeasuring = true;
}
}
void MainWindow::handleSerialData() {
while (serial->canReadLine()) {
QByteArray line = serial->readLine();

View File

@ -1,4 +1,4 @@
// File: host/src/MainWindow.h
// host/src/MainWindow.h
#pragma once
#include <QMainWindow>
@ -36,6 +36,7 @@ private slots:
void checkDeviceId();
void runCalibration();
void startSweep();
void toggleMeasurement();
private:
void setupUi();
@ -57,4 +58,8 @@ private:
QPushButton *checkIdBtn;
QPushButton *calibrateBtn;
QPushButton *sweepBtn;
QPushButton *measureBtn;
QDoubleSpinBox *spinFreq;
bool isMeasuring = false;
};

94
main.c
View File

@ -1,4 +1,4 @@
// File: main.c
// main.c
#include <stdio.h>
#include <math.h>
#include <string.h>
@ -84,7 +84,7 @@ void AD5940ImpedanceStructInit(void)
pImpedanceCfg->SeqStartAddr = 0;
pImpedanceCfg->MaxSeqLen = 512;
pImpedanceCfg->RcalVal = 10000.0;
pImpedanceCfg->RcalVal = 100.0;
pImpedanceCfg->RtiaVal = 200.0;
pImpedanceCfg->SinFreq = 1000.0;
pImpedanceCfg->FifoThresh = 6;
@ -96,7 +96,7 @@ void AD5940ImpedanceStructInit(void)
pImpedanceCfg->DswitchSel = SWD_CE0;
pImpedanceCfg->PswitchSel = SWP_CE0;
pImpedanceCfg->NswitchSel = SWN_SE0;
pImpedanceCfg->TswitchSel = SWT_TRTIA;
pImpedanceCfg->TswitchSel = SWT_SE0LOAD;
pImpedanceCfg->HstiaRtiaSel = HSTIARTIA_200;
pImpedanceCfg->BiasVolt = 0.0;
@ -196,15 +196,82 @@ void process_command() {
printf("CHIP_ID:0x%04X\n", id);
}
else if (cmd == 'c') {
// Calibration: Run a single measurement at 1kHz
pCfg->SweepCfg.SweepEn = bFALSE;
pCfg->SinFreq = 1000.0f;
pCfg->NumOfData = 1; // Single Shot
// 1. CRITICAL FIX: Force System to 16MHz Low Power Mode
// This prevents the 32MHz post-sweep state from corrupting calibration timing
AD5940_HPModeEn(bFALSE);
if(AppIMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) {
AppIMPCtrl(IMPCTRL_START, 0);
// 2. Reset Analog Blocks to ensure clean state
AD5940_AFECtrlS(AFECTRL_ALL, bFALSE);
// 3. Disable and Reset the FIFO to stop "DATA" interrupts
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);
// 4. Clear any pending interrupts
AD5940_INTCClrFlag(AFEINTSRC_ALLINT);
// 5. Perform ADC Calibration (Offset)
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);
// 6. Configure HSDAC to Low Gain explicitly
HSDACCfg_Type hsdac_cfg;
hsdac_cfg.ExcitBufGain = EXCITBUFGAIN_0P25;
hsdac_cfg.HsDacGain = HSDACGAIN_0P2;
hsdac_cfg.HsDacUpdateRate = 7;
AD5940_HSDacCfgS(&hsdac_cfg);
// 7. Run 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;
// CRITICAL FIX: Explicitly OPEN the DE0 switches.
// memset set them to 0 (50 Ohm / 0 Ohm), causing the 475 Ohm error.
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);
// Optional: Update global config
// pCfg->RtiaVal = Res.Magnitude;
} else {
printf("ERROR: Init Failed\n");
printf("Calibration Failed\n");
}
}
else if (cmd == 'm') {
@ -215,6 +282,7 @@ void process_command() {
pCfg->SweepCfg.SweepEn = bFALSE;
pCfg->SinFreq = freq;
pCfg->NumOfData = -1; // Continuous
pCfg->bParaChanged = bTRUE; // Force sequence regeneration
if(AppIMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) {
AppIMPCtrl(IMPCTRL_START, 0);
@ -234,6 +302,7 @@ void process_command() {
pCfg->SweepCfg.SweepPoints = steps;
pCfg->SweepCfg.SweepLog = bTRUE;
pCfg->NumOfData = steps; // Stop after sweep
pCfg->bParaChanged = bTRUE; // Force sequence regeneration
if(AppIMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) {
AppIMPCtrl(IMPCTRL_START, 0);
@ -241,6 +310,11 @@ void process_command() {
printf("ERROR: Init Failed\n");
}
}
else if (cmd == 'x') {
// Stop Measurement
AppIMPCtrl(IMPCTRL_STOPNOW, 0);
printf("STOPPED\n");
}
else if (cmd == 'z') {
// Full System Reset
watchdog_reboot(0, 0, 0);