From 98bd3534eacd9b7ab77a5c70008ab73ca47272ca Mon Sep 17 00:00:00 2001 From: pszsh Date: Mon, 26 Jan 2026 14:07:55 -0800 Subject: [PATCH] it works (just doesn't work very well) but the measurements are now actually accurate at least --- .drv.min.h | 262 ---------------------------------------- .gitignore | 3 +- Impedance.c | 58 ++++----- host/src/MainWindow.cpp | 71 ++++++++--- host/src/MainWindow.h | 7 +- main.c | 94 ++++++++++++-- 6 files changed, 174 insertions(+), 321 deletions(-) delete mode 100644 .drv.min.h diff --git a/.drv.min.h b/.drv.min.h deleted file mode 100644 index 09aa109..0000000 --- a/.drv.min.h +++ /dev/null @@ -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 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 96c3b29..c352adf 100644 --- a/.gitignore +++ b/.gitignore @@ -6,12 +6,13 @@ build *.swp *.cmake requirements.txt -ad5940.c +ad5940.* pico_sdk_import.cmake build* *.png icons/ *.pdf +examples/ build/ build_android/ diff --git a/Impedance.c b/Impedance.c index fd1b1fc..e92b0cd 100644 --- a/Impedance.c +++ b/Impedance.c @@ -1,4 +1,4 @@ -// File: Impedance.c +// Impedance.c #include "ad5940.h" #include #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); diff --git a/host/src/MainWindow.cpp b/host/src/MainWindow.cpp index b5edfda..9326420 100644 --- a/host/src/MainWindow.cpp +++ b/host/src/MainWindow.cpp @@ -1,4 +1,4 @@ -// File: host/src/MainWindow.cpp +// host/src/MainWindow.cpp #include "MainWindow.h" #include #include @@ -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 \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,15 +123,28 @@ 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()); - if (!serial->isOpen()) { - connectToPort(); - } + + // 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(); } } } @@ -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(); diff --git a/host/src/MainWindow.h b/host/src/MainWindow.h index 66a1ecf..3bcde90 100644 --- a/host/src/MainWindow.h +++ b/host/src/MainWindow.h @@ -1,4 +1,4 @@ -// File: host/src/MainWindow.h +// host/src/MainWindow.h #pragma once #include @@ -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; }; \ No newline at end of file diff --git a/main.c b/main.c index d06f10d..2d1dc2e 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -// File: main.c +// main.c #include #include #include @@ -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); + + // 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); - if(AppIMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { - AppIMPCtrl(IMPCTRL_START, 0); + 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);