working again a bit
This commit is contained in:
parent
5723e89a1a
commit
794f71ccaf
|
|
@ -6,7 +6,7 @@ build
|
|||
*.swp
|
||||
*.cmake
|
||||
requirements.txt
|
||||
ad5940.*
|
||||
ad5940
|
||||
pico_sdk_import.cmake
|
||||
build*
|
||||
*.png
|
||||
|
|
|
|||
231
Impedance.c
231
Impedance.c
|
|
@ -1,9 +1,9 @@
|
|||
// File: Impedance.c
|
||||
#include "ad5940.h"
|
||||
#include <stdio.h>
|
||||
#include "string.h"
|
||||
#include "math.h"
|
||||
#include "Impedance.h"
|
||||
#include "ad5940.h"
|
||||
#include "math.h"
|
||||
#include "string.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define AD5940ERR_STOP 10
|
||||
|
||||
|
|
@ -14,8 +14,7 @@
|
|||
/* Forward declaration */
|
||||
AD5940Err AppIMPCheckFreq(float freq);
|
||||
|
||||
AppIMPCfg_Type AppIMPCfg =
|
||||
{
|
||||
AppIMPCfg_Type AppIMPCfg = {
|
||||
.bParaChanged = bFALSE,
|
||||
.SeqStartAddr = 0,
|
||||
.MaxSeqLen = 0,
|
||||
|
|
@ -85,7 +84,8 @@ AppIMPCfg_Type AppIMPCfg =
|
|||
* @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;
|
||||
|
|
@ -95,7 +95,8 @@ void AppIMPConfigureSweep(float start, float stop, float ppd) {
|
|||
// 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
|
||||
if (decades < 0)
|
||||
decades = -decades; // Handle sweep down if needed
|
||||
|
||||
uint32_t points = (uint32_t)(decades * ppd) + 1;
|
||||
AppIMPCfg.SweepCfg.SweepPoints = points;
|
||||
|
|
@ -112,7 +113,8 @@ void AppIMPConfigureSweep(float start, float stop, float ppd) {
|
|||
|
||||
void AppIMPCleanup(void) {
|
||||
// Ensure chip is awake before sending commands
|
||||
if(AD5940_WakeUp(10) > 10) return;
|
||||
if (AD5940_WakeUp(10) > 10)
|
||||
return;
|
||||
|
||||
// Stop Sequencer and Wakeup Timer
|
||||
AD5940_WUPTCtrl(bFALSE);
|
||||
|
|
@ -152,22 +154,17 @@ void AppIMPCalibrateLFO(void) {
|
|||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
int32_t AppIMPGetCfg(void *pCfg)
|
||||
{
|
||||
if(pCfg)
|
||||
{
|
||||
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:
|
||||
{
|
||||
int32_t AppIMPCtrl(uint32_t Command, void *pPara) {
|
||||
switch (Command) {
|
||||
case IMPCTRL_START: {
|
||||
// Configure interrupts and trigger the first sequence manually
|
||||
AD5940_WUPTCtrl(bFALSE);
|
||||
|
||||
|
|
@ -179,16 +176,17 @@ int32_t AppIMPCtrl(uint32_t Command, void *pPara)
|
|||
AppIMPCfg.StopRequired = bFALSE;
|
||||
|
||||
// Reset Sweep State for subsequent sweeps
|
||||
if(AppIMPCfg.SweepCfg.SweepEn)
|
||||
{
|
||||
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
|
||||
// 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)
|
||||
// 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
|
||||
|
|
@ -198,29 +196,27 @@ int32_t AppIMPCtrl(uint32_t Command, void *pPara)
|
|||
AD5940_SEQMmrTrig(SEQID_0);
|
||||
break;
|
||||
}
|
||||
case IMPCTRL_STOPNOW:
|
||||
{
|
||||
if(AD5940_WakeUp(10) > 10) return AD5940ERR_WAKEUP;
|
||||
case IMPCTRL_STOPNOW: {
|
||||
if (AD5940_WakeUp(10) > 10)
|
||||
return AD5940ERR_WAKEUP;
|
||||
AD5940_WUPTCtrl(bFALSE);
|
||||
AD5940_SEQCtrlS(bFALSE);
|
||||
break;
|
||||
}
|
||||
case IMPCTRL_STOPSYNC:
|
||||
{
|
||||
case IMPCTRL_STOPSYNC: {
|
||||
AppIMPCfg.StopRequired = bTRUE;
|
||||
break;
|
||||
}
|
||||
case IMPCTRL_GETFREQ:
|
||||
{
|
||||
if(pPara == 0) return AD5940ERR_PARA;
|
||||
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:
|
||||
{
|
||||
case IMPCTRL_SHUTDOWN: {
|
||||
AppIMPCtrl(IMPCTRL_STOPNOW, 0);
|
||||
AFERefCfg_Type aferef_cfg;
|
||||
LPLoopCfg_Type lp_loop;
|
||||
|
|
@ -237,8 +233,7 @@ int32_t AppIMPCtrl(uint32_t Command, void *pPara)
|
|||
return AD5940ERR_OK;
|
||||
}
|
||||
|
||||
float AppIMPGetCurrFreq(void)
|
||||
{
|
||||
float AppIMPGetCurrFreq(void) {
|
||||
if (AppIMPCfg.SweepCfg.SweepEn == bTRUE)
|
||||
return AppIMPCfg.FreqofData;
|
||||
else
|
||||
|
|
@ -246,8 +241,7 @@ float AppIMPGetCurrFreq(void)
|
|||
}
|
||||
|
||||
/* Generate Initialization Sequence */
|
||||
static AD5940Err AppIMPSeqCfgGen(void)
|
||||
{
|
||||
static AD5940Err AppIMPSeqCfgGen(void) {
|
||||
AD5940Err error = AD5940ERR_OK;
|
||||
const uint32_t *pSeqCmd;
|
||||
uint32_t SeqLen;
|
||||
|
|
@ -298,34 +292,28 @@ static AD5940Err AppIMPSeqCfgGen(void)
|
|||
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)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
// Configure DSP and ADC
|
||||
dsp_cfg.ADCBaseCfg.ADCMuxN = ADCMUXN_HSTIA_N;
|
||||
|
|
@ -349,30 +337,28 @@ static AD5940Err AppIMPSeqCfgGen(void)
|
|||
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_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)
|
||||
{
|
||||
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
|
||||
} 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;
|
||||
|
|
@ -407,9 +393,10 @@ static AD5940Err AppIMPSeqMeasureGen(void)
|
|||
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_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);
|
||||
|
|
@ -470,9 +457,10 @@ static AD5940Err AppIMPSeqMeasureGen(void)
|
|||
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_AFECtrlS(AFECTRL_HSTIAPWR | AFECTRL_INAMPPWR | AFECTRL_EXTBUFPWR |
|
||||
AFECTRL_WG | AFECTRL_DACREFPWR | AFECTRL_HSDACPWR |
|
||||
AFECTRL_SINC2NOTCH,
|
||||
bFALSE);
|
||||
AD5940_SEQGpioCtrlS(0);
|
||||
|
||||
AD5940_SEQGenInsert(SEQ_STOP());
|
||||
|
|
@ -480,21 +468,19 @@ static AD5940Err AppIMPSeqMeasureGen(void)
|
|||
error = AD5940_SEQGenFetchSeq(&pSeqCmd, &SeqLen);
|
||||
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
|
||||
} 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;
|
||||
|
|
@ -536,7 +522,8 @@ AD5940Err AppIMPCheckFreq(float freq)
|
|||
|
||||
// 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];
|
||||
|
||||
|
|
@ -551,13 +538,13 @@ AD5940Err AppIMPCheckFreq(float freq)
|
|||
return AD5940ERR_OK;
|
||||
}
|
||||
|
||||
int32_t AppIMPInit(uint32_t *pBuffer, uint32_t BufferSize)
|
||||
{
|
||||
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);
|
||||
|
|
@ -580,17 +567,20 @@ int32_t AppIMPInit(uint32_t *pBuffer, uint32_t BufferSize)
|
|||
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;
|
||||
if (error != AD5940ERR_OK)
|
||||
return error;
|
||||
|
||||
error = AppIMPSeqMeasureGen();
|
||||
if(error != AD5940ERR_OK) return error;
|
||||
if (error != AD5940ERR_OK)
|
||||
return error;
|
||||
|
||||
AppIMPCfg.bParaChanged = bFALSE;
|
||||
}
|
||||
|
|
@ -626,25 +616,20 @@ int32_t AppIMPInit(uint32_t *pBuffer, uint32_t BufferSize)
|
|||
return AD5940ERR_OK;
|
||||
}
|
||||
|
||||
int32_t AppIMPRegModify(int32_t * const pData, uint32_t *pDataCount)
|
||||
{
|
||||
if(AppIMPCfg.NumOfData > 0)
|
||||
{
|
||||
int32_t AppIMPRegModify(int32_t *const pData, uint32_t *pDataCount) {
|
||||
if (AppIMPCfg.NumOfData > 0) {
|
||||
AppIMPCfg.FifoDataCount += *pDataCount / 6;
|
||||
if(AppIMPCfg.FifoDataCount >= AppIMPCfg.NumOfData)
|
||||
{
|
||||
if (AppIMPCfg.FifoDataCount >= AppIMPCfg.NumOfData) {
|
||||
AD5940_WUPTCtrl(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);
|
||||
|
||||
|
|
@ -654,8 +639,7 @@ int32_t AppIMPRegModify(int32_t * const pData, uint32_t *pDataCount)
|
|||
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;
|
||||
|
||||
|
|
@ -664,17 +648,14 @@ int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount)
|
|||
|
||||
*pDataCount = 0;
|
||||
|
||||
for(uint32_t i=0; i<DataCount; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < DataCount; i++) {
|
||||
pData[i] &= 0x3ffff;
|
||||
if(pData[i]&(1L<<17))
|
||||
{
|
||||
if (pData[i] & (1L << 17)) {
|
||||
pData[i] |= 0xfffc0000;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32_t i=0; i<ImpResCount; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < ImpResCount; i++) {
|
||||
iImpCar_Type *pDftRcal, *pDftI, *pDftV;
|
||||
|
||||
pDftRcal = pSrcData++;
|
||||
|
|
@ -685,10 +666,12 @@ int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount)
|
|||
float MagV, PhaseV;
|
||||
float ZMag, ZPhase;
|
||||
|
||||
MagI = sqrt((float)pDftI->Real*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
|
||||
|
|
@ -699,8 +682,10 @@ int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount)
|
|||
|
||||
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;
|
||||
|
|
@ -708,8 +693,7 @@ int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount)
|
|||
*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,15 +702,15 @@ 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;
|
||||
if (AD5940_WakeUp(10) > 10)
|
||||
return AD5940ERR_WAKEUP;
|
||||
AD5940_SleepKeyCtrlS(SLPKEY_LOCK);
|
||||
|
||||
uint32_t IntFlag = AD5940_INTCGetFlag(AFEINTC_1);
|
||||
|
|
@ -747,31 +731,27 @@ int32_t AppIMPISR(void *pBuff, uint32_t *pCount)
|
|||
return AD5940ERR_FIFO;
|
||||
}
|
||||
|
||||
if(IntFlag & AFEINTSRC_ENDSEQ)
|
||||
{
|
||||
if (IntFlag & AFEINTSRC_ENDSEQ) {
|
||||
int timeout = 200;
|
||||
while(AD5940_FIFOGetCnt() < 6 && timeout-- > 0)
|
||||
{
|
||||
while (AD5940_FIFOGetCnt() < 6 && timeout-- > 0) {
|
||||
AD5940_Delay10us(10);
|
||||
}
|
||||
|
||||
FifoCnt = (AD5940_FIFOGetCnt() / 6) * 6;
|
||||
if(FifoCnt > BuffCount) FifoCnt = BuffCount;
|
||||
if (FifoCnt > BuffCount)
|
||||
FifoCnt = BuffCount;
|
||||
|
||||
AD5940_FIFORd((uint32_t *)pBuff, FifoCnt);
|
||||
AD5940_INTCClrFlag(AFEINTSRC_ENDSEQ);
|
||||
|
||||
if (FifoCnt > 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
|
@ -795,10 +775,9 @@ int32_t AppIMPISR(void *pBuff, uint32_t *pCount)
|
|||
*pCount = FifoCnt;
|
||||
}
|
||||
|
||||
if (status == AD5940ERR_STOP) return AD5940ERR_STOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (status == AD5940ERR_STOP)
|
||||
return AD5940ERR_STOP;
|
||||
} else {
|
||||
AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK);
|
||||
*pCount = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ void AD5940ImpedanceStructInit(void) {
|
|||
|
||||
// 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->TswitchSel = SWT_SE0LOAD; // Restoring Legacy Config (Commit
|
||||
// 4266c4b). Connects SE0 to T-Node.
|
||||
|
||||
pImpedanceCfg->HstiaRtiaSel = GetHSTIARtia(ConfigHstiaVal);
|
||||
pImpedanceCfg->BiasVolt = 0.0;
|
||||
|
|
@ -110,7 +111,8 @@ void Config_LPLOOP(float bias_mv) {
|
|||
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;
|
||||
if (vbias_code > 4095)
|
||||
vbias_code = 4095;
|
||||
|
||||
LPDACCfg_Type lpdac_cfg;
|
||||
lpdac_cfg.LpdacSel = LPDAC0;
|
||||
|
|
@ -119,7 +121,8 @@ void Config_LPLOOP(float bias_mv) {
|
|||
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.LpDacSW = LPDACSW_VBIAS2LPPA | LPDACSW_VBIAS2PIN |
|
||||
LPDACSW_VZERO2LPTIA | LPDACSW_VZERO2PIN;
|
||||
lpdac_cfg.LpDacRef = LPDACREF_2P5;
|
||||
lpdac_cfg.LpDacSrc = LPDACSRC_MMR;
|
||||
lpdac_cfg.PowerEn = bTRUE;
|
||||
|
|
@ -135,7 +138,8 @@ void Config_LPLOOP(float bias_mv) {
|
|||
lp_loop.LpAmpCfg.LpTiaRtia = GetLPTIARtia(ConfigLptiaVal);
|
||||
|
||||
// Base Switches
|
||||
lp_loop.LpAmpCfg.LpTiaSW = LPTIASW(5)|LPTIASW(2)|LPTIASW(4)|LPTIASW(12)|LPTIASW(13);
|
||||
lp_loop.LpAmpCfg.LpTiaSW =
|
||||
LPTIASW(5) | LPTIASW(2) | LPTIASW(4) | LPTIASW(12) | LPTIASW(13);
|
||||
|
||||
// Apply Short Option
|
||||
if (GlobalShortRe0Se0) {
|
||||
|
|
@ -342,18 +346,22 @@ void Do_WaveGen(float freq) {
|
|||
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);
|
||||
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.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_EXTBUFPWR | AFECTRL_INAMPPWR | AFECTRL_HSTIAPWR |
|
||||
AFECTRL_HSDACPWR,
|
||||
bTRUE);
|
||||
AD5940_AFECtrlS(AFECTRL_WG, bTRUE);
|
||||
AD5940_AFECtrlS(AFECTRL_DCBUFPWR, bTRUE);
|
||||
AD5940_AFEPwrBW(AFEPWR_LP, AFEBW_250KHZ);
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@
|
|||
|
||||
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);
|
||||
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;
|
||||
|
|
@ -20,8 +23,10 @@ void Routine_CalibrateLFO(void) {
|
|||
}
|
||||
|
||||
void Routine_Measure(float freq) {
|
||||
if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
||||
else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
||||
if (CurrentMode == MODE_AMPEROMETRIC)
|
||||
AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
||||
else if (CurrentMode == MODE_RAMP)
|
||||
AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
||||
CurrentMode = MODE_IMPEDANCE;
|
||||
|
||||
AppIMPCfg_Type *pCfg;
|
||||
|
|
@ -35,6 +40,12 @@ void Routine_Measure(float freq) {
|
|||
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) {
|
||||
|
|
@ -45,8 +56,10 @@ void Routine_Measure(float freq) {
|
|||
}
|
||||
|
||||
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);
|
||||
if (CurrentMode == MODE_AMPEROMETRIC)
|
||||
AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
||||
else if (CurrentMode == MODE_RAMP)
|
||||
AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
||||
CurrentMode = MODE_IMPEDANCE;
|
||||
|
||||
AppIMPCfg_Type *pCfg;
|
||||
|
|
@ -63,6 +76,12 @@ void Routine_Sweep(float start, float end, int steps) {
|
|||
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) {
|
||||
|
|
@ -73,11 +92,14 @@ void Routine_Sweep(float start, float end, int steps) {
|
|||
}
|
||||
|
||||
void Routine_Amperometric(float bias_mv) {
|
||||
if (CurrentMode == MODE_IMPEDANCE) AppIMPCleanup();
|
||||
else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
||||
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);
|
||||
printf(">> Starting Amperometry (Bias: %.1f mV, LP Range: %d)...\n", bias_mv,
|
||||
ConfigLptiaVal);
|
||||
|
||||
AppAMPCfg_Type *pCfg;
|
||||
AppAMPGetCfg(&pCfg);
|
||||
|
|
@ -93,11 +115,15 @@ void Routine_Amperometric(float bias_mv) {
|
|||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
|
|
@ -118,8 +144,10 @@ void Routine_LSV(float start_mv, float end_mv, int steps, int duration_ms) {
|
|||
}
|
||||
|
||||
void Routine_CalibrateSystem(void) {
|
||||
if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
||||
else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
||||
if (CurrentMode == MODE_AMPEROMETRIC)
|
||||
AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
||||
else if (CurrentMode == MODE_RAMP)
|
||||
AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
||||
CurrentMode = MODE_IMPEDANCE;
|
||||
|
||||
AppIMPCfg_Type *pCfg;
|
||||
|
|
@ -160,7 +188,8 @@ void Routine_CalibrateSystem(void) {
|
|||
|
||||
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);
|
||||
printf("Calibrated LPTIA: Mag = %f Ohm, Phase = %f\n", LpRes.Magnitude,
|
||||
LpRes.Phase);
|
||||
CalibratedLptiaVal = LpRes.Magnitude;
|
||||
} else {
|
||||
printf("LPTIA Calibration Failed\n");
|
||||
|
|
@ -194,7 +223,8 @@ void Routine_CalibrateSystem(void) {
|
|||
|
||||
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);
|
||||
printf("Calibrated HSTIA: Mag = %f Ohm, Phase = %f\n", HsRes.Magnitude,
|
||||
HsRes.Phase);
|
||||
CalibratedHstiaVal = HsRes.Magnitude;
|
||||
} else {
|
||||
printf("HSTIA Calibration Failed\n");
|
||||
|
|
|
|||
|
|
@ -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** ->>
|
||||
|
|
@ -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 <stdio.h>
|
||||
|
||||
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
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
* */
|
||||
|
|
@ -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 <stdio.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
* */
|
||||
|
|
@ -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 <stdio.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
* */
|
||||
|
|
@ -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;i<DataCount;i++)
|
||||
{
|
||||
printf("RzMag: %f Ohm , RzPhase: %f \n",pImp[i].Magnitude,pImp[i].Phase*180/MATH_PI);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t AD5940PlatformCfg(void)
|
||||
{
|
||||
CLKCfg_Type clk_cfg;
|
||||
FIFOCfg_Type fifo_cfg;
|
||||
AGPIOCfg_Type gpio_cfg;
|
||||
|
||||
/* Use hardware reset */
|
||||
AD5940_HWReset();
|
||||
AD5940_Initialize();
|
||||
/* 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 = 6;
|
||||
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_DATAFIFOTHRESH, bTRUE);
|
||||
AD5940_INTCClrFlag(AFEINTSRC_ALLINT);
|
||||
/* Step4: Reconfigure GPIO */
|
||||
gpio_cfg.FuncSet = GP0_INT|GP1_SLEEP|GP2_SYNC;
|
||||
gpio_cfg.InputEnSet = 0;
|
||||
gpio_cfg.OutputEnSet = AGPIO_Pin0|AGPIO_Pin1|AGPIO_Pin2;
|
||||
gpio_cfg.OutVal = 0;
|
||||
gpio_cfg.PullEnSet = 0;
|
||||
AD5940_AGPIOCfg(&gpio_cfg);
|
||||
AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); /* Allow AFE to enter sleep mode. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AD5940ImpedanceStructInit(void)
|
||||
{
|
||||
AppIMPCfg_Type *pImpedanceCfg;
|
||||
|
||||
AppIMPGetCfg(&pImpedanceCfg);
|
||||
/* Step1: configure initialization sequence Info */
|
||||
pImpedanceCfg->SeqStartAddr = 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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 <stdio.h>
|
||||
#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");
|
||||
}
|
||||
|
||||
|
|
@ -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;i<DataCount;i++)
|
||||
{
|
||||
printf("RzMag: %f Ohm , RzPhase: %f \n",pImp[i].Magnitude,pImp[i].Phase*180/MATH_PI);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t AD5940PlatformCfg(void)
|
||||
{
|
||||
CLKCfg_Type clk_cfg;
|
||||
FIFOCfg_Type fifo_cfg;
|
||||
AGPIOCfg_Type gpio_cfg;
|
||||
|
||||
/* Use hardware reset */
|
||||
AD5940_HWReset();
|
||||
AD5940_Initialize();
|
||||
/* 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_DATAFIFOTHRESH, bTRUE);
|
||||
AD5940_INTCClrFlag(AFEINTSRC_ALLINT);
|
||||
/* Step4: Reconfigure GPIO */
|
||||
gpio_cfg.FuncSet = GP0_INT|GP1_SLEEP|GP2_SYNC;
|
||||
gpio_cfg.InputEnSet = 0;
|
||||
gpio_cfg.OutputEnSet = AGPIO_Pin0|AGPIO_Pin1|AGPIO_Pin2;
|
||||
gpio_cfg.OutVal = 0;
|
||||
gpio_cfg.PullEnSet = 0;
|
||||
AD5940_AGPIOCfg(&gpio_cfg);
|
||||
AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK); /* Allow AFE to enter sleep mode. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AD5940ImpedanceStructInit(void)
|
||||
{
|
||||
AppIMPCfg_Type *pImpedanceCfg;
|
||||
|
||||
AppIMPGetCfg(&pImpedanceCfg);
|
||||
/* Step1: configure initialization sequence Info */
|
||||
pImpedanceCfg->SeqStartAddr = 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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 <stdio.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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)/" <SOURCE_DIR>/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)
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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" <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 20x20 "$IOS_DIR/Icon-20.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 40x40 "$IOS_DIR/Icon-20@2x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 60x60 "$IOS_DIR/Icon-20@3x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 29x29 "$IOS_DIR/Icon-29.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 58x58 "$IOS_DIR/Icon-29@2x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 87x87 "$IOS_DIR/Icon-29@3x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 40x40 "$IOS_DIR/Icon-40.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 80x80 "$IOS_DIR/Icon-40@2x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 120x120 "$IOS_DIR/Icon-40@3x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 120x120 "$IOS_DIR/Icon-60@2x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 180x180 "$IOS_DIR/Icon-60@3x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 76x76 "$IOS_DIR/Icon-76.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 152x152 "$IOS_DIR/Icon-76@2x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 167x167 "$IOS_DIR/Icon-83.5@2x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -scale 1024x1024 "$IOS_DIR/Icon-1024.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 20x20 "$IOS_DIR/Icon-20.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 40x40 "$IOS_DIR/Icon-20@2x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 60x60 "$IOS_DIR/Icon-20@3x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 29x29 "$IOS_DIR/Icon-29.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 58x58 "$IOS_DIR/Icon-29@2x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 87x87 "$IOS_DIR/Icon-29@3x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 40x40 "$IOS_DIR/Icon-40.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 80x80 "$IOS_DIR/Icon-40@2x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 120x120 "$IOS_DIR/Icon-40@3x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 120x120 "$IOS_DIR/Icon-60@2x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 180x180 "$IOS_DIR/Icon-60@3x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 76x76 "$IOS_DIR/Icon-76.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 152x152 "$IOS_DIR/Icon-76@2x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 167x167 "$IOS_DIR/Icon-83.5@2x.png"
|
||||
"$MAGICK_BIN" "$SOURCE" -sample 1024x1024 "$IOS_DIR/Icon-1024.png"
|
||||
|
||||
cat > "$IOS_DIR/Contents.json" <<EOF
|
||||
{
|
||||
|
|
@ -133,3 +140,5 @@ cat > "$IOS_DIR/Contents.json" <<EOF
|
|||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "[SUCCESS] All platform icons generated."
|
||||
|
|
@ -0,0 +1,795 @@
|
|||
// File: Impedance.c
|
||||
#include "ad5940.h"
|
||||
#include <stdio.h>
|
||||
#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; i<DataCount; i++)
|
||||
{
|
||||
pData[i] &= 0x3ffff;
|
||||
if(pData[i]&(1L<<17))
|
||||
{
|
||||
pData[i] |= 0xfffc0000;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32_t i=0; i<ImpResCount; i++)
|
||||
{
|
||||
iImpCar_Type *pDftRcal, *pDftI, *pDftV;
|
||||
|
||||
pDftRcal = pSrcData++;
|
||||
pDftI = pSrcData++;
|
||||
pDftV = pSrcData++;
|
||||
|
||||
float MagI, PhaseI;
|
||||
float MagV, PhaseV;
|
||||
float ZMag, ZPhase;
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,375 @@
|
|||
// File: main.c
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#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<DataCount;i++)
|
||||
{
|
||||
float mag = pImp[i].Magnitude;
|
||||
float phase = pImp[i].Phase;
|
||||
|
||||
float real = mag * cosf(phase);
|
||||
float imag = mag * sinf(phase);
|
||||
|
||||
printf("DATA,%.2f,%.4f,%.4f,%.4f,%.4f\n",
|
||||
freq,
|
||||
mag,
|
||||
phase * 180.0f / MATH_PI,
|
||||
real,
|
||||
imag
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// High-Level Routines
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void Routine_CalibrateLFO(void) {
|
||||
printf(">> 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;
|
||||
}
|
||||
Loading…
Reference in New Issue