This commit is contained in:
pszsh 2026-02-02 00:47:30 -08:00
parent 3e78b4eb75
commit 2945835eeb
5 changed files with 178 additions and 132 deletions

View File

@ -29,24 +29,24 @@ protected:
bool event(QEvent *event) override; bool event(QEvent *event) override;
private slots: private slots:
// Serial Slots (MainWindow_Serial.cpp) // Serial Slots
void handleSerialData(); void handleSerialData();
void connectToPort(); void connectToPort();
void refreshPorts(); void refreshPorts();
void onPortError(QSerialPort::SerialPortError error); void onPortError(QSerialPort::SerialPortError error);
// UI Slots (MainWindow_UI.cpp / MainWindow.cpp) // UI Slots
void onBlinkTimer(); void onBlinkTimer();
void onLPFChanged(int index); void onLPFChanged(int index);
// Action Slots (MainWindow_Actions.cpp) // Action Slots
void checkDeviceId(); void checkDeviceId();
void runCalibration(); void runCalibration();
void startSweep(); void startSweep();
void toggleMeasurement(); void toggleMeasurement();
void toggleAmperometry(); void toggleAmperometry();
// LSV Slots (MainWindow_Actions.cpp) // LSV Slots
void startLSVBlank(); void startLSVBlank();
void startLSVSample(); void startLSVSample();
void stopLSV(); void stopLSV();
@ -54,18 +54,16 @@ private slots:
void calibrateCellConstant(); void calibrateCellConstant();
private: private:
// Initialization Methods // Split Implementation Methods
void setupUi(); // In MainWindow_UI.cpp void setupUi();
void loadSettings(); // In MainWindow.cpp void loadSettings();
void saveSettings(); // In MainWindow.cpp void saveSettings();
void parseData(const QString &data);
// Logic Helpers void handleSwipe(QSwipeGesture *gesture);
void parseData(const QString &data); // In MainWindow_Serial.cpp void computeHilbert();
void handleSwipe(QSwipeGesture *gesture); // In MainWindow.cpp void performCircleFit();
void computeHilbert(); // In MainWindow_Actions.cpp void calculateLSVDiff();
void performCircleFit(); // In MainWindow_Actions.cpp void setButtonBlinking(QPushButton *btn, bool blinking);
void calculateLSVDiff(); // In MainWindow_Actions.cpp
void setButtonBlinking(QPushButton *btn, bool blinking); // In MainWindow_UI.cpp
QSerialPort *serial; QSerialPort *serial;
QSettings *settings; QSettings *settings;
@ -80,7 +78,7 @@ private:
GraphWidget *lsvGraph; GraphWidget *lsvGraph;
QTextEdit *logWidget; QTextEdit *logWidget;
// Layout Elements // Layout
QTabWidget *tabWidget; QTabWidget *tabWidget;
QComboBox *portSelector; QComboBox *portSelector;
QPushButton *connectBtn; QPushButton *connectBtn;
@ -94,7 +92,8 @@ private:
QDoubleSpinBox *spinSweepStart; QDoubleSpinBox *spinSweepStart;
QDoubleSpinBox *spinSweepStop; QDoubleSpinBox *spinSweepStop;
QSpinBox *spinSweepPPD; QSpinBox *spinSweepPPD;
QComboBox *comboRange; QComboBox *comboRangeLP; // New LP Range
QComboBox *comboRangeHP; // New HP Range
// Shunt / De-embedding Configuration // Shunt / De-embedding Configuration
QCheckBox *checkShunt; QCheckBox *checkShunt;
@ -121,11 +120,11 @@ private:
double cellConstant = 1.0; double cellConstant = 1.0;
// State Flags
bool isMeasuringImp = false; bool isMeasuringImp = false;
bool isMeasuringAmp = false; bool isMeasuringAmp = false;
bool isSweeping = false; bool isSweeping = false;
// LSV State
enum LSVState { LSV_IDLE, LSV_RUNNING_BLANK, LSV_RUNNING_SAMPLE }; enum LSVState { LSV_IDLE, LSV_RUNNING_BLANK, LSV_RUNNING_SAMPLE };
LSVState lsvState = LSV_IDLE; LSVState lsvState = LSV_IDLE;
@ -134,7 +133,7 @@ private:
QVector<double> sweepReals; QVector<double> sweepReals;
QVector<double> sweepImags; QVector<double> sweepImags;
// LSV Data Storage // LSV Data Storage for Diff Calculation
struct LSVPoint { double voltage; double current; }; struct LSVPoint { double voltage; double current; };
QVector<LSVPoint> lsvBlankData; QVector<LSVPoint> lsvBlankData;
QVector<LSVPoint> lsvSampleData; QVector<LSVPoint> lsvSampleData;

View File

@ -11,8 +11,9 @@ void MainWindow::checkDeviceId() {
void MainWindow::runCalibration() { void MainWindow::runCalibration() {
if (serial->isOpen()) { if (serial->isOpen()) {
int rangeVal = comboRange->currentData().toInt(); int lpVal = comboRangeLP->currentData().toInt();
serial->write(QString("r %1\n").arg(rangeVal).toUtf8()); int hpVal = comboRangeHP->currentData().toInt();
serial->write(QString("r %1 %2\n").arg(lpVal).arg(hpVal).toUtf8());
serial->write("c\n"); serial->write("c\n");
} }
} }
@ -47,11 +48,14 @@ void MainWindow::startSweep() {
double start = spinSweepStart->value(); double start = spinSweepStart->value();
double stop = spinSweepStop->value(); double stop = spinSweepStop->value();
int ppd = spinSweepPPD->value(); int ppd = spinSweepPPD->value();
int rangeVal = comboRange->currentData().toInt();
logWidget->append(QString(">> Starting Sweep (Range: %1, s %2 %3 %4)...").arg(rangeVal).arg(start).arg(stop).arg(ppd));
serial->write(QString("r %1\n").arg(rangeVal).toUtf8()); // Ensure firmware has correct ranges before starting
int lpVal = comboRangeLP->currentData().toInt();
int hpVal = comboRangeHP->currentData().toInt();
serial->write(QString("r %1 %2\n").arg(lpVal).arg(hpVal).toUtf8());
logWidget->append(QString(">> Starting Sweep (HP Range: %1, s %2 %3 %4)...").arg(hpVal).arg(start).arg(stop).arg(ppd));
serial->write(QString("s %1 %2 %3\n").arg(start).arg(stop).arg(ppd).toUtf8()); serial->write(QString("s %1 %2 %3\n").arg(start).arg(stop).arg(ppd).toUtf8());
isSweeping = true; isSweeping = true;
@ -73,9 +77,10 @@ void MainWindow::toggleMeasurement() {
isMeasuringImp = false; isMeasuringImp = false;
} else { } else {
double freq = spinFreq->value(); double freq = spinFreq->value();
int rangeVal = comboRange->currentData().toInt(); int lpVal = comboRangeLP->currentData().toInt();
int hpVal = comboRangeHP->currentData().toInt();
serial->write(QString("r %1\n").arg(rangeVal).toUtf8()); serial->write(QString("r %1 %2\n").arg(lpVal).arg(hpVal).toUtf8());
serial->write(QString("m %1\n").arg(freq).toUtf8()); serial->write(QString("m %1\n").arg(freq).toUtf8());
measureBtn->setText("Stop"); measureBtn->setText("Stop");
@ -98,9 +103,10 @@ void MainWindow::toggleAmperometry() {
isMeasuringAmp = false; isMeasuringAmp = false;
} else { } else {
double bias = spinAmpBias->value(); double bias = spinAmpBias->value();
int rangeVal = comboRange->currentData().toInt(); int lpVal = comboRangeLP->currentData().toInt();
int hpVal = comboRangeHP->currentData().toInt();
serial->write(QString("r %1\n").arg(rangeVal).toUtf8()); serial->write(QString("r %1 %2\n").arg(lpVal).arg(hpVal).toUtf8());
serial->write(QString("a %1\n").arg(bias).toUtf8()); serial->write(QString("a %1\n").arg(bias).toUtf8());
ampBtn->setText("Stop Amp"); ampBtn->setText("Stop Amp");
@ -122,11 +128,12 @@ void MainWindow::startLSVBlank() {
double stop = spinLsvStop->value(); double stop = spinLsvStop->value();
int steps = spinLsvSteps->value(); int steps = spinLsvSteps->value();
int duration = spinLsvDuration->value(); int duration = spinLsvDuration->value();
int rangeVal = comboRange->currentData().toInt(); int lpVal = comboRangeLP->currentData().toInt();
int hpVal = comboRangeHP->currentData().toInt();
logWidget->append(QString(">> Starting LSV Blank (Range: %1, %.1f to %.1f mV)...").arg(rangeVal).arg(start).arg(stop)); logWidget->append(QString(">> Starting LSV Blank (LP Range: %1, %.1f to %.1f mV)...").arg(lpVal).arg(start).arg(stop));
serial->write(QString("r %1\n").arg(rangeVal).toUtf8()); serial->write(QString("r %1 %2\n").arg(lpVal).arg(hpVal).toUtf8());
serial->write(QString("l %1 %2 %3 %4\n").arg(start).arg(stop).arg(steps).arg(duration).toUtf8()); serial->write(QString("l %1 %2 %3 %4\n").arg(start).arg(stop).arg(steps).arg(duration).toUtf8());
lsvBlankBtn->setText("Stop Blank"); lsvBlankBtn->setText("Stop Blank");
@ -151,11 +158,12 @@ void MainWindow::startLSVSample() {
double stop = spinLsvStop->value(); double stop = spinLsvStop->value();
int steps = spinLsvSteps->value(); int steps = spinLsvSteps->value();
int duration = spinLsvDuration->value(); int duration = spinLsvDuration->value();
int rangeVal = comboRange->currentData().toInt(); int lpVal = comboRangeLP->currentData().toInt();
int hpVal = comboRangeHP->currentData().toInt();
logWidget->append(QString(">> Starting LSV Sample (Range: %1, %.1f to %.1f mV)...").arg(rangeVal).arg(start).arg(stop)); logWidget->append(QString(">> Starting LSV Sample (LP Range: %1, %.1f to %.1f mV)...").arg(lpVal).arg(start).arg(stop));
serial->write(QString("r %1\n").arg(rangeVal).toUtf8()); serial->write(QString("r %1 %2\n").arg(lpVal).arg(hpVal).toUtf8());
serial->write(QString("l %1 %2 %3 %4\n").arg(start).arg(stop).arg(steps).arg(duration).toUtf8()); serial->write(QString("l %1 %2 %3 %4\n").arg(start).arg(stop).arg(steps).arg(duration).toUtf8());
lsvSampleBtn->setText("Stop Sample"); lsvSampleBtn->setText("Stop Sample");

View File

@ -40,7 +40,11 @@ void MainWindow::connectToPort() {
ampBtn->setEnabled(false); ampBtn->setEnabled(false);
spinAmpBias->setEnabled(false); spinAmpBias->setEnabled(false);
btnCalCond->setEnabled(false); btnCalCond->setEnabled(false);
comboRange->setEnabled(false);
// Updated Range Controls
comboRangeLP->setEnabled(false);
comboRangeHP->setEnabled(false);
comboLPF->setEnabled(false); comboLPF->setEnabled(false);
lsvBlankBtn->setEnabled(false); lsvBlankBtn->setEnabled(false);
lsvSampleBtn->setEnabled(false); lsvSampleBtn->setEnabled(false);
@ -80,7 +84,11 @@ void MainWindow::connectToPort() {
ampBtn->setEnabled(true); ampBtn->setEnabled(true);
spinAmpBias->setEnabled(true); spinAmpBias->setEnabled(true);
btnCalCond->setEnabled(true); btnCalCond->setEnabled(true);
comboRange->setEnabled(true);
// Updated Range Controls
comboRangeLP->setEnabled(true);
comboRangeHP->setEnabled(true);
comboLPF->setEnabled(true); comboLPF->setEnabled(true);
lsvBlankBtn->setEnabled(true); lsvBlankBtn->setEnabled(true);
lsvSampleBtn->setEnabled(true); lsvSampleBtn->setEnabled(true);
@ -111,7 +119,11 @@ void MainWindow::onPortError(QSerialPort::SerialPortError error) {
ampBtn->setEnabled(false); ampBtn->setEnabled(false);
spinAmpBias->setEnabled(false); spinAmpBias->setEnabled(false);
btnCalCond->setEnabled(false); btnCalCond->setEnabled(false);
comboRange->setEnabled(false);
// Updated Range Controls
comboRangeLP->setEnabled(false);
comboRangeHP->setEnabled(false);
comboLPF->setEnabled(false); comboLPF->setEnabled(false);
lsvBlankBtn->setEnabled(false); lsvBlankBtn->setEnabled(false);
lsvSampleBtn->setEnabled(false); lsvSampleBtn->setEnabled(false);

View File

@ -28,8 +28,8 @@ void MainWindow::setupUi() {
portSelector->setMinimumWidth(120); portSelector->setMinimumWidth(120);
connectBtn = new QPushButton("Connect", this); connectBtn = new QPushButton("Connect", this);
// Disconnect color (Red 50%) will be set when connected, default is Connect // Default Connect Color (Greenish)
connectBtn->setStyleSheet("background-color: rgba(255, 0, 0, 128); color: white; font-weight: bold;"); connectBtn->setStyleSheet("background-color: rgba(0, 128, 0, 128); color: white; font-weight: bold;");
QPushButton *refreshBtn = new QPushButton("Refresh", this); QPushButton *refreshBtn = new QPushButton("Refresh", this);
refreshBtn->setStyleSheet("background-color: rgba(255, 255, 255, 178); color: black; font-weight: bold;"); refreshBtn->setStyleSheet("background-color: rgba(255, 255, 255, 178); color: black; font-weight: bold;");
@ -44,11 +44,7 @@ void MainWindow::setupUi() {
checkIdBtn = new QPushButton("Check ID", this); checkIdBtn = new QPushButton("Check ID", this);
checkIdBtn->setStyleSheet("background-color: rgba(255, 255, 255, 166); color: black; font-weight: bold;"); checkIdBtn->setStyleSheet("background-color: rgba(255, 255, 255, 166); color: black; font-weight: bold;");
calibrateBtn = new QPushButton("Calibrate HW", this);
calibrateBtn->setStyleSheet("background-color: rgba(255, 255, 0, 102); color: white; font-weight: bold;");
row1->addWidget(checkIdBtn); row1->addWidget(checkIdBtn);
row1->addWidget(calibrateBtn);
QFrame *sep2 = new QFrame(); sep2->setFrameShape(QFrame::VLine); sep2->setFrameShadow(QFrame::Sunken); QFrame *sep2 = new QFrame(); sep2->setFrameShape(QFrame::VLine); sep2->setFrameShadow(QFrame::Sunken);
row1->addWidget(sep2); row1->addWidget(sep2);
@ -105,37 +101,55 @@ void MainWindow::setupUi() {
QHBoxLayout *row2 = new QHBoxLayout(); QHBoxLayout *row2 = new QHBoxLayout();
row2->setSpacing(8); row2->setSpacing(8);
row2->addWidget(new QLabel("Range:")); // LP Range (Full List)
comboRange = new QComboBox(this); row2->addWidget(new QLabel("LP Range:"));
// Full 26 Resistor List comboRangeLP = new QComboBox(this);
comboRange->addItem("200 Ω", 200); comboRangeLP->addItem("200 Ω", 200);
comboRange->addItem("1 kΩ", 1000); comboRangeLP->addItem("1 kΩ", 1000);
comboRange->addItem("2 kΩ", 2000); comboRangeLP->addItem("2 kΩ", 2000);
comboRange->addItem("3 kΩ", 3000); comboRangeLP->addItem("3 kΩ", 3000);
comboRange->addItem("4 kΩ", 4000); comboRangeLP->addItem("4 kΩ", 4000);
comboRange->addItem("6 kΩ", 6000); comboRangeLP->addItem("6 kΩ", 6000);
comboRange->addItem("8 kΩ", 8000); comboRangeLP->addItem("8 kΩ", 8000);
comboRange->addItem("10 kΩ", 10000); comboRangeLP->addItem("10 kΩ", 10000);
comboRange->addItem("12 kΩ", 12000); comboRangeLP->addItem("12 kΩ", 12000);
comboRange->addItem("16 kΩ", 16000); comboRangeLP->addItem("16 kΩ", 16000);
comboRange->addItem("20 kΩ", 20000); comboRangeLP->addItem("20 kΩ", 20000);
comboRange->addItem("24 kΩ", 24000); comboRangeLP->addItem("24 kΩ", 24000);
comboRange->addItem("30 kΩ", 30000); comboRangeLP->addItem("30 kΩ", 30000);
comboRange->addItem("32 kΩ", 32000); comboRangeLP->addItem("32 kΩ", 32000);
comboRange->addItem("40 kΩ", 40000); comboRangeLP->addItem("40 kΩ", 40000);
comboRange->addItem("48 kΩ", 48000); comboRangeLP->addItem("48 kΩ", 48000);
comboRange->addItem("64 kΩ", 64000); comboRangeLP->addItem("64 kΩ", 64000);
comboRange->addItem("85 kΩ", 85000); comboRangeLP->addItem("85 kΩ", 85000);
comboRange->addItem("96 kΩ", 96000); comboRangeLP->addItem("96 kΩ", 96000);
comboRange->addItem("100 kΩ", 100000); comboRangeLP->addItem("100 kΩ", 100000);
comboRange->addItem("120 kΩ", 120000); comboRangeLP->addItem("120 kΩ", 120000);
comboRange->addItem("128 kΩ", 128000); comboRangeLP->addItem("128 kΩ", 128000);
comboRange->addItem("160 kΩ", 160000); comboRangeLP->addItem("160 kΩ", 160000);
comboRange->addItem("196 kΩ", 196000); comboRangeLP->addItem("196 kΩ", 196000);
comboRange->addItem("256 kΩ", 256000); comboRangeLP->addItem("256 kΩ", 256000);
comboRange->addItem("512 kΩ", 512000); comboRangeLP->addItem("512 kΩ", 512000);
comboRange->setCurrentIndex(1); // Default 1k comboRangeLP->setCurrentIndex(1); // Default 1k
row2->addWidget(comboRange); row2->addWidget(comboRangeLP);
// HP Range (Limited List)
row2->addWidget(new QLabel("HP Range:"));
comboRangeHP = new QComboBox(this);
comboRangeHP->addItem("200 Ω", 200);
comboRangeHP->addItem("1 kΩ", 1000);
comboRangeHP->addItem("5 kΩ", 5000);
comboRangeHP->addItem("10 kΩ", 10000);
comboRangeHP->addItem("20 kΩ", 20000);
comboRangeHP->addItem("40 kΩ", 40000);
comboRangeHP->addItem("80 kΩ", 80000);
comboRangeHP->addItem("160 kΩ", 160000);
comboRangeHP->setCurrentIndex(1); // Default 1k
row2->addWidget(comboRangeHP);
calibrateBtn = new QPushButton("Calibrate HW", this);
calibrateBtn->setStyleSheet("background-color: rgba(255, 255, 0, 102); color: white; font-weight: bold;");
row2->addWidget(calibrateBtn);
QFrame *sepRange = new QFrame(); sepRange->setFrameShape(QFrame::VLine); sepRange->setFrameShadow(QFrame::Sunken); QFrame *sepRange = new QFrame(); sepRange->setFrameShape(QFrame::VLine); sepRange->setFrameShadow(QFrame::Sunken);
row2->addWidget(sepRange); row2->addWidget(sepRange);
@ -258,7 +272,8 @@ void MainWindow::setupUi() {
ampBtn->setEnabled(false); ampBtn->setEnabled(false);
spinAmpBias->setEnabled(false); spinAmpBias->setEnabled(false);
btnCalCond->setEnabled(false); btnCalCond->setEnabled(false);
comboRange->setEnabled(false); comboRangeLP->setEnabled(false);
comboRangeHP->setEnabled(false);
comboLPF->setEnabled(false); comboLPF->setEnabled(false);
lsvBlankBtn->setEnabled(false); lsvBlankBtn->setEnabled(false);
lsvSampleBtn->setEnabled(false); lsvSampleBtn->setEnabled(false);

122
main.c
View File

@ -47,27 +47,16 @@ float LFOSCFreq = 32000.0;
// Range / RTIA Management // Range / RTIA Management
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Full list of 26 supported ranges // Current Configuration
float RtiaCalibrationTable[26] = { uint32_t ConfigLptiaVal = 1000; // Default LP: 1k
200.0, 1000.0, 2000.0, 3000.0, 4000.0, 6000.0, 8000.0, uint32_t ConfigHstiaVal = 1000; // Default HP: 1k
10000.0, 12000.0, 16000.0, 20000.0, 24000.0, 30000.0, 32000.0,
40000.0, 48000.0, 64000.0, 85000.0, 96000.0, 100000.0,
120000.0, 128000.0, 160000.0, 196000.0, 256000.0, 512000.0
};
uint32_t CurrentRtiaIndex = 1; // Default 1k
uint32_t ConfigRtiaVal = 1000;
uint32_t CurrentLpTiaRf = LPTIARF_20K; uint32_t CurrentLpTiaRf = LPTIARF_20K;
// Helper to find index for calibration table // Calibrated Values
int GetRtiaIndex(uint32_t val) { float CalibratedLptiaVal = 1000.0f;
for(int i=0; i<26; i++) { float CalibratedHstiaVal = 1000.0f;
if((uint32_t)RtiaCalibrationTable[i] == val) return i;
}
return 1; // Default 1k
}
// Map integer value to HSTIA Enum (Impedance) // Map integer value to HSTIA Enum (Impedance) - Limited Selection
uint32_t GetHSTIARtia(uint32_t val) { uint32_t GetHSTIARtia(uint32_t val) {
switch(val) { switch(val) {
case 200: return HSTIARTIA_200; case 200: return HSTIARTIA_200;
@ -78,12 +67,11 @@ uint32_t GetHSTIARtia(uint32_t val) {
case 40000: return HSTIARTIA_40K; case 40000: return HSTIARTIA_40K;
case 80000: return HSTIARTIA_80K; case 80000: return HSTIARTIA_80K;
case 160000: return HSTIARTIA_160K; case 160000: return HSTIARTIA_160K;
// Note: HSTIA has fewer options than LPTIA. Map closest or default.
default: return HSTIARTIA_1K; default: return HSTIARTIA_1K;
} }
} }
// Map integer value to LPTIA Enum (Amperometric/Ramp) // Map integer value to LPTIA Enum (Amperometric/Ramp) - Massive Selection
uint32_t GetLPTIARtia(uint32_t val) { uint32_t GetLPTIARtia(uint32_t val) {
switch(val) { switch(val) {
case 200: return LPTIARTIA_200R; case 200: return LPTIARTIA_200R;
@ -175,7 +163,7 @@ void AD5940ImpedanceStructInit(void)
pImpedanceCfg->SeqStartAddr = 0; pImpedanceCfg->SeqStartAddr = 0;
pImpedanceCfg->MaxSeqLen = 512; pImpedanceCfg->MaxSeqLen = 512;
pImpedanceCfg->RcalVal = 100.0; pImpedanceCfg->RcalVal = 100.0;
pImpedanceCfg->RtiaVal = RtiaCalibrationTable[CurrentRtiaIndex]; pImpedanceCfg->RtiaVal = CalibratedHstiaVal; // Use Calibrated HP Value
pImpedanceCfg->SinFreq = 1000.0; pImpedanceCfg->SinFreq = 1000.0;
pImpedanceCfg->FifoThresh = 6; pImpedanceCfg->FifoThresh = 6;
pImpedanceCfg->DacVoltPP = 600.0; pImpedanceCfg->DacVoltPP = 600.0;
@ -185,7 +173,7 @@ void AD5940ImpedanceStructInit(void)
pImpedanceCfg->PswitchSel = SWP_CE0; pImpedanceCfg->PswitchSel = SWP_CE0;
pImpedanceCfg->NswitchSel = SWN_SE0; pImpedanceCfg->NswitchSel = SWN_SE0;
pImpedanceCfg->TswitchSel = SWT_SE0LOAD; pImpedanceCfg->TswitchSel = SWT_SE0LOAD;
pImpedanceCfg->HstiaRtiaSel = GetHSTIARtia(ConfigRtiaVal); pImpedanceCfg->HstiaRtiaSel = GetHSTIARtia(ConfigHstiaVal); // Use HP Selection
pImpedanceCfg->BiasVolt = 0.0; pImpedanceCfg->BiasVolt = 0.0;
pImpedanceCfg->SweepCfg.SweepEn = bFALSE; pImpedanceCfg->SweepCfg.SweepEn = bFALSE;
pImpedanceCfg->SweepCfg.SweepStart = 100.0f; pImpedanceCfg->SweepCfg.SweepStart = 100.0f;
@ -210,11 +198,12 @@ void AD5940AMPStructInit(void)
pAMPCfg->AmpODR = 1.0; pAMPCfg->AmpODR = 1.0;
pAMPCfg->FifoThresh = 4; pAMPCfg->FifoThresh = 4;
pAMPCfg->SensorBias = 0; pAMPCfg->SensorBias = 0;
pAMPCfg->LptiaRtiaSel = GetLPTIARtia(ConfigRtiaVal); pAMPCfg->LptiaRtiaSel = GetLPTIARtia(ConfigLptiaVal); // Use LP Selection
pAMPCfg->LpTiaRl = LPTIARLOAD_10R; pAMPCfg->LpTiaRl = LPTIARLOAD_10R;
pAMPCfg->LpTiaRf = CurrentLpTiaRf; pAMPCfg->LpTiaRf = CurrentLpTiaRf;
pAMPCfg->Vzero = 1100; pAMPCfg->Vzero = 1100;
pAMPCfg->ADCRefVolt = 1.82; pAMPCfg->ADCRefVolt = 1.82;
pAMPCfg->RtiaCalValue.Magnitude = CalibratedLptiaVal; // Use Calibrated LP Value
} }
void AD5940RampStructInit(void) void AD5940RampStructInit(void)
@ -238,10 +227,11 @@ void AD5940RampStructInit(void)
pRampCfg->RampDuration = 10000; pRampCfg->RampDuration = 10000;
pRampCfg->SampleDelay = 1.0f; pRampCfg->SampleDelay = 1.0f;
pRampCfg->LPTIARtiaSel = GetLPTIARtia(ConfigRtiaVal); pRampCfg->LPTIARtiaSel = GetLPTIARtia(ConfigLptiaVal); // Use LP Selection
pRampCfg->LPTIARloadSel = LPTIARLOAD_10R; pRampCfg->LPTIARloadSel = LPTIARLOAD_10R;
pRampCfg->LpTiaRf = CurrentLpTiaRf; pRampCfg->LpTiaRf = CurrentLpTiaRf;
pRampCfg->AdcPgaGain = ADCPGA_1P5; pRampCfg->AdcPgaGain = ADCPGA_1P5;
pRampCfg->RtiaValue.Magnitude = CalibratedLptiaVal; // Use Calibrated LP Value
} }
static int32_t AD5940PlatformCfg(void) static int32_t AD5940PlatformCfg(void)
@ -354,9 +344,10 @@ void Routine_Measure(float freq) {
AppIMPCfg_Type *pCfg; AppIMPCfg_Type *pCfg;
AppIMPGetCfg(&pCfg); AppIMPGetCfg(&pCfg);
AppIMPCleanup(); AppIMPCleanup();
AD5940ImpedanceStructInit(); // Reload config with current HP settings
pCfg->WuptClkFreq = LFOSCFreq; pCfg->WuptClkFreq = LFOSCFreq;
pCfg->HstiaRtiaSel = GetHSTIARtia(ConfigRtiaVal);
pCfg->RtiaVal = RtiaCalibrationTable[CurrentRtiaIndex];
pCfg->SweepCfg.SweepEn = bFALSE; pCfg->SweepCfg.SweepEn = bFALSE;
pCfg->SinFreq = freq; pCfg->SinFreq = freq;
pCfg->NumOfData = -1; pCfg->NumOfData = -1;
@ -378,9 +369,10 @@ void Routine_Sweep(float start, float end, int steps) {
AppIMPCfg_Type *pCfg; AppIMPCfg_Type *pCfg;
AppIMPGetCfg(&pCfg); AppIMPGetCfg(&pCfg);
AppIMPCleanup(); AppIMPCleanup();
AD5940ImpedanceStructInit(); // Reload config with current HP settings
pCfg->WuptClkFreq = LFOSCFreq; pCfg->WuptClkFreq = LFOSCFreq;
pCfg->HstiaRtiaSel = GetHSTIARtia(ConfigRtiaVal);
pCfg->RtiaVal = RtiaCalibrationTable[CurrentRtiaIndex];
pCfg->SweepCfg.SweepEn = bTRUE; pCfg->SweepCfg.SweepEn = bTRUE;
pCfg->SweepCfg.SweepStart = start; pCfg->SweepCfg.SweepStart = start;
pCfg->SweepCfg.SweepStop = end; pCfg->SweepCfg.SweepStop = end;
@ -402,15 +394,13 @@ void Routine_Amperometric(float bias_mv) {
else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0); else if (CurrentMode == MODE_RAMP) AppRAMPCtrl(APPCTRL_SHUTDOWN, 0);
CurrentMode = MODE_AMPEROMETRIC; CurrentMode = MODE_AMPEROMETRIC;
printf(">> Starting Amperometry (Bias: %.1f mV, Range: %d)...\n", bias_mv, ConfigRtiaVal); printf(">> Starting Amperometry (Bias: %.1f mV, LP Range: %d)...\n", bias_mv, ConfigLptiaVal);
AppAMPCfg_Type *pCfg; AppAMPCfg_Type *pCfg;
AppAMPGetCfg(&pCfg); AppAMPGetCfg(&pCfg);
AD5940AMPStructInit(); AD5940AMPStructInit(); // Reload config with current LP settings
pCfg->SensorBias = bias_mv; pCfg->SensorBias = bias_mv;
pCfg->WuptClkFreq = LFOSCFreq; pCfg->ReDoRtiaCal = bFALSE; // Use pre-calibrated value
pCfg->LptiaRtiaSel = GetLPTIARtia(ConfigRtiaVal);
pCfg->ReDoRtiaCal = bTRUE;
if(AppAMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { if(AppAMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) {
AppAMPCtrl(AMPCTRL_START, 0); AppAMPCtrl(AMPCTRL_START, 0);
@ -424,24 +414,17 @@ void Routine_LSV(float start_mv, float end_mv, int steps, int duration_ms) {
else if (CurrentMode == MODE_AMPEROMETRIC) AppAMPCtrl(AMPCTRL_SHUTDOWN, 0); 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)...\n", start_mv, end_mv, steps, duration_ms); 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);
AD5940RampStructInit(); AD5940RampStructInit(); // Reload config with current LP settings
pCfg->RampStartVolt = start_mv; pCfg->RampStartVolt = start_mv;
pCfg->RampPeakVolt = end_mv; pCfg->RampPeakVolt = end_mv;
pCfg->StepNumber = steps; pCfg->StepNumber = steps;
pCfg->RampDuration = duration_ms; pCfg->RampDuration = duration_ms;
pCfg->LFOSCClkFreq = LFOSCFreq; pCfg->bRampOneDir = bTRUE;
pCfg->LPTIARtiaSel = GetLPTIARtia(ConfigRtiaVal);
// Use global calibration value
pCfg->RtiaValue.Magnitude = RtiaCalibrationTable[CurrentRtiaIndex];
pCfg->RtiaValue.Phase = 0;
pCfg->bRampOneDir = bTRUE; // Linear Sweep (not Cyclic)
pCfg->bParaChanged = bTRUE; pCfg->bParaChanged = bTRUE;
if(AppRAMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) { if(AppRAMPInit(AppBuff, APPBUFF_SIZE) == AD5940ERR_OK) {
@ -473,6 +456,34 @@ void Routine_CalibrateSystem(void) {
printf(">> Calibrating ADC Offset...\n"); printf(">> Calibrating ADC Offset...\n");
AD5940_ADCPGACal(&adcpga_cal); AD5940_ADCPGACal(&adcpga_cal);
// --- 1. Calibrate LPTIA (Low Power Loop) ---
LPRTIACal_Type lprtia_cal;
fImpPol_Type LpRes;
memset(&lprtia_cal, 0, sizeof(lprtia_cal));
lprtia_cal.AdcClkFreq = 16000000.0;
lprtia_cal.SysClkFreq = 16000000.0;
lprtia_cal.ADCSinc3Osr = ADCSINC3OSR_4;
lprtia_cal.ADCSinc2Osr = ADCSINC2OSR_22;
lprtia_cal.bPolarResult = bTRUE;
lprtia_cal.fRcal = 100.0;
lprtia_cal.LpTiaRtia = GetLPTIARtia(ConfigLptiaVal);
lprtia_cal.LpAmpPwrMod = LPAMPPWR_NORM;
lprtia_cal.bWithCtia = bFALSE;
// Use a low frequency for LPTIA calibration
lprtia_cal.fFreq = 100.0f;
lprtia_cal.DftCfg.DftNum = DFTNUM_2048;
lprtia_cal.DftCfg.DftSrc = DFTSRC_SINC3;
lprtia_cal.DftCfg.HanWinEn = bTRUE;
printf(">> Calibrating LPTIA %d Ohm...\n", ConfigLptiaVal);
if (AD5940_LPRtiaCal(&lprtia_cal, &LpRes) == AD5940ERR_OK) {
printf("Calibrated LPTIA: Mag = %f Ohm, Phase = %f\n", LpRes.Magnitude, LpRes.Phase);
CalibratedLptiaVal = LpRes.Magnitude;
} else {
printf("LPTIA Calibration Failed\n");
}
// --- 2. Calibrate HSTIA (High Speed Loop) ---
HSDACCfg_Type hsdac_cfg; HSDACCfg_Type hsdac_cfg;
hsdac_cfg.ExcitBufGain = EXCITBUFGAIN_0P25; hsdac_cfg.ExcitBufGain = EXCITBUFGAIN_0P25;
hsdac_cfg.HsDacGain = HSDACGAIN_0P2; hsdac_cfg.HsDacGain = HSDACGAIN_0P2;
@ -480,7 +491,7 @@ void Routine_CalibrateSystem(void) {
AD5940_HSDacCfgS(&hsdac_cfg); AD5940_HSDacCfgS(&hsdac_cfg);
HSRTIACal_Type hsrtia_cal; HSRTIACal_Type hsrtia_cal;
fImpPol_Type Res; fImpPol_Type HsRes;
memset(&hsrtia_cal, 0, sizeof(hsrtia_cal)); memset(&hsrtia_cal, 0, sizeof(hsrtia_cal));
hsrtia_cal.fFreq = 1000.0f; hsrtia_cal.fFreq = 1000.0f;
hsrtia_cal.AdcClkFreq = 16000000.0; hsrtia_cal.AdcClkFreq = 16000000.0;
@ -492,19 +503,18 @@ void Routine_CalibrateSystem(void) {
hsrtia_cal.HsTiaCfg.DiodeClose = bFALSE; hsrtia_cal.HsTiaCfg.DiodeClose = bFALSE;
hsrtia_cal.HsTiaCfg.HstiaBias = HSTIABIAS_1P1; hsrtia_cal.HsTiaCfg.HstiaBias = HSTIABIAS_1P1;
hsrtia_cal.HsTiaCfg.HstiaCtia = 31; hsrtia_cal.HsTiaCfg.HstiaCtia = 31;
hsrtia_cal.HsTiaCfg.HstiaRtiaSel = GetHSTIARtia(ConfigRtiaVal); hsrtia_cal.HsTiaCfg.HstiaRtiaSel = GetHSTIARtia(ConfigHstiaVal);
hsrtia_cal.HsTiaCfg.HstiaDeRtia = HSTIADERTIA_OPEN; hsrtia_cal.HsTiaCfg.HstiaDeRtia = HSTIADERTIA_OPEN;
hsrtia_cal.HsTiaCfg.HstiaDeRload = HSTIADERLOAD_OPEN; hsrtia_cal.HsTiaCfg.HstiaDeRload = HSTIADERLOAD_OPEN;
hsrtia_cal.DftCfg.DftNum = DFTNUM_16384; hsrtia_cal.DftCfg.DftNum = DFTNUM_16384;
hsrtia_cal.DftCfg.DftSrc = DFTSRC_SINC3; hsrtia_cal.DftCfg.DftSrc = DFTSRC_SINC3;
printf(">> Calibrating RTIA %d Ohm...\n", ConfigRtiaVal); printf(">> Calibrating HSTIA %d Ohm...\n", ConfigHstiaVal);
if (AD5940_HSRtiaCal(&hsrtia_cal, &Res) == AD5940ERR_OK) { if (AD5940_HSRtiaCal(&hsrtia_cal, &HsRes) == AD5940ERR_OK) {
printf("Calibrated Rtia: Mag = %f Ohm, Phase = %f\n", Res.Magnitude, Res.Phase); printf("Calibrated HSTIA: Mag = %f Ohm, Phase = %f\n", HsRes.Magnitude, HsRes.Phase);
RtiaCalibrationTable[CurrentRtiaIndex] = Res.Magnitude; CalibratedHstiaVal = HsRes.Magnitude;
pCfg->RtiaVal = Res.Magnitude;
} else { } else {
printf("Calibration Failed\n"); printf("HSTIA Calibration Failed\n");
} }
} }
@ -524,11 +534,13 @@ void process_command() {
printf("CHIP_ID:0x%04X\n", id); printf("CHIP_ID:0x%04X\n", id);
} }
else if (cmd == 'r') { else if (cmd == 'r') {
// r <lp_val> <hp_val>
if (strlen(input_buffer) > 2) { if (strlen(input_buffer) > 2) {
uint32_t val = atoi(input_buffer + 2); int lp = 0, hp = 0;
ConfigRtiaVal = val; int count = sscanf(input_buffer + 2, "%d %d", &lp, &hp);
CurrentRtiaIndex = GetRtiaIndex(val); if (count >= 1) ConfigLptiaVal = lp;
printf("RANGE_SET:%d\n", ConfigRtiaVal); if (count >= 2) ConfigHstiaVal = hp;
printf("RANGE_SET LP:%d HP:%d\n", ConfigLptiaVal, ConfigHstiaVal);
} }
} }
else if (cmd == 'f') { else if (cmd == 'f') {