working again a bit
This commit is contained in:
parent
5723e89a1a
commit
794f71ccaf
|
|
@ -6,7 +6,7 @@ build
|
||||||
*.swp
|
*.swp
|
||||||
*.cmake
|
*.cmake
|
||||||
requirements.txt
|
requirements.txt
|
||||||
ad5940.*
|
ad5940
|
||||||
pico_sdk_import.cmake
|
pico_sdk_import.cmake
|
||||||
build*
|
build*
|
||||||
*.png
|
*.png
|
||||||
|
|
|
||||||
231
Impedance.c
231
Impedance.c
|
|
@ -1,9 +1,9 @@
|
||||||
// File: Impedance.c
|
// File: Impedance.c
|
||||||
#include "ad5940.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "string.h"
|
|
||||||
#include "math.h"
|
|
||||||
#include "Impedance.h"
|
#include "Impedance.h"
|
||||||
|
#include "ad5940.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define AD5940ERR_STOP 10
|
#define AD5940ERR_STOP 10
|
||||||
|
|
||||||
|
|
@ -14,8 +14,7 @@
|
||||||
/* Forward declaration */
|
/* Forward declaration */
|
||||||
AD5940Err AppIMPCheckFreq(float freq);
|
AD5940Err AppIMPCheckFreq(float freq);
|
||||||
|
|
||||||
AppIMPCfg_Type AppIMPCfg =
|
AppIMPCfg_Type AppIMPCfg = {
|
||||||
{
|
|
||||||
.bParaChanged = bFALSE,
|
.bParaChanged = bFALSE,
|
||||||
.SeqStartAddr = 0,
|
.SeqStartAddr = 0,
|
||||||
.MaxSeqLen = 0,
|
.MaxSeqLen = 0,
|
||||||
|
|
@ -85,7 +84,8 @@ AppIMPCfg_Type AppIMPCfg =
|
||||||
* @param ppd Points Per Decade (Resolution)
|
* @param ppd Points Per Decade (Resolution)
|
||||||
*/
|
*/
|
||||||
void AppIMPConfigureSweep(float start, float stop, float ppd) {
|
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.SweepEn = bTRUE;
|
||||||
AppIMPCfg.SweepCfg.SweepStart = start;
|
AppIMPCfg.SweepCfg.SweepStart = start;
|
||||||
|
|
@ -95,7 +95,8 @@ void AppIMPConfigureSweep(float start, float stop, float ppd) {
|
||||||
// Calculate total points based on decades and PPD
|
// Calculate total points based on decades and PPD
|
||||||
// Formula: Points = (Decades * PPD) + 1
|
// Formula: Points = (Decades * PPD) + 1
|
||||||
float decades = log10f(stop) - log10f(start);
|
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;
|
uint32_t points = (uint32_t)(decades * ppd) + 1;
|
||||||
AppIMPCfg.SweepCfg.SweepPoints = points;
|
AppIMPCfg.SweepCfg.SweepPoints = points;
|
||||||
|
|
@ -112,7 +113,8 @@ void AppIMPConfigureSweep(float start, float stop, float ppd) {
|
||||||
|
|
||||||
void AppIMPCleanup(void) {
|
void AppIMPCleanup(void) {
|
||||||
// Ensure chip is awake before sending commands
|
// Ensure chip is awake before sending commands
|
||||||
if(AD5940_WakeUp(10) > 10) return;
|
if (AD5940_WakeUp(10) > 10)
|
||||||
|
return;
|
||||||
|
|
||||||
// Stop Sequencer and Wakeup Timer
|
// Stop Sequencer and Wakeup Timer
|
||||||
AD5940_WUPTCtrl(bFALSE);
|
AD5940_WUPTCtrl(bFALSE);
|
||||||
|
|
@ -152,22 +154,17 @@ void AppIMPCalibrateLFO(void) {
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
int32_t AppIMPGetCfg(void *pCfg)
|
int32_t AppIMPGetCfg(void *pCfg) {
|
||||||
{
|
if (pCfg) {
|
||||||
if(pCfg)
|
|
||||||
{
|
|
||||||
*(AppIMPCfg_Type **)pCfg = &AppIMPCfg;
|
*(AppIMPCfg_Type **)pCfg = &AppIMPCfg;
|
||||||
return AD5940ERR_OK;
|
return AD5940ERR_OK;
|
||||||
}
|
}
|
||||||
return AD5940ERR_PARA;
|
return AD5940ERR_PARA;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t AppIMPCtrl(uint32_t Command, void *pPara)
|
int32_t AppIMPCtrl(uint32_t Command, void *pPara) {
|
||||||
{
|
switch (Command) {
|
||||||
switch (Command)
|
case IMPCTRL_START: {
|
||||||
{
|
|
||||||
case IMPCTRL_START:
|
|
||||||
{
|
|
||||||
// Configure interrupts and trigger the first sequence manually
|
// Configure interrupts and trigger the first sequence manually
|
||||||
AD5940_WUPTCtrl(bFALSE);
|
AD5940_WUPTCtrl(bFALSE);
|
||||||
|
|
||||||
|
|
@ -179,16 +176,17 @@ int32_t AppIMPCtrl(uint32_t Command, void *pPara)
|
||||||
AppIMPCfg.StopRequired = bFALSE;
|
AppIMPCfg.StopRequired = bFALSE;
|
||||||
|
|
||||||
// Reset Sweep State for subsequent sweeps
|
// Reset Sweep State for subsequent sweeps
|
||||||
if(AppIMPCfg.SweepCfg.SweepEn)
|
if (AppIMPCfg.SweepCfg.SweepEn) {
|
||||||
{
|
|
||||||
AppIMPCfg.SweepCfg.SweepIndex = 0;
|
AppIMPCfg.SweepCfg.SweepIndex = 0;
|
||||||
AppIMPCfg.SweepCurrFreq = AppIMPCfg.SweepCfg.SweepStart;
|
AppIMPCfg.SweepCurrFreq = AppIMPCfg.SweepCfg.SweepStart;
|
||||||
AppIMPCfg.FreqofData = 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);
|
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);
|
AD5940_WGFreqCtrlS(AppIMPCfg.SweepCurrFreq, AppIMPCfg.SysClkFreq);
|
||||||
|
|
||||||
// Reset SRAM Wait Times for the Start Frequency
|
// Reset SRAM Wait Times for the Start Frequency
|
||||||
|
|
@ -198,29 +196,27 @@ int32_t AppIMPCtrl(uint32_t Command, void *pPara)
|
||||||
AD5940_SEQMmrTrig(SEQID_0);
|
AD5940_SEQMmrTrig(SEQID_0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IMPCTRL_STOPNOW:
|
case IMPCTRL_STOPNOW: {
|
||||||
{
|
if (AD5940_WakeUp(10) > 10)
|
||||||
if(AD5940_WakeUp(10) > 10) return AD5940ERR_WAKEUP;
|
return AD5940ERR_WAKEUP;
|
||||||
AD5940_WUPTCtrl(bFALSE);
|
AD5940_WUPTCtrl(bFALSE);
|
||||||
AD5940_SEQCtrlS(bFALSE);
|
AD5940_SEQCtrlS(bFALSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IMPCTRL_STOPSYNC:
|
case IMPCTRL_STOPSYNC: {
|
||||||
{
|
|
||||||
AppIMPCfg.StopRequired = bTRUE;
|
AppIMPCfg.StopRequired = bTRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IMPCTRL_GETFREQ:
|
case IMPCTRL_GETFREQ: {
|
||||||
{
|
if (pPara == 0)
|
||||||
if(pPara == 0) return AD5940ERR_PARA;
|
return AD5940ERR_PARA;
|
||||||
if (AppIMPCfg.SweepCfg.SweepEn == bTRUE)
|
if (AppIMPCfg.SweepCfg.SweepEn == bTRUE)
|
||||||
*(float *)pPara = AppIMPCfg.FreqofData;
|
*(float *)pPara = AppIMPCfg.FreqofData;
|
||||||
else
|
else
|
||||||
*(float *)pPara = AppIMPCfg.SinFreq;
|
*(float *)pPara = AppIMPCfg.SinFreq;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IMPCTRL_SHUTDOWN:
|
case IMPCTRL_SHUTDOWN: {
|
||||||
{
|
|
||||||
AppIMPCtrl(IMPCTRL_STOPNOW, 0);
|
AppIMPCtrl(IMPCTRL_STOPNOW, 0);
|
||||||
AFERefCfg_Type aferef_cfg;
|
AFERefCfg_Type aferef_cfg;
|
||||||
LPLoopCfg_Type lp_loop;
|
LPLoopCfg_Type lp_loop;
|
||||||
|
|
@ -237,8 +233,7 @@ int32_t AppIMPCtrl(uint32_t Command, void *pPara)
|
||||||
return AD5940ERR_OK;
|
return AD5940ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
float AppIMPGetCurrFreq(void)
|
float AppIMPGetCurrFreq(void) {
|
||||||
{
|
|
||||||
if (AppIMPCfg.SweepCfg.SweepEn == bTRUE)
|
if (AppIMPCfg.SweepCfg.SweepEn == bTRUE)
|
||||||
return AppIMPCfg.FreqofData;
|
return AppIMPCfg.FreqofData;
|
||||||
else
|
else
|
||||||
|
|
@ -246,8 +241,7 @@ float AppIMPGetCurrFreq(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate Initialization Sequence */
|
/* Generate Initialization Sequence */
|
||||||
static AD5940Err AppIMPSeqCfgGen(void)
|
static AD5940Err AppIMPSeqCfgGen(void) {
|
||||||
{
|
|
||||||
AD5940Err error = AD5940ERR_OK;
|
AD5940Err error = AD5940ERR_OK;
|
||||||
const uint32_t *pSeqCmd;
|
const uint32_t *pSeqCmd;
|
||||||
uint32_t SeqLen;
|
uint32_t SeqLen;
|
||||||
|
|
@ -298,34 +292,28 @@ static AD5940Err AppIMPSeqCfgGen(void)
|
||||||
HsLoopCfg.WgCfg.GainCalEn = bTRUE;
|
HsLoopCfg.WgCfg.GainCalEn = bTRUE;
|
||||||
HsLoopCfg.WgCfg.OffsetCalEn = bTRUE;
|
HsLoopCfg.WgCfg.OffsetCalEn = bTRUE;
|
||||||
|
|
||||||
if(AppIMPCfg.SweepCfg.SweepEn == bTRUE)
|
if (AppIMPCfg.SweepCfg.SweepEn == bTRUE) {
|
||||||
{
|
|
||||||
AppIMPCfg.FreqofData = AppIMPCfg.SweepCfg.SweepStart;
|
AppIMPCfg.FreqofData = AppIMPCfg.SweepCfg.SweepStart;
|
||||||
AppIMPCfg.SweepCurrFreq = AppIMPCfg.SweepCfg.SweepStart;
|
AppIMPCfg.SweepCurrFreq = AppIMPCfg.SweepCfg.SweepStart;
|
||||||
AD5940_SweepNext(&AppIMPCfg.SweepCfg, &AppIMPCfg.SweepNextFreq);
|
AD5940_SweepNext(&AppIMPCfg.SweepCfg, &AppIMPCfg.SweepNextFreq);
|
||||||
sin_freq = AppIMPCfg.SweepCurrFreq;
|
sin_freq = AppIMPCfg.SweepCurrFreq;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
sin_freq = AppIMPCfg.SinFreq;
|
sin_freq = AppIMPCfg.SinFreq;
|
||||||
AppIMPCfg.FreqofData = sin_freq;
|
AppIMPCfg.FreqofData = sin_freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
HsLoopCfg.WgCfg.SinCfg.SinFreqWord = AD5940_WGFreqWordCal(sin_freq, AppIMPCfg.SysClkFreq);
|
HsLoopCfg.WgCfg.SinCfg.SinFreqWord =
|
||||||
HsLoopCfg.WgCfg.SinCfg.SinAmplitudeWord = (uint32_t)(AppIMPCfg.DacVoltPP/800.0f*2047 + 0.5f);
|
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.SinOffsetWord = 0;
|
||||||
HsLoopCfg.WgCfg.SinCfg.SinPhaseWord = 0;
|
HsLoopCfg.WgCfg.SinCfg.SinPhaseWord = 0;
|
||||||
AD5940_HSLoopCfgS(&HsLoopCfg);
|
AD5940_HSLoopCfgS(&HsLoopCfg);
|
||||||
|
|
||||||
// Handle RE0-SE0 Short (SW11 in LPTIASW0)
|
// 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
|
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
|
// Configure DSP and ADC
|
||||||
dsp_cfg.ADCBaseCfg.ADCMuxN = ADCMUXN_HSTIA_N;
|
dsp_cfg.ADCBaseCfg.ADCMuxN = ADCMUXN_HSTIA_N;
|
||||||
|
|
@ -349,30 +337,28 @@ static AD5940Err AppIMPSeqCfgGen(void)
|
||||||
AD5940_DSPCfgS(&dsp_cfg);
|
AD5940_DSPCfgS(&dsp_cfg);
|
||||||
|
|
||||||
// Enable Power for AFE blocks
|
// Enable Power for AFE blocks
|
||||||
AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\
|
AD5940_AFECtrlS(AFECTRL_HSTIAPWR | AFECTRL_INAMPPWR | AFECTRL_EXTBUFPWR |
|
||||||
AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\
|
AFECTRL_WG | AFECTRL_DACREFPWR | AFECTRL_HSDACPWR |
|
||||||
AFECTRL_SINC2NOTCH, bTRUE);
|
AFECTRL_SINC2NOTCH,
|
||||||
|
bTRUE);
|
||||||
|
|
||||||
AD5940_SEQGenInsert(SEQ_STOP());
|
AD5940_SEQGenInsert(SEQ_STOP());
|
||||||
|
|
||||||
error = AD5940_SEQGenFetchSeq(&pSeqCmd, &SeqLen);
|
error = AD5940_SEQGenFetchSeq(&pSeqCmd, &SeqLen);
|
||||||
AD5940_SEQGenCtrl(bFALSE);
|
AD5940_SEQGenCtrl(bFALSE);
|
||||||
if(error == AD5940ERR_OK)
|
if (error == AD5940ERR_OK) {
|
||||||
{
|
|
||||||
AppIMPCfg.InitSeqInfo.SeqId = SEQID_1;
|
AppIMPCfg.InitSeqInfo.SeqId = SEQID_1;
|
||||||
AppIMPCfg.InitSeqInfo.SeqRamAddr = AppIMPCfg.SeqStartAddr;
|
AppIMPCfg.InitSeqInfo.SeqRamAddr = AppIMPCfg.SeqStartAddr;
|
||||||
AppIMPCfg.InitSeqInfo.pSeqCmd = pSeqCmd;
|
AppIMPCfg.InitSeqInfo.pSeqCmd = pSeqCmd;
|
||||||
AppIMPCfg.InitSeqInfo.SeqLen = SeqLen;
|
AppIMPCfg.InitSeqInfo.SeqLen = SeqLen;
|
||||||
AD5940_SEQCmdWrite(AppIMPCfg.InitSeqInfo.SeqRamAddr, pSeqCmd, SeqLen);
|
AD5940_SEQCmdWrite(AppIMPCfg.InitSeqInfo.SeqRamAddr, pSeqCmd, SeqLen);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return error;
|
return error;
|
||||||
return AD5940ERR_OK;
|
return AD5940ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate Measurement Sequence */
|
/* Generate Measurement Sequence */
|
||||||
static AD5940Err AppIMPSeqMeasureGen(void)
|
static AD5940Err AppIMPSeqMeasureGen(void) {
|
||||||
{
|
|
||||||
AD5940Err error = AD5940ERR_OK;
|
AD5940Err error = AD5940ERR_OK;
|
||||||
const uint32_t *pSeqCmd;
|
const uint32_t *pSeqCmd;
|
||||||
uint32_t SeqLen;
|
uint32_t SeqLen;
|
||||||
|
|
@ -407,9 +393,10 @@ static AD5940Err AppIMPSeqMeasureGen(void)
|
||||||
AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N);
|
AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N);
|
||||||
|
|
||||||
// Enable AFE Power and Waveform Generator
|
// Enable AFE Power and Waveform Generator
|
||||||
AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\
|
AD5940_AFECtrlS(AFECTRL_HSTIAPWR | AFECTRL_INAMPPWR | AFECTRL_EXTBUFPWR |
|
||||||
AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\
|
AFECTRL_WG | AFECTRL_DACREFPWR | AFECTRL_HSDACPWR |
|
||||||
AFECTRL_SINC2NOTCH, bTRUE);
|
AFECTRL_SINC2NOTCH,
|
||||||
|
bTRUE);
|
||||||
AD5940_AFECtrlS(AFECTRL_WG | AFECTRL_ADCPWR, bTRUE);
|
AD5940_AFECtrlS(AFECTRL_WG | AFECTRL_ADCPWR, bTRUE);
|
||||||
AD5940_SEQGenInsert(SEQ_WAIT(16 * 2000));
|
AD5940_SEQGenInsert(SEQ_WAIT(16 * 2000));
|
||||||
AD5940_AFECtrlS(AFECTRL_ADCCNV | AFECTRL_DFT, bTRUE);
|
AD5940_AFECtrlS(AFECTRL_ADCCNV | AFECTRL_DFT, bTRUE);
|
||||||
|
|
@ -470,9 +457,10 @@ static AD5940Err AppIMPSeqMeasureGen(void)
|
||||||
AD5940_AFECtrlS(AFECTRL_WG | AFECTRL_ADCPWR, bFALSE);
|
AD5940_AFECtrlS(AFECTRL_WG | AFECTRL_ADCPWR, bFALSE);
|
||||||
|
|
||||||
// Power down AFE blocks
|
// Power down AFE blocks
|
||||||
AD5940_AFECtrlS(AFECTRL_HSTIAPWR|AFECTRL_INAMPPWR|AFECTRL_EXTBUFPWR|\
|
AD5940_AFECtrlS(AFECTRL_HSTIAPWR | AFECTRL_INAMPPWR | AFECTRL_EXTBUFPWR |
|
||||||
AFECTRL_WG|AFECTRL_DACREFPWR|AFECTRL_HSDACPWR|\
|
AFECTRL_WG | AFECTRL_DACREFPWR | AFECTRL_HSDACPWR |
|
||||||
AFECTRL_SINC2NOTCH, bFALSE);
|
AFECTRL_SINC2NOTCH,
|
||||||
|
bFALSE);
|
||||||
AD5940_SEQGpioCtrlS(0);
|
AD5940_SEQGpioCtrlS(0);
|
||||||
|
|
||||||
AD5940_SEQGenInsert(SEQ_STOP());
|
AD5940_SEQGenInsert(SEQ_STOP());
|
||||||
|
|
@ -480,21 +468,19 @@ static AD5940Err AppIMPSeqMeasureGen(void)
|
||||||
error = AD5940_SEQGenFetchSeq(&pSeqCmd, &SeqLen);
|
error = AD5940_SEQGenFetchSeq(&pSeqCmd, &SeqLen);
|
||||||
AD5940_SEQGenCtrl(bFALSE);
|
AD5940_SEQGenCtrl(bFALSE);
|
||||||
|
|
||||||
if(error == AD5940ERR_OK)
|
if (error == AD5940ERR_OK) {
|
||||||
{
|
|
||||||
AppIMPCfg.MeasureSeqInfo.SeqId = SEQID_0;
|
AppIMPCfg.MeasureSeqInfo.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.pSeqCmd = pSeqCmd;
|
||||||
AppIMPCfg.MeasureSeqInfo.SeqLen = SeqLen;
|
AppIMPCfg.MeasureSeqInfo.SeqLen = SeqLen;
|
||||||
AD5940_SEQCmdWrite(AppIMPCfg.MeasureSeqInfo.SeqRamAddr, pSeqCmd, SeqLen);
|
AD5940_SEQCmdWrite(AppIMPCfg.MeasureSeqInfo.SeqRamAddr, pSeqCmd, SeqLen);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return error;
|
return error;
|
||||||
return AD5940ERR_OK;
|
return AD5940ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
AD5940Err AppIMPCheckFreq(float freq)
|
AD5940Err AppIMPCheckFreq(float freq) {
|
||||||
{
|
|
||||||
ADCFilterCfg_Type filter_cfg;
|
ADCFilterCfg_Type filter_cfg;
|
||||||
DFTCfg_Type dft_cfg;
|
DFTCfg_Type dft_cfg;
|
||||||
uint32_t WaitClks;
|
uint32_t WaitClks;
|
||||||
|
|
@ -536,7 +522,8 @@ AD5940Err AppIMPCheckFreq(float freq)
|
||||||
|
|
||||||
// Update Wait Times in SRAM for all 3 measurements
|
// Update Wait Times in SRAM for all 3 measurements
|
||||||
for (int i = 0; i < 3; i++) {
|
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];
|
SRAMAddr = AppIMPCfg.MeasureSeqInfo.SeqRamAddr + AppIMPCfg.SeqWaitAddr[i];
|
||||||
|
|
||||||
|
|
@ -551,13 +538,13 @@ AD5940Err AppIMPCheckFreq(float freq)
|
||||||
return AD5940ERR_OK;
|
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;
|
AD5940Err error = AD5940ERR_OK;
|
||||||
SEQCfg_Type seq_cfg;
|
SEQCfg_Type seq_cfg;
|
||||||
FIFOCfg_Type fifo_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
|
// Stop timers and sequencer before reconfiguration
|
||||||
AD5940_WUPTCtrl(bFALSE);
|
AD5940_WUPTCtrl(bFALSE);
|
||||||
|
|
@ -580,17 +567,20 @@ int32_t AppIMPInit(uint32_t *pBuffer, uint32_t BufferSize)
|
||||||
AD5940_FIFOCfg(&fifo_cfg);
|
AD5940_FIFOCfg(&fifo_cfg);
|
||||||
AD5940_INTCClrFlag(AFEINTSRC_ALLINT);
|
AD5940_INTCClrFlag(AFEINTSRC_ALLINT);
|
||||||
|
|
||||||
if((AppIMPCfg.IMPInited == bFALSE)||(AppIMPCfg.bParaChanged == bTRUE))
|
if ((AppIMPCfg.IMPInited == bFALSE) || (AppIMPCfg.bParaChanged == bTRUE)) {
|
||||||
{
|
if (pBuffer == 0)
|
||||||
if(pBuffer == 0) return AD5940ERR_PARA;
|
return AD5940ERR_PARA;
|
||||||
if(BufferSize == 0) return AD5940ERR_PARA;
|
if (BufferSize == 0)
|
||||||
|
return AD5940ERR_PARA;
|
||||||
AD5940_SEQGenInit(pBuffer, BufferSize);
|
AD5940_SEQGenInit(pBuffer, BufferSize);
|
||||||
|
|
||||||
error = AppIMPSeqCfgGen();
|
error = AppIMPSeqCfgGen();
|
||||||
if(error != AD5940ERR_OK) return error;
|
if (error != AD5940ERR_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
error = AppIMPSeqMeasureGen();
|
error = AppIMPSeqMeasureGen();
|
||||||
if(error != AD5940ERR_OK) return error;
|
if (error != AD5940ERR_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
AppIMPCfg.bParaChanged = bFALSE;
|
AppIMPCfg.bParaChanged = bFALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -626,25 +616,20 @@ int32_t AppIMPInit(uint32_t *pBuffer, uint32_t BufferSize)
|
||||||
return AD5940ERR_OK;
|
return AD5940ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t AppIMPRegModify(int32_t * const pData, uint32_t *pDataCount)
|
int32_t AppIMPRegModify(int32_t *const pData, uint32_t *pDataCount) {
|
||||||
{
|
if (AppIMPCfg.NumOfData > 0) {
|
||||||
if(AppIMPCfg.NumOfData > 0)
|
|
||||||
{
|
|
||||||
AppIMPCfg.FifoDataCount += *pDataCount / 6;
|
AppIMPCfg.FifoDataCount += *pDataCount / 6;
|
||||||
if(AppIMPCfg.FifoDataCount >= AppIMPCfg.NumOfData)
|
if (AppIMPCfg.FifoDataCount >= AppIMPCfg.NumOfData) {
|
||||||
{
|
|
||||||
AD5940_WUPTCtrl(bFALSE);
|
AD5940_WUPTCtrl(bFALSE);
|
||||||
AD5940_SEQCtrlS(bFALSE);
|
AD5940_SEQCtrlS(bFALSE);
|
||||||
return AD5940ERR_STOP; // Return STOP code
|
return AD5940ERR_STOP; // Return STOP code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(AppIMPCfg.StopRequired == bTRUE)
|
if (AppIMPCfg.StopRequired == bTRUE) {
|
||||||
{
|
|
||||||
AD5940_WUPTCtrl(bFALSE);
|
AD5940_WUPTCtrl(bFALSE);
|
||||||
return AD5940ERR_OK;
|
return AD5940ERR_OK;
|
||||||
}
|
}
|
||||||
if(AppIMPCfg.SweepCfg.SweepEn)
|
if (AppIMPCfg.SweepCfg.SweepEn) {
|
||||||
{
|
|
||||||
// Update Filters and Wait Times in SRAM
|
// Update Filters and Wait Times in SRAM
|
||||||
AppIMPCheckFreq(AppIMPCfg.SweepNextFreq);
|
AppIMPCheckFreq(AppIMPCfg.SweepNextFreq);
|
||||||
|
|
||||||
|
|
@ -654,8 +639,7 @@ int32_t AppIMPRegModify(int32_t * const pData, uint32_t *pDataCount)
|
||||||
return AD5940ERR_OK;
|
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 DataCount = *pDataCount;
|
||||||
uint32_t ImpResCount = DataCount / 6;
|
uint32_t ImpResCount = DataCount / 6;
|
||||||
|
|
||||||
|
|
@ -664,17 +648,14 @@ int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount)
|
||||||
|
|
||||||
*pDataCount = 0;
|
*pDataCount = 0;
|
||||||
|
|
||||||
for(uint32_t i=0; i<DataCount; i++)
|
for (uint32_t i = 0; i < DataCount; i++) {
|
||||||
{
|
|
||||||
pData[i] &= 0x3ffff;
|
pData[i] &= 0x3ffff;
|
||||||
if(pData[i]&(1L<<17))
|
if (pData[i] & (1L << 17)) {
|
||||||
{
|
|
||||||
pData[i] |= 0xfffc0000;
|
pData[i] |= 0xfffc0000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uint32_t i=0; i<ImpResCount; i++)
|
for (uint32_t i = 0; i < ImpResCount; i++) {
|
||||||
{
|
|
||||||
iImpCar_Type *pDftRcal, *pDftI, *pDftV;
|
iImpCar_Type *pDftRcal, *pDftI, *pDftV;
|
||||||
|
|
||||||
pDftRcal = pSrcData++;
|
pDftRcal = pSrcData++;
|
||||||
|
|
@ -685,10 +666,12 @@ int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount)
|
||||||
float MagV, PhaseV;
|
float MagV, PhaseV;
|
||||||
float ZMag, ZPhase;
|
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);
|
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);
|
PhaseV = atan2(-pDftV->Image, pDftV->Real);
|
||||||
|
|
||||||
// Calculate Impedance: Z = (V / I) * Rtia
|
// 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;
|
ZPhase = PhaseV - PhaseI + MATH_PI;
|
||||||
|
|
||||||
while(ZPhase > MATH_PI) ZPhase -= 2*MATH_PI;
|
while (ZPhase > MATH_PI)
|
||||||
while(ZPhase < -MATH_PI) ZPhase += 2*MATH_PI;
|
ZPhase -= 2 * MATH_PI;
|
||||||
|
while (ZPhase < -MATH_PI)
|
||||||
|
ZPhase += 2 * MATH_PI;
|
||||||
|
|
||||||
pOut[i].Magnitude = ZMag;
|
pOut[i].Magnitude = ZMag;
|
||||||
pOut[i].Phase = ZPhase;
|
pOut[i].Phase = ZPhase;
|
||||||
|
|
@ -708,8 +693,7 @@ int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount)
|
||||||
*pDataCount = ImpResCount;
|
*pDataCount = ImpResCount;
|
||||||
AppIMPCfg.FreqofData = AppIMPCfg.SweepCurrFreq;
|
AppIMPCfg.FreqofData = AppIMPCfg.SweepCurrFreq;
|
||||||
|
|
||||||
if(AppIMPCfg.SweepCfg.SweepEn == bTRUE)
|
if (AppIMPCfg.SweepCfg.SweepEn == bTRUE) {
|
||||||
{
|
|
||||||
AppIMPCfg.FreqofData = AppIMPCfg.SweepCurrFreq;
|
AppIMPCfg.FreqofData = AppIMPCfg.SweepCurrFreq;
|
||||||
AppIMPCfg.SweepCurrFreq = AppIMPCfg.SweepNextFreq;
|
AppIMPCfg.SweepCurrFreq = AppIMPCfg.SweepNextFreq;
|
||||||
AD5940_SweepNext(&AppIMPCfg.SweepCfg, &AppIMPCfg.SweepNextFreq);
|
AD5940_SweepNext(&AppIMPCfg.SweepCfg, &AppIMPCfg.SweepNextFreq);
|
||||||
|
|
@ -718,15 +702,15 @@ int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t AppIMPISR(void *pBuff, uint32_t *pCount)
|
int32_t AppIMPISR(void *pBuff, uint32_t *pCount) {
|
||||||
{
|
|
||||||
uint32_t BuffCount;
|
uint32_t BuffCount;
|
||||||
uint32_t FifoCnt;
|
uint32_t FifoCnt;
|
||||||
BuffCount = *pCount;
|
BuffCount = *pCount;
|
||||||
|
|
||||||
*pCount = 0;
|
*pCount = 0;
|
||||||
|
|
||||||
if(AD5940_WakeUp(10) > 10) return AD5940ERR_WAKEUP;
|
if (AD5940_WakeUp(10) > 10)
|
||||||
|
return AD5940ERR_WAKEUP;
|
||||||
AD5940_SleepKeyCtrlS(SLPKEY_LOCK);
|
AD5940_SleepKeyCtrlS(SLPKEY_LOCK);
|
||||||
|
|
||||||
uint32_t IntFlag = AD5940_INTCGetFlag(AFEINTC_1);
|
uint32_t IntFlag = AD5940_INTCGetFlag(AFEINTC_1);
|
||||||
|
|
@ -747,31 +731,27 @@ int32_t AppIMPISR(void *pBuff, uint32_t *pCount)
|
||||||
return AD5940ERR_FIFO;
|
return AD5940ERR_FIFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IntFlag & AFEINTSRC_ENDSEQ)
|
if (IntFlag & AFEINTSRC_ENDSEQ) {
|
||||||
{
|
|
||||||
int timeout = 200;
|
int timeout = 200;
|
||||||
while(AD5940_FIFOGetCnt() < 6 && timeout-- > 0)
|
while (AD5940_FIFOGetCnt() < 6 && timeout-- > 0) {
|
||||||
{
|
|
||||||
AD5940_Delay10us(10);
|
AD5940_Delay10us(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
FifoCnt = (AD5940_FIFOGetCnt() / 6) * 6;
|
FifoCnt = (AD5940_FIFOGetCnt() / 6) * 6;
|
||||||
if(FifoCnt > BuffCount) FifoCnt = BuffCount;
|
if (FifoCnt > BuffCount)
|
||||||
|
FifoCnt = BuffCount;
|
||||||
|
|
||||||
AD5940_FIFORd((uint32_t *)pBuff, FifoCnt);
|
AD5940_FIFORd((uint32_t *)pBuff, FifoCnt);
|
||||||
AD5940_INTCClrFlag(AFEINTSRC_ENDSEQ);
|
AD5940_INTCClrFlag(AFEINTSRC_ENDSEQ);
|
||||||
|
|
||||||
if (FifoCnt > 0)
|
if (FifoCnt > 0) {
|
||||||
{
|
|
||||||
AD5940_SEQCtrlS(bFALSE);
|
AD5940_SEQCtrlS(bFALSE);
|
||||||
|
|
||||||
int32_t status = AppIMPRegModify(pBuff, &FifoCnt);
|
int32_t status = AppIMPRegModify(pBuff, &FifoCnt);
|
||||||
if (status == AD5940ERR_OK)
|
if (status == AD5940ERR_OK) {
|
||||||
{
|
if (AppIMPCfg.FifoDataCount < AppIMPCfg.NumOfData ||
|
||||||
if(AppIMPCfg.FifoDataCount < AppIMPCfg.NumOfData || AppIMPCfg.NumOfData == -1)
|
AppIMPCfg.NumOfData == -1) {
|
||||||
{
|
if (AppIMPCfg.StopRequired == bFALSE) {
|
||||||
if(AppIMPCfg.StopRequired == bFALSE)
|
|
||||||
{
|
|
||||||
AD5940_Delay10us(20);
|
AD5940_Delay10us(20);
|
||||||
|
|
||||||
AD5940_WriteReg(REG_AFE_SEQCNT, 0);
|
AD5940_WriteReg(REG_AFE_SEQCNT, 0);
|
||||||
|
|
@ -795,10 +775,9 @@ int32_t AppIMPISR(void *pBuff, uint32_t *pCount)
|
||||||
*pCount = FifoCnt;
|
*pCount = FifoCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == AD5940ERR_STOP) return AD5940ERR_STOP;
|
if (status == AD5940ERR_STOP)
|
||||||
}
|
return AD5940ERR_STOP;
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK);
|
AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK);
|
||||||
*pCount = 0;
|
*pCount = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ void AD5940ImpedanceStructInit(void) {
|
||||||
|
|
||||||
// T-Switch: Only connect the Feedback Resistor (TRTIA).
|
// T-Switch: Only connect the Feedback Resistor (TRTIA).
|
||||||
// DO NOT connect SWT_SE0 (T11), as it may short SE0 to RE0/LPTIA nodes.
|
// 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->HstiaRtiaSel = GetHSTIARtia(ConfigHstiaVal);
|
||||||
pImpedanceCfg->BiasVolt = 0.0;
|
pImpedanceCfg->BiasVolt = 0.0;
|
||||||
|
|
@ -110,7 +111,8 @@ void Config_LPLOOP(float bias_mv) {
|
||||||
float vzero_volts = vzero_code * (2200.0f / 64.0f);
|
float vzero_volts = vzero_code * (2200.0f / 64.0f);
|
||||||
float vbias_volts = vzero_volts + bias_mv;
|
float vbias_volts = vzero_volts + bias_mv;
|
||||||
uint32_t vbias_code = (uint32_t)(vbias_volts / (2200.0f / 4095.0f));
|
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;
|
LPDACCfg_Type lpdac_cfg;
|
||||||
lpdac_cfg.LpdacSel = LPDAC0;
|
lpdac_cfg.LpdacSel = LPDAC0;
|
||||||
|
|
@ -119,7 +121,8 @@ void Config_LPLOOP(float bias_mv) {
|
||||||
lpdac_cfg.DacData6Bit = vzero_code;
|
lpdac_cfg.DacData6Bit = vzero_code;
|
||||||
lpdac_cfg.DacData12Bit = vbias_code;
|
lpdac_cfg.DacData12Bit = vbias_code;
|
||||||
lpdac_cfg.DataRst = bFALSE;
|
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.LpDacRef = LPDACREF_2P5;
|
||||||
lpdac_cfg.LpDacSrc = LPDACSRC_MMR;
|
lpdac_cfg.LpDacSrc = LPDACSRC_MMR;
|
||||||
lpdac_cfg.PowerEn = bTRUE;
|
lpdac_cfg.PowerEn = bTRUE;
|
||||||
|
|
@ -135,7 +138,8 @@ void Config_LPLOOP(float bias_mv) {
|
||||||
lp_loop.LpAmpCfg.LpTiaRtia = GetLPTIARtia(ConfigLptiaVal);
|
lp_loop.LpAmpCfg.LpTiaRtia = GetLPTIARtia(ConfigLptiaVal);
|
||||||
|
|
||||||
// Base Switches
|
// 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
|
// Apply Short Option
|
||||||
if (GlobalShortRe0Se0) {
|
if (GlobalShortRe0Se0) {
|
||||||
|
|
@ -342,18 +346,22 @@ void Do_WaveGen(float freq) {
|
||||||
HpLoopCfg.WgCfg.WgType = WGTYPE_SIN;
|
HpLoopCfg.WgCfg.WgType = WGTYPE_SIN;
|
||||||
HpLoopCfg.WgCfg.GainCalEn = bFALSE;
|
HpLoopCfg.WgCfg.GainCalEn = bFALSE;
|
||||||
HpLoopCfg.WgCfg.OffsetCalEn = 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
|
// Reduced Amplitude: 50mV peak (100mV pp) to prevent saturation
|
||||||
// Range is +/- 607mV with Gain 2/1.
|
// Range is +/- 607mV with Gain 2/1.
|
||||||
// 50 / 607 * 2047 = ~168
|
// 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.SinOffsetWord = 0;
|
||||||
HpLoopCfg.WgCfg.SinCfg.SinPhaseWord = 0;
|
HpLoopCfg.WgCfg.SinCfg.SinPhaseWord = 0;
|
||||||
AD5940_HSLoopCfgS(&HpLoopCfg);
|
AD5940_HSLoopCfgS(&HpLoopCfg);
|
||||||
|
|
||||||
AD5940_AFECtrlS(AFECTRL_DACREFPWR, bTRUE);
|
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_WG, bTRUE);
|
||||||
AD5940_AFECtrlS(AFECTRL_DCBUFPWR, bTRUE);
|
AD5940_AFECtrlS(AFECTRL_DCBUFPWR, bTRUE);
|
||||||
AD5940_AFEPwrBW(AFEPWR_LP, AFEBW_250KHZ);
|
AD5940_AFEPwrBW(AFEPWR_LP, AFEBW_250KHZ);
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,12 @@
|
||||||
|
|
||||||
void Routine_CalibrateLFO(void) {
|
void Routine_CalibrateLFO(void) {
|
||||||
printf(">> Calibrating LFOSC...\n");
|
printf(">> Calibrating LFOSC...\n");
|
||||||
if (CurrentMode == MODE_IMPEDANCE) AppIMPCleanup();
|
if (CurrentMode == MODE_IMPEDANCE)
|
||||||
else if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
AppIMPCleanup();
|
||||||
else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
else if (CurrentMode == MODE_AMPEROMETRIC)
|
||||||
|
AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
||||||
|
else if (CurrentMode == MODE_RAMP)
|
||||||
|
AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
||||||
|
|
||||||
LFOSCMeasure_Type cal_cfg;
|
LFOSCMeasure_Type cal_cfg;
|
||||||
cal_cfg.CalDuration = 1000.0;
|
cal_cfg.CalDuration = 1000.0;
|
||||||
|
|
@ -20,8 +23,10 @@ void Routine_CalibrateLFO(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Routine_Measure(float freq) {
|
void Routine_Measure(float freq) {
|
||||||
if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
if (CurrentMode == MODE_AMPEROMETRIC)
|
||||||
else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
||||||
|
else if (CurrentMode == MODE_RAMP)
|
||||||
|
AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
||||||
CurrentMode = MODE_IMPEDANCE;
|
CurrentMode = MODE_IMPEDANCE;
|
||||||
|
|
||||||
AppIMPCfg_Type *pCfg;
|
AppIMPCfg_Type *pCfg;
|
||||||
|
|
@ -35,6 +40,12 @@ void Routine_Measure(float freq) {
|
||||||
pCfg->SinFreq = freq;
|
pCfg->SinFreq = freq;
|
||||||
pCfg->NumOfData = -1;
|
pCfg->NumOfData = -1;
|
||||||
pCfg->RealDataCount = -1;
|
pCfg->RealDataCount = -1;
|
||||||
|
|
||||||
|
// Apply Global Settings
|
||||||
|
pCfg->ShortRe0Se0 = GlobalShortRe0Se0;
|
||||||
|
pCfg->HstiaRtiaSel = GetHSTIARtia(ConfigHstiaVal);
|
||||||
|
pCfg->RtiaVal = (float)ConfigHstiaVal;
|
||||||
|
|
||||||
pCfg->bParaChanged = bTRUE;
|
pCfg->bParaChanged = bTRUE;
|
||||||
|
|
||||||
if (AppIMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) {
|
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) {
|
void Routine_Sweep(float start, float end, int steps) {
|
||||||
if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
if (CurrentMode == MODE_AMPEROMETRIC)
|
||||||
else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
||||||
|
else if (CurrentMode == MODE_RAMP)
|
||||||
|
AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
||||||
CurrentMode = MODE_IMPEDANCE;
|
CurrentMode = MODE_IMPEDANCE;
|
||||||
|
|
||||||
AppIMPCfg_Type *pCfg;
|
AppIMPCfg_Type *pCfg;
|
||||||
|
|
@ -63,6 +76,12 @@ void Routine_Sweep(float start, float end, int steps) {
|
||||||
pCfg->NumOfData = steps + 1;
|
pCfg->NumOfData = steps + 1;
|
||||||
pCfg->RealDataCount = steps;
|
pCfg->RealDataCount = steps;
|
||||||
pCfg->SweepCfg.SweepLog = bTRUE;
|
pCfg->SweepCfg.SweepLog = bTRUE;
|
||||||
|
|
||||||
|
// Apply Global Settings
|
||||||
|
pCfg->ShortRe0Se0 = GlobalShortRe0Se0;
|
||||||
|
pCfg->HstiaRtiaSel = GetHSTIARtia(ConfigHstiaVal);
|
||||||
|
pCfg->RtiaVal = (float)ConfigHstiaVal;
|
||||||
|
|
||||||
pCfg->bParaChanged = bTRUE;
|
pCfg->bParaChanged = bTRUE;
|
||||||
|
|
||||||
if (AppIMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) {
|
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) {
|
void Routine_Amperometric(float bias_mv) {
|
||||||
if (CurrentMode == MODE_IMPEDANCE) AppIMPCleanup();
|
if (CurrentMode == MODE_IMPEDANCE)
|
||||||
else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
AppIMPCleanup();
|
||||||
|
else if (CurrentMode == MODE_RAMP)
|
||||||
|
AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
||||||
CurrentMode = MODE_AMPEROMETRIC;
|
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;
|
AppAMPCfg_Type *pCfg;
|
||||||
AppAMPGetCfg(&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) {
|
void Routine_LSV(float start_mv, float end_mv, int steps, int duration_ms) {
|
||||||
if (CurrentMode == MODE_IMPEDANCE) AppIMPCleanup();
|
if (CurrentMode == MODE_IMPEDANCE)
|
||||||
else if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
AppIMPCleanup();
|
||||||
|
else if (CurrentMode == MODE_AMPEROMETRIC)
|
||||||
|
AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
||||||
CurrentMode = MODE_RAMP;
|
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;
|
AppRAMPCfg_Type *pCfg;
|
||||||
AppRAMPGetCfg(&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) {
|
void Routine_CalibrateSystem(void) {
|
||||||
if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
if (CurrentMode == MODE_AMPEROMETRIC)
|
||||||
else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
AppAMPCtrl(AMPCTRL_SHUTDOWN, 0);
|
||||||
|
else if (CurrentMode == MODE_RAMP)
|
||||||
|
AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
|
||||||
CurrentMode = MODE_IMPEDANCE;
|
CurrentMode = MODE_IMPEDANCE;
|
||||||
|
|
||||||
AppIMPCfg_Type *pCfg;
|
AppIMPCfg_Type *pCfg;
|
||||||
|
|
@ -160,7 +188,8 @@ void Routine_CalibrateSystem(void) {
|
||||||
|
|
||||||
printf(">> Calibrating LPTIA %d Ohm...\n", ConfigLptiaVal);
|
printf(">> Calibrating LPTIA %d Ohm...\n", ConfigLptiaVal);
|
||||||
if (AD5940_LPRtiaCal(&lprtia_cal, &LpRes) == AD5940ERR_OK) {
|
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;
|
CalibratedLptiaVal = LpRes.Magnitude;
|
||||||
} else {
|
} else {
|
||||||
printf("LPTIA Calibration Failed\n");
|
printf("LPTIA Calibration Failed\n");
|
||||||
|
|
@ -194,7 +223,8 @@ void Routine_CalibrateSystem(void) {
|
||||||
|
|
||||||
printf(">> Calibrating HSTIA %d Ohm...\n", ConfigHstiaVal);
|
printf(">> Calibrating HSTIA %d Ohm...\n", ConfigHstiaVal);
|
||||||
if (AD5940_HSRtiaCal(&hsrtia_cal, &HsRes) == AD5940ERR_OK) {
|
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;
|
CalibratedHstiaVal = HsRes.Magnitude;
|
||||||
} else {
|
} else {
|
||||||
printf("HSTIA Calibration Failed\n");
|
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 ---
|
||||||
# ==========================================
|
# ==========================================
|
||||||
|
|
||||||
|
|
||||||
|
# --- FFTW3 Configuration (Double Precision) ---
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
# Windows: Expects FFTW3 to be installed/found via Config
|
# Windows: Expects FFTW3 to be installed/found via Config
|
||||||
find_package(FFTW3 CONFIG REQUIRED)
|
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}"
|
IMPORTED_LOCATION "${FFTW3_LIB}"
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${FFTW3_INCLUDE_DIR}"
|
INTERFACE_INCLUDE_DIRECTORIES "${FFTW3_INCLUDE_DIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
else()
|
else()
|
||||||
message(STATUS "Building FFTW3 from source (Double Precision)...")
|
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_SHARED_LIBS OFF CACHE BOOL "Build Static Libs" FORCE)
|
||||||
set(BUILD_TESTS OFF CACHE BOOL "Disable Tests" 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")
|
if(ANDROID_ABI STREQUAL "arm64-v8a")
|
||||||
message(STATUS "Enabling NEON for Android ARM64")
|
message(STATUS "Enabling NEON for Android ARM64")
|
||||||
set(ENABLE_NEON ON CACHE BOOL "Enable NEON" FORCE)
|
set(ENABLE_NEON ON CACHE BOOL "Enable NEON" FORCE)
|
||||||
elseif(BUILD_IOS)
|
elseif(BUILD_IOS)
|
||||||
set(ENABLE_NEON ON CACHE BOOL "Enable NEON" FORCE)
|
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()
|
endif()
|
||||||
|
|
||||||
# Patch for older CMake versions inside the tarball if needed
|
# Only apply sed patch on UNIX-like systems
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
set(PATCH_CMD sed -i.bak "s/cmake_minimum_required.*/cmake_minimum_required(VERSION 3.16)/" <SOURCE_DIR>/CMakeLists.txt)
|
set(PATCH_CMD sed -i.bak "s/cmake_minimum_required.*/cmake_minimum_required(VERSION 3.16)/" <SOURCE_DIR>/CMakeLists.txt)
|
||||||
else()
|
else()
|
||||||
|
|
@ -208,8 +214,10 @@ if(BUILD_ANDROID)
|
||||||
|
|
||||||
target_link_libraries(EISConfigurator PRIVATE Qt6::Widgets Qt6::SerialPort Qt6::AndroidExtras)
|
target_link_libraries(EISConfigurator PRIVATE Qt6::Widgets Qt6::SerialPort Qt6::AndroidExtras)
|
||||||
else()
|
else()
|
||||||
add_executable(EISConfigurator ${PROJECT_SOURCES})
|
target_link_libraries(EISConfigurator PRIVATE Qt6::Widgets Qt6::SerialPort Qt6::PrintSupport)
|
||||||
target_link_libraries(EISConfigurator PRIVATE Qt6::Widgets Qt6::SerialPort)
|
if(APPLE)
|
||||||
|
target_link_libraries(EISConfigurator PRIVATE ${FFTW_TARGET})
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -253,5 +261,5 @@ elseif(WIN32)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# CRITICAL: Triggers androiddeployqt to build the APK
|
|
||||||
qt_finalize_executable(EISConfigurator)
|
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
|
#!/bin/bash
|
||||||
|
|
||||||
# Resolve the directory where the script is located
|
# Argument 1: Path to magick executable
|
||||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
|
||||||
# Project Root is two levels up (host/scripts -> host -> root)
|
|
||||||
PROJECT_ROOT="$SCRIPT_DIR/../.."
|
|
||||||
|
|
||||||
MAGICK_BIN="$1"
|
MAGICK_BIN="$1"
|
||||||
if [ -z "$MAGICK_BIN" ]; then MAGICK_BIN="magick"; fi
|
|
||||||
|
|
||||||
SOURCE="$PROJECT_ROOT/assets/icon_source.png"
|
# Fallback if not provided
|
||||||
OUT_DIR="$PROJECT_ROOT/assets/icons"
|
if [ -z "$MAGICK_BIN" ]; then
|
||||||
ANDROID_RES_DIR="$PROJECT_ROOT/host/android/res"
|
MAGICK_BIN="magick"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Assumes running from Project Root
|
||||||
|
SOURCE="assets/icon_source.png"
|
||||||
|
|
||||||
if [ ! -f "$SOURCE" ]; then
|
if [ ! -f "$SOURCE" ]; then
|
||||||
echo "Error: Source image '$SOURCE' not found."
|
echo "Error: Source image '$SOURCE' not found in $(pwd)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -26,56 +23,66 @@ if [ $? -ne 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p "$OUT_DIR"
|
# --- macOS ---
|
||||||
|
# Keep macOS icons in assets/icons as they are linked explicitly
|
||||||
# macOS
|
MACOS_OUT_DIR="assets/icons"
|
||||||
ICONSET="$OUT_DIR/icon.iconset"
|
mkdir -p "$MACOS_OUT_DIR"
|
||||||
|
ICONSET="$MACOS_OUT_DIR/icon.iconset"
|
||||||
mkdir -p "$ICONSET"
|
mkdir -p "$ICONSET"
|
||||||
|
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 16x16 "$ICONSET/icon_16x16.png"
|
echo "[ICONS] Generating macOS iconset (Pixel Perfect)..."
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 32x32 "$ICONSET/icon_16x16@2x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 16x16 "$ICONSET/icon_16x16.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 32x32 "$ICONSET/icon_32x32.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 32x32 "$ICONSET/icon_16x16@2x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 64x64 "$ICONSET/icon_32x32@2x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 32x32 "$ICONSET/icon_32x32.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 128x128 "$ICONSET/icon_128x128.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 64x64 "$ICONSET/icon_32x32@2x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 256x256 "$ICONSET/icon_128x128@2x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 128x128 "$ICONSET/icon_128x128.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 256x256 "$ICONSET/icon_256x256.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 256x256 "$ICONSET/icon_128x128@2x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 512x512 "$ICONSET/icon_256x256@2x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 256x256 "$ICONSET/icon_256x256.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 512x512 "$ICONSET/icon_512x512.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 512x512 "$ICONSET/icon_256x256@2x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 1024x1024 "$ICONSET/icon_512x512@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"
|
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" \
|
"$MAGICK_BIN" "$SOURCE" \
|
||||||
\( -clone 0 -scale 256x256 \) \
|
-background none -alpha on \
|
||||||
\( -clone 0 -scale 128x128 \) \
|
\( -clone 0 -sample 256x256 \) \
|
||||||
\( -clone 0 -scale 64x64 \) \
|
\( -clone 0 -sample 128x128 \) \
|
||||||
\( -clone 0 -scale 48x48 \) \
|
\( -clone 0 -sample 64x64 \) \
|
||||||
\( -clone 0 -scale 32x32 \) \
|
\( -clone 0 -sample 48x48 \) \
|
||||||
\( -clone 0 -scale 16x16 \) \
|
\( -clone 0 -sample 32x32 \) \
|
||||||
-delete 0 -alpha off -colors 256 "$OUT_DIR/app_icon.ico"
|
\( -clone 0 -sample 16x16 \) \
|
||||||
|
-delete 0 "$MACOS_OUT_DIR/app_icon.ico"
|
||||||
|
|
||||||
# Android
|
# --- Android ---
|
||||||
echo "Generating Android Icons into $ANDROID_RES_DIR..."
|
# 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"
|
mkdir -p "$ANDROID_DIR/mipmap-mdpi"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 48x48 "$ANDROID_RES_DIR/mipmap-mdpi/ic_launcher.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 48x48 "$ANDROID_DIR/mipmap-mdpi/ic_launcher.png"
|
||||||
|
|
||||||
mkdir -p "$ANDROID_RES_DIR/mipmap-hdpi"
|
mkdir -p "$ANDROID_DIR/mipmap-hdpi"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 72x72 "$ANDROID_RES_DIR/mipmap-hdpi/ic_launcher.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 72x72 "$ANDROID_DIR/mipmap-hdpi/ic_launcher.png"
|
||||||
|
|
||||||
mkdir -p "$ANDROID_RES_DIR/mipmap-xhdpi"
|
mkdir -p "$ANDROID_DIR/mipmap-xhdpi"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 96x96 "$ANDROID_RES_DIR/mipmap-xhdpi/ic_launcher.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 96x96 "$ANDROID_DIR/mipmap-xhdpi/ic_launcher.png"
|
||||||
|
|
||||||
mkdir -p "$ANDROID_RES_DIR/mipmap-xxhdpi"
|
mkdir -p "$ANDROID_DIR/mipmap-xxhdpi"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 144x144 "$ANDROID_RES_DIR/mipmap-xxhdpi/ic_launcher.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 144x144 "$ANDROID_DIR/mipmap-xxhdpi/ic_launcher.png"
|
||||||
|
|
||||||
mkdir -p "$ANDROID_RES_DIR/mipmap-xxxhdpi"
|
mkdir -p "$ANDROID_DIR/mipmap-xxxhdpi"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 192x192 "$ANDROID_RES_DIR/mipmap-xxxhdpi/ic_launcher.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 192x192 "$ANDROID_DIR/mipmap-xxxhdpi/ic_launcher.png"
|
||||||
|
|
||||||
# iOS
|
# --- iOS ---
|
||||||
XCASSETS_DIR="$OUT_DIR/ios/Assets.xcassets"
|
# Output directly to ios/Assets.xcassets
|
||||||
|
echo "[ICONS] Generating iOS AppIcon (Pixel Perfect)..."
|
||||||
|
XCASSETS_DIR="ios/Assets.xcassets"
|
||||||
IOS_DIR="$XCASSETS_DIR/AppIcon.appiconset"
|
IOS_DIR="$XCASSETS_DIR/AppIcon.appiconset"
|
||||||
mkdir -p "$IOS_DIR"
|
mkdir -p "$IOS_DIR"
|
||||||
|
|
||||||
|
|
@ -88,21 +95,21 @@ cat > "$XCASSETS_DIR/Contents.json" <<EOF
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 20x20 "$IOS_DIR/Icon-20.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 20x20 "$IOS_DIR/Icon-20.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 40x40 "$IOS_DIR/Icon-20@2x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 40x40 "$IOS_DIR/Icon-20@2x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 60x60 "$IOS_DIR/Icon-20@3x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 60x60 "$IOS_DIR/Icon-20@3x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 29x29 "$IOS_DIR/Icon-29.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 29x29 "$IOS_DIR/Icon-29.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 58x58 "$IOS_DIR/Icon-29@2x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 58x58 "$IOS_DIR/Icon-29@2x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 87x87 "$IOS_DIR/Icon-29@3x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 87x87 "$IOS_DIR/Icon-29@3x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 40x40 "$IOS_DIR/Icon-40.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 40x40 "$IOS_DIR/Icon-40.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 80x80 "$IOS_DIR/Icon-40@2x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 80x80 "$IOS_DIR/Icon-40@2x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 120x120 "$IOS_DIR/Icon-40@3x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 120x120 "$IOS_DIR/Icon-40@3x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 120x120 "$IOS_DIR/Icon-60@2x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 120x120 "$IOS_DIR/Icon-60@2x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 180x180 "$IOS_DIR/Icon-60@3x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 180x180 "$IOS_DIR/Icon-60@3x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 76x76 "$IOS_DIR/Icon-76.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 76x76 "$IOS_DIR/Icon-76.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 152x152 "$IOS_DIR/Icon-76@2x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 152x152 "$IOS_DIR/Icon-76@2x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 167x167 "$IOS_DIR/Icon-83.5@2x.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 167x167 "$IOS_DIR/Icon-83.5@2x.png"
|
||||||
"$MAGICK_BIN" "$SOURCE" -scale 1024x1024 "$IOS_DIR/Icon-1024.png"
|
"$MAGICK_BIN" "$SOURCE" -sample 1024x1024 "$IOS_DIR/Icon-1024.png"
|
||||||
|
|
||||||
cat > "$IOS_DIR/Contents.json" <<EOF
|
cat > "$IOS_DIR/Contents.json" <<EOF
|
||||||
{
|
{
|
||||||
|
|
@ -133,3 +140,5 @@ cat > "$IOS_DIR/Contents.json" <<EOF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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