diff --git a/packages/adrv9009/plugins/adrv9009plugin/include/adrv9009plugin/adrv9009advanced.h b/packages/adrv9009/plugins/adrv9009plugin/include/adrv9009plugin/adrv9009advanced.h
index 13dae9c947..5459b337ce 100644
--- a/packages/adrv9009/plugins/adrv9009plugin/include/adrv9009plugin/adrv9009advanced.h
+++ b/packages/adrv9009/plugins/adrv9009plugin/include/adrv9009plugin/adrv9009advanced.h
@@ -33,6 +33,8 @@
namespace scopy::adrv9009 {
+class AgcSetupWidget;
+
class SCOPY_ADRV9009PLUGIN_EXPORT Adrv9009Advanced : public QWidget
{
Q_OBJECT
@@ -74,7 +76,7 @@ class SCOPY_ADRV9009PLUGIN_EXPORT Adrv9009Advanced : public QWidget
QWidget *m_fhmSetup = nullptr;
QWidget *m_paProtection = nullptr;
QWidget *m_gainSetup = nullptr;
- QWidget *m_agcSetup = nullptr;
+ AgcSetupWidget *m_agcSetup = nullptr;
QWidget *m_gpioConfig = nullptr;
QWidget *m_auxDac = nullptr;
QWidget *m_jesd204Settings = nullptr;
@@ -87,4 +89,4 @@ class SCOPY_ADRV9009PLUGIN_EXPORT Adrv9009Advanced : public QWidget
};
} // namespace scopy::adrv9009
-#endif // ADRV9009ADVANCED_H
\ No newline at end of file
+#endif // ADRV9009ADVANCED_H
diff --git a/packages/adrv9009/plugins/adrv9009plugin/include/adrv9009plugin/advanced/agcsetupwidget.h b/packages/adrv9009/plugins/adrv9009plugin/include/adrv9009plugin/advanced/agcsetupwidget.h
new file mode 100644
index 0000000000..1e051b9bf6
--- /dev/null
+++ b/packages/adrv9009/plugins/adrv9009plugin/include/adrv9009plugin/advanced/agcsetupwidget.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2025 Analog Devices Inc.
+ *
+ * This file is part of Scopy
+ * (see https://www.github.com/analogdevicesinc/scopy).
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef AGCSETUPWIDGET_H
+#define AGCSETUPWIDGET_H
+
+#include
+#include
+#include
+
+namespace scopy::adrv9009 {
+
+class AgcSetupWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit AgcSetupWidget(iio_device *device, QWidget *parent = nullptr);
+ ~AgcSetupWidget();
+
+Q_SIGNALS:
+ void readRequested();
+
+private:
+ void setupUi();
+ QWidget *createRxTddPowerGroup(int channel, QWidget *parent);
+ QWidget *createAgcRxChannelGroup(const QString &baseAttr, const QString &displayName, const QString &range,
+ QWidget *parent);
+
+ iio_device *m_device;
+};
+
+} // namespace scopy::adrv9009
+
+#endif // AGCSETUPWIDGET_H
diff --git a/packages/adrv9009/plugins/adrv9009plugin/src/adrv9009advanced.cpp b/packages/adrv9009/plugins/adrv9009plugin/src/adrv9009advanced.cpp
index a4c4de63e5..7c9c4e99a1 100644
--- a/packages/adrv9009/plugins/adrv9009plugin/src/adrv9009advanced.cpp
+++ b/packages/adrv9009/plugins/adrv9009plugin/src/adrv9009advanced.cpp
@@ -19,6 +19,7 @@
*/
#include "adrv9009advanced.h"
+#include "advanced/agcsetupwidget.h"
#include
#include
#include
@@ -237,7 +238,7 @@ void Adrv9009Advanced::createContentWidgets()
m_fhmSetup = createPlaceholderWidget("FHM Setup");
m_paProtection = createPlaceholderWidget("PA Protection");
m_gainSetup = createPlaceholderWidget("GAIN Setup");
- m_agcSetup = createPlaceholderWidget("AGC Setup");
+ m_agcSetup = new AgcSetupWidget(m_device, this);
m_gpioConfig = createPlaceholderWidget("GPIO Config");
m_auxDac = createPlaceholderWidget("AUX DAC");
m_jesd204Settings = createPlaceholderWidget("JESD204 Settings");
@@ -260,6 +261,10 @@ void Adrv9009Advanced::createContentWidgets()
// Set first widget as current (CLK Settings)
m_centralWidget->setCurrentWidget(m_clkSettings);
+
+ if(m_agcSetup) {
+ connect(this, &Adrv9009Advanced::readRequested, m_agcSetup, &AgcSetupWidget::readRequested);
+ }
}
QWidget *Adrv9009Advanced::createPlaceholderWidget(const QString §ionName)
diff --git a/packages/adrv9009/plugins/adrv9009plugin/src/advanced/agcsetupwidget.cpp b/packages/adrv9009/plugins/adrv9009plugin/src/advanced/agcsetupwidget.cpp
new file mode 100644
index 0000000000..8633a8ce13
--- /dev/null
+++ b/packages/adrv9009/plugins/adrv9009plugin/src/advanced/agcsetupwidget.cpp
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 2025 Analog Devices Inc.
+ *
+ * This file is part of Scopy
+ * (see https://www.github.com/analogdevicesinc/scopy).
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "advanced/agcsetupwidget.h"
+#include "adrv9009widgetfactory.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+Q_LOGGING_CATEGORY(CAT_AGCSETUP, "AgcSetup")
+
+using namespace scopy;
+using namespace scopy::adrv9009;
+
+AgcSetupWidget::AgcSetupWidget(iio_device *device, QWidget *parent)
+ : QWidget(parent)
+ , m_device(device)
+{
+ if(!m_device) {
+ qWarning(CAT_AGCSETUP) << "No device provided to AGC Setup widget";
+ return;
+ }
+
+ setupUi();
+}
+
+AgcSetupWidget::~AgcSetupWidget() {}
+
+void AgcSetupWidget::setupUi()
+{
+ // Main layout for this widget
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+ mainLayout->setContentsMargins(0, 0, 0, 0);
+ mainLayout->setSpacing(0);
+
+ // Create scroll area for all sections
+ QScrollArea *scrollArea = new QScrollArea();
+ scrollArea->setWidgetResizable(true);
+ scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+
+ // Create content widget for scroll area
+ QWidget *contentWidget = new QWidget();
+ QVBoxLayout *contentLayout = new QVBoxLayout(contentWidget);
+ contentLayout->setContentsMargins(10, 10, 10, 10);
+ contentLayout->setSpacing(15);
+
+ // 1. AGC Config section (19 attributes - adi,rxagc-agc-* only)
+ MenuSectionCollapseWidget *agcConfigSection = new MenuSectionCollapseWidget(
+ "AGC Config", MenuCollapseSection::MHCW_ARROW, MenuCollapseSection::MHW_BASEWIDGET, contentWidget);
+
+ // Peak Wait Time - Range Widget [0 1 31]
+ auto peakWaitTime = Adrv9009WidgetFactory::createRangeWidget(m_device, "adi,rxagc-agc-peak-wait-time",
+ "[0 1 31]", "Peak Wait Time");
+ if(peakWaitTime) {
+ agcConfigSection->contentLayout()->addWidget(peakWaitTime);
+ connect(this, &AgcSetupWidget::readRequested, peakWaitTime, &IIOWidget::readAsync);
+ }
+
+ // RX1/RX2 MAX GAIN INDEX - Two-column layout [0 1 255]
+ auto maxGainIndexGroup = createAgcRxChannelGroup("adi,rxagc-agc-rx%1-max-gain-index", "MAX GAIN INDEX",
+ "[0 1 255]", agcConfigSection);
+ agcConfigSection->contentLayout()->addWidget(maxGainIndexGroup);
+
+ // RX1/RX2 MIN GAIN INDEX - Two-column layout [0 1 255]
+ auto minGainIndexGroup = createAgcRxChannelGroup("adi,rxagc-agc-rx%1-min-gain-index", "MIN GAIN INDEX",
+ "[0 1 255]", agcConfigSection);
+ agcConfigSection->contentLayout()->addWidget(minGainIndexGroup);
+
+ // Gain Update Counter (us) - Range Widget [0 1 16000000]
+ auto gainUpdateCounter = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-agc-gain-update-counter_us", "[0 1 16000000]", "Gain Update Counter (us)");
+ if(gainUpdateCounter) {
+ agcConfigSection->contentLayout()->addWidget(gainUpdateCounter);
+ connect(this, &AgcSetupWidget::readRequested, gainUpdateCounter, &IIOWidget::readAsync);
+ }
+
+ // RX1/RX2 ATTACK DELAY - Two-column layout [0 1 63]
+ auto attackDelayGroup = createAgcRxChannelGroup("adi,rxagc-agc-rx%1-attack-delay", "ATTACK DELAY", "[0 1 63]",
+ agcConfigSection);
+ agcConfigSection->contentLayout()->addWidget(attackDelayGroup);
+
+ // Slow Loop Settling Delay - Range Widget [0 1 127]
+ auto slowLoopSettlingDelay = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-agc-slow-loop-settling-delay", "[0 1 127]", "Slow Loop Settling Delay");
+ if(slowLoopSettlingDelay) {
+ agcConfigSection->contentLayout()->addWidget(slowLoopSettlingDelay);
+ connect(this, &AgcSetupWidget::readRequested, slowLoopSettlingDelay, &IIOWidget::readAsync);
+ }
+
+ // Low Thresh Prevent Gain - Checkbox
+ auto lowThreshPreventGain = Adrv9009WidgetFactory::createCheckboxWidget(
+ m_device, "adi,rxagc-agc-low-thresh-prevent-gain", "Low Thresh Prevent Gain");
+ if(lowThreshPreventGain) {
+ agcConfigSection->contentLayout()->addWidget(lowThreshPreventGain);
+ connect(this, &AgcSetupWidget::readRequested, lowThreshPreventGain, &IIOWidget::readAsync);
+ }
+
+ // Change Gain If Thresh High - Checkbox
+ auto changeGainIfThreshHigh = Adrv9009WidgetFactory::createCheckboxWidget(
+ m_device, "adi,rxagc-agc-change-gain-if-thresh-high", "Change Gain If Thresh High");
+ if(changeGainIfThreshHigh) {
+ agcConfigSection->contentLayout()->addWidget(changeGainIfThreshHigh);
+ connect(this, &AgcSetupWidget::readRequested, changeGainIfThreshHigh, &IIOWidget::readAsync);
+ }
+
+ // Peak Thresh Gain Control Mode - Checkbox
+ auto peakThreshGainControlMode = Adrv9009WidgetFactory::createCheckboxWidget(
+ m_device, "adi,rxagc-agc-peak-thresh-gain-control-mode", "Peak Thresh Gain Control Mode");
+ if(peakThreshGainControlMode) {
+ agcConfigSection->contentLayout()->addWidget(peakThreshGainControlMode);
+ connect(this, &AgcSetupWidget::readRequested, peakThreshGainControlMode, &IIOWidget::readAsync);
+ }
+
+ // Reset On RXON - Checkbox
+ auto resetOnRxon =
+ Adrv9009WidgetFactory::createCheckboxWidget(m_device, "adi,rxagc-agc-reset-on-rxon", "Reset On RXON");
+ if(resetOnRxon) {
+ agcConfigSection->contentLayout()->addWidget(resetOnRxon);
+ connect(this, &AgcSetupWidget::readRequested, resetOnRxon, &IIOWidget::readAsync);
+ }
+
+ // Enable Sync Pulse For Gain Counter - Checkbox
+ auto enableSyncPulseForGainCounter = Adrv9009WidgetFactory::createCheckboxWidget(
+ m_device, "adi,rxagc-agc-enable-sync-pulse-for-gain-counter", "Enable Sync Pulse For Gain Counter");
+ if(enableSyncPulseForGainCounter) {
+ agcConfigSection->contentLayout()->addWidget(enableSyncPulseForGainCounter);
+ connect(this, &AgcSetupWidget::readRequested, enableSyncPulseForGainCounter, &IIOWidget::readAsync);
+ }
+
+ // Enable IP3 Optimization Thresh - Checkbox
+ auto enableIp3OptimizationThresh = Adrv9009WidgetFactory::createCheckboxWidget(
+ m_device, "adi,rxagc-agc-enable-ip3-optimization-thresh", "Enable IP3 Optimization Thresh");
+ if(enableIp3OptimizationThresh) {
+ agcConfigSection->contentLayout()->addWidget(enableIp3OptimizationThresh);
+ connect(this, &AgcSetupWidget::readRequested, enableIp3OptimizationThresh, &IIOWidget::readAsync);
+ }
+
+ // IP3 Over Range Thresh - Range Widget [0 1 63]
+ auto ip3OverRangeThresh = Adrv9009WidgetFactory::createRangeWidget(m_device, "adi,rxagc-ip3-over-range-thresh",
+ "[0 1 63]", "IP3 Over Range Thresh");
+ if(ip3OverRangeThresh) {
+ agcConfigSection->contentLayout()->addWidget(ip3OverRangeThresh);
+ connect(this, &AgcSetupWidget::readRequested, ip3OverRangeThresh, &IIOWidget::readAsync);
+ }
+
+ // IP3 Over Range Thresh Index - Range Widget [0 1 255]
+ auto ip3OverRangeThreshIndex = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-ip3-over-range-thresh-index", "[0 1 255]", "IP3 Over Range Thresh Index");
+ if(ip3OverRangeThreshIndex) {
+ agcConfigSection->contentLayout()->addWidget(ip3OverRangeThreshIndex);
+ connect(this, &AgcSetupWidget::readRequested, ip3OverRangeThreshIndex, &IIOWidget::readAsync);
+ }
+
+ // IP3 Peak Exceeded Count - Range Widget [0 1 255]
+ auto ip3PeakExceededCnt = Adrv9009WidgetFactory::createRangeWidget(m_device, "adi,rxagc-ip3-peak-exceeded-cnt",
+ "[0 1 255]", "IP3 Peak Exceeded Count");
+ if(ip3PeakExceededCnt) {
+ agcConfigSection->contentLayout()->addWidget(ip3PeakExceededCnt);
+ connect(this, &AgcSetupWidget::readRequested, ip3PeakExceededCnt, &IIOWidget::readAsync);
+ }
+
+ // Enable Fast Recovery Loop - Checkbox
+ auto enableFastRecoveryLoop = Adrv9009WidgetFactory::createCheckboxWidget(
+ m_device, "adi,rxagc-agc-enable-fast-recovery-loop", "Enable Fast Recovery Loop");
+ if(enableFastRecoveryLoop) {
+ agcConfigSection->contentLayout()->addWidget(enableFastRecoveryLoop);
+ connect(this, &AgcSetupWidget::readRequested, enableFastRecoveryLoop, &IIOWidget::readAsync);
+ }
+
+ contentLayout->addWidget(agcConfigSection);
+
+ // 2. Analog Peak Detector section (29 attributes - adi,rxagc-peak-* including HB2)
+ MenuSectionCollapseWidget *apdSection =
+ new MenuSectionCollapseWidget("Analog Peak Detector", MenuCollapseSection::MHCW_ARROW,
+ MenuCollapseSection::MHW_BASEWIDGET, contentWidget);
+
+ // Under Range Low Interval (ns) - Range Widget [0 1 4294967295]
+ auto underRangeLowInterval =
+ Adrv9009WidgetFactory::createRangeWidget(m_device, "adi,rxagc-peak-agc-under-range-low-interval_ns",
+ "[0 1 4294967295]", "Under Range Low Interval (ns)");
+ if(underRangeLowInterval) {
+ apdSection->contentLayout()->addWidget(underRangeLowInterval);
+ }
+
+ // Under Range Mid Interval - Range Widget [0 1 63]
+ auto underRangeMidInterval = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-agc-under-range-mid-interval", "[0 1 63]", "Under Range Mid Interval");
+ if(underRangeMidInterval) {
+ apdSection->contentLayout()->addWidget(underRangeMidInterval);
+ }
+
+ // Under Range High Interval - Range Widget [0 1 63]
+ auto underRangeHighInterval = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-agc-under-range-high-interval", "[0 1 63]", "Under Range High Interval");
+ if(underRangeHighInterval) {
+ apdSection->contentLayout()->addWidget(underRangeHighInterval);
+ }
+
+ // APD High Thresh - Range Widget [7 1 49]
+ auto apdHighThresh = Adrv9009WidgetFactory::createRangeWidget(m_device, "adi,rxagc-peak-apd-high-thresh",
+ "[7 1 49]", "APD High Thresh");
+ if(apdHighThresh) {
+ apdSection->contentLayout()->addWidget(apdHighThresh);
+ }
+
+ // APD Low Gain Mode High Thresh - Range Widget [7 1 49]
+ auto apdLowGainModeHighThresh = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-apd-low-gain-mode-high-thresh", "[7 1 49]", "APD Low Gain Mode High Thresh");
+ if(apdLowGainModeHighThresh) {
+ apdSection->contentLayout()->addWidget(apdLowGainModeHighThresh);
+ }
+
+ // APD Low Thresh - Range Widget [7 1 49]
+ auto apdLowThresh = Adrv9009WidgetFactory::createRangeWidget(m_device, "adi,rxagc-peak-apd-low-thresh",
+ "[7 1 49]", "APD Low Thresh");
+ if(apdLowThresh) {
+ apdSection->contentLayout()->addWidget(apdLowThresh);
+ }
+
+ // APD Low Gain Mode Low Thresh - Range Widget [7 1 49]
+ auto apdLowGainModeLowThresh = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-apd-low-gain-mode-low-thresh", "[7 1 49]", "APD Low Gain Mode Low Thresh");
+ if(apdLowGainModeLowThresh) {
+ apdSection->contentLayout()->addWidget(apdLowGainModeLowThresh);
+ }
+
+ // APD Upper Thresh Peak Exceeded Count - Range Widget [0 1 255]
+ auto apdUpperThreshPeakExceededCnt =
+ Adrv9009WidgetFactory::createRangeWidget(m_device, "adi,rxagc-peak-apd-upper-thresh-peak-exceeded-cnt",
+ "[0 1 255]", "APD Upper Thresh Peak Exceeded Count");
+ if(apdUpperThreshPeakExceededCnt) {
+ apdSection->contentLayout()->addWidget(apdUpperThreshPeakExceededCnt);
+ }
+
+ // APD Lower Thresh Peak Exceeded Count - Range Widget [0 1 255]
+ auto apdLowerThreshPeakExceededCnt =
+ Adrv9009WidgetFactory::createRangeWidget(m_device, "adi,rxagc-peak-apd-lower-thresh-peak-exceeded-cnt",
+ "[0 1 255]", "APD Lower Thresh Peak Exceeded Count");
+ if(apdLowerThreshPeakExceededCnt) {
+ apdSection->contentLayout()->addWidget(apdLowerThreshPeakExceededCnt);
+ }
+
+ // APD Gain Step Attack - Range Widget [0 1 31]
+ auto apdGainStepAttack = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-apd-gain-step-attack", "[0 1 31]", "APD Gain Step Attack");
+ if(apdGainStepAttack) {
+ apdSection->contentLayout()->addWidget(apdGainStepAttack);
+ }
+
+ // APD Gain Step Recovery - Range Widget [0 1 31]
+ auto apdGainStepRecovery = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-apd-gain-step-recovery", "[0 1 31]", "APD Gain Step Recovery");
+ if(apdGainStepRecovery) {
+ apdSection->contentLayout()->addWidget(apdGainStepRecovery);
+ connect(this, &AgcSetupWidget::readRequested, apdGainStepRecovery, &IIOWidget::readAsync);
+ }
+
+ // === ALL HB2 ATTRIBUTES (MOVED TO CORRECT ANALOG PEAK DETECTOR SECTION) ===
+
+ // Enable HB2 Overload - Checkbox
+ auto enableHb2Overload = Adrv9009WidgetFactory::createCheckboxWidget(
+ m_device, "adi,rxagc-peak-enable-hb2-overload", "Enable HB2 Overload");
+ if(enableHb2Overload) {
+ apdSection->contentLayout()->addWidget(enableHb2Overload);
+ connect(this, &AgcSetupWidget::readRequested, enableHb2Overload, &IIOWidget::readAsync);
+ }
+
+ // HB2 Overload Duration Count - Range Widget [0 1 6]
+ auto hb2OverloadDurationCnt = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-hb2-overload-duration-cnt", "[0 1 6]", "HB2 Overload Duration Count");
+ if(hb2OverloadDurationCnt) {
+ apdSection->contentLayout()->addWidget(hb2OverloadDurationCnt);
+ connect(this, &AgcSetupWidget::readRequested, hb2OverloadDurationCnt, &IIOWidget::readAsync);
+ }
+
+ // HB2 Overload Thresh Count - Range Widget [1 1 15]
+ auto hb2OverloadThreshCnt = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-hb2-overload-thresh-cnt", "[1 1 15]", "HB2 Overload Thresh Count");
+ if(hb2OverloadThreshCnt) {
+ apdSection->contentLayout()->addWidget(hb2OverloadThreshCnt);
+ connect(this, &AgcSetupWidget::readRequested, hb2OverloadThreshCnt, &IIOWidget::readAsync);
+ }
+
+ // HB2 High Thresh - Range Widget [0 1 255]
+ auto hb2HighThresh = Adrv9009WidgetFactory::createRangeWidget(m_device, "adi,rxagc-peak-hb2-high-thresh",
+ "[0 1 255]", "HB2 High Thresh");
+ if(hb2HighThresh) {
+ apdSection->contentLayout()->addWidget(hb2HighThresh);
+ connect(this, &AgcSetupWidget::readRequested, hb2HighThresh, &IIOWidget::readAsync);
+ }
+
+ // HB2 Under Range Low Thresh - Range Widget [0 1 255]
+ auto hb2UnderRangeLowThresh = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-hb2-under-range-low-thresh", "[0 1 255]", "HB2 Under Range Low Thresh");
+ if(hb2UnderRangeLowThresh) {
+ apdSection->contentLayout()->addWidget(hb2UnderRangeLowThresh);
+ connect(this, &AgcSetupWidget::readRequested, hb2UnderRangeLowThresh, &IIOWidget::readAsync);
+ }
+
+ // HB2 Under Range Mid Thresh - Range Widget [0 1 255]
+ auto hb2UnderRangeMidThresh = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-hb2-under-range-mid-thresh", "[0 1 255]", "HB2 Under Range Mid Thresh");
+ if(hb2UnderRangeMidThresh) {
+ apdSection->contentLayout()->addWidget(hb2UnderRangeMidThresh);
+ connect(this, &AgcSetupWidget::readRequested, hb2UnderRangeMidThresh, &IIOWidget::readAsync);
+ }
+
+ // HB2 Under Range High Thresh - Range Widget [0 1 255]
+ auto hb2UnderRangeHighThresh = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-hb2-under-range-high-thresh", "[0 1 255]", "HB2 Under Range High Thresh");
+ if(hb2UnderRangeHighThresh) {
+ apdSection->contentLayout()->addWidget(hb2UnderRangeHighThresh);
+ connect(this, &AgcSetupWidget::readRequested, hb2UnderRangeHighThresh, &IIOWidget::readAsync);
+ }
+
+ // HB2 Upper Thresh Peak Exceeded Count - Range Widget [0 1 255]
+ auto hb2UpperThreshPeakExceededCnt =
+ Adrv9009WidgetFactory::createRangeWidget(m_device, "adi,rxagc-peak-hb2-upper-thresh-peak-exceeded-cnt",
+ "[0 1 255]", "HB2 Upper Thresh Peak Exceeded Count");
+ if(hb2UpperThreshPeakExceededCnt) {
+ apdSection->contentLayout()->addWidget(hb2UpperThreshPeakExceededCnt);
+ connect(this, &AgcSetupWidget::readRequested, hb2UpperThreshPeakExceededCnt, &IIOWidget::readAsync);
+ }
+
+ // HB2 Lower Thresh Peak Exceeded Count - Range Widget [0 1 255]
+ auto hb2LowerThreshPeakExceededCnt =
+ Adrv9009WidgetFactory::createRangeWidget(m_device, "adi,rxagc-peak-hb2-lower-thresh-peak-exceeded-cnt",
+ "[0 1 255]", "HB2 Lower Thresh Peak Exceeded Count");
+ if(hb2LowerThreshPeakExceededCnt) {
+ apdSection->contentLayout()->addWidget(hb2LowerThreshPeakExceededCnt);
+ connect(this, &AgcSetupWidget::readRequested, hb2LowerThreshPeakExceededCnt, &IIOWidget::readAsync);
+ }
+
+ // HB2 Gain Step High Recovery - Range Widget [0 1 31]
+ auto hb2GainStepHighRecovery = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-hb2-gain-step-high-recovery", "[0 1 31]", "HB2 Gain Step High Recovery");
+ if(hb2GainStepHighRecovery) {
+ apdSection->contentLayout()->addWidget(hb2GainStepHighRecovery);
+ connect(this, &AgcSetupWidget::readRequested, hb2GainStepHighRecovery, &IIOWidget::readAsync);
+ }
+
+ // HB2 Gain Step Low Recovery - Range Widget [0 1 31]
+ auto hb2GainStepLowRecovery = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-hb2-gain-step-low-recovery", "[0 1 31]", "HB2 Gain Step Low Recovery");
+ if(hb2GainStepLowRecovery) {
+ apdSection->contentLayout()->addWidget(hb2GainStepLowRecovery);
+ connect(this, &AgcSetupWidget::readRequested, hb2GainStepLowRecovery, &IIOWidget::readAsync);
+ }
+
+ // HB2 Gain Step Mid Recovery - Range Widget [0 1 31]
+ auto hb2GainStepMidRecovery = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-hb2-gain-step-mid-recovery", "[0 1 31]", "HB2 Gain Step Mid Recovery");
+ if(hb2GainStepMidRecovery) {
+ apdSection->contentLayout()->addWidget(hb2GainStepMidRecovery);
+ connect(this, &AgcSetupWidget::readRequested, hb2GainStepMidRecovery, &IIOWidget::readAsync);
+ }
+
+ // HB2 Gain Step Attack - Range Widget [0 1 31]
+ auto hb2GainStepAttack = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-peak-hb2-gain-step-attack", "[0 1 31]", "HB2 Gain Step Attack");
+ if(hb2GainStepAttack) {
+ apdSection->contentLayout()->addWidget(hb2GainStepAttack);
+ connect(this, &AgcSetupWidget::readRequested, hb2GainStepAttack, &IIOWidget::readAsync);
+ }
+
+ // HB2 Overload Power Mode - Checkbox
+ auto hb2OverloadPowerMode = Adrv9009WidgetFactory::createCheckboxWidget(
+ m_device, "adi,rxagc-peak-hb2-overload-power-mode", "HB2 Overload Power Mode");
+ if(hb2OverloadPowerMode) {
+ apdSection->contentLayout()->addWidget(hb2OverloadPowerMode);
+ connect(this, &AgcSetupWidget::readRequested, hb2OverloadPowerMode, &IIOWidget::readAsync);
+ }
+
+ // HB2 OVRG Sel - Checkbox
+ auto hb2OvrgSel =
+ Adrv9009WidgetFactory::createCheckboxWidget(m_device, "adi,rxagc-peak-hb2-ovrg-sel", "HB2 OVRG Sel");
+ if(hb2OvrgSel) {
+ apdSection->contentLayout()->addWidget(hb2OvrgSel);
+ connect(this, &AgcSetupWidget::readRequested, hb2OvrgSel, &IIOWidget::readAsync);
+ }
+
+ // HB2 Thresh Config - Checkbox
+ auto hb2ThreshConfig = Adrv9009WidgetFactory::createCheckboxWidget(m_device, "adi,rxagc-peak-hb2-thresh-config",
+ "HB2 Thresh Config");
+ if(hb2ThreshConfig) {
+ apdSection->contentLayout()->addWidget(hb2ThreshConfig);
+ connect(this, &AgcSetupWidget::readRequested, hb2ThreshConfig, &IIOWidget::readAsync);
+ }
+
+ contentLayout->addWidget(apdSection);
+
+ // 3. Power Measurement Detector section (15 attributes - adi,rxagc-power-* only)
+ MenuSectionCollapseWidget *powerSection =
+ new MenuSectionCollapseWidget("Power Measurement Detector", MenuCollapseSection::MHCW_ARROW,
+ MenuCollapseSection::MHW_BASEWIDGET, contentWidget);
+
+ // Power Enable Measurement - Checkbox
+ auto powerEnableMeasurement = Adrv9009WidgetFactory::createCheckboxWidget(
+ m_device, "adi,rxagc-power-power-enable-measurement", "Power Enable Measurement");
+ if(powerEnableMeasurement) {
+ powerSection->contentLayout()->addWidget(powerEnableMeasurement);
+ connect(this, &AgcSetupWidget::readRequested, powerEnableMeasurement, &IIOWidget::readAsync);
+ }
+
+ // Power Use RFIR Out - Checkbox
+ auto powerUseRfirOut = Adrv9009WidgetFactory::createCheckboxWidget(
+ m_device, "adi,rxagc-power-power-use-rfir-out", "Power Use RFIR Out");
+ if(powerUseRfirOut) {
+ powerSection->contentLayout()->addWidget(powerUseRfirOut);
+ connect(this, &AgcSetupWidget::readRequested, powerUseRfirOut, &IIOWidget::readAsync);
+ }
+
+ // Power Use BBDC2 - Checkbox
+ auto powerUseBbdc2 = Adrv9009WidgetFactory::createCheckboxWidget(m_device, "adi,rxagc-power-power-use-bbdc2",
+ "Power Use BBDC2");
+ if(powerUseBbdc2) {
+ powerSection->contentLayout()->addWidget(powerUseBbdc2);
+ connect(this, &AgcSetupWidget::readRequested, powerUseBbdc2, &IIOWidget::readAsync);
+ }
+
+ // Under Range High Power Thresh - Range Widget [0 1 127]
+ auto underRangeHighPowerThresh =
+ Adrv9009WidgetFactory::createRangeWidget(m_device, "adi,rxagc-power-under-range-high-power-thresh",
+ "[0 1 127]", "Under Range High Power Thresh");
+ if(underRangeHighPowerThresh) {
+ powerSection->contentLayout()->addWidget(underRangeHighPowerThresh);
+ connect(this, &AgcSetupWidget::readRequested, underRangeHighPowerThresh, &IIOWidget::readAsync);
+ }
+
+ // Under Range Low Power Thresh - Range Widget [0 1 31]
+ auto underRangeLowPowerThresh = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-power-under-range-low-power-thresh", "[0 1 31]", "Under Range Low Power Thresh");
+ if(underRangeLowPowerThresh) {
+ powerSection->contentLayout()->addWidget(underRangeLowPowerThresh);
+ connect(this, &AgcSetupWidget::readRequested, underRangeLowPowerThresh, &IIOWidget::readAsync);
+ }
+
+ // Under Range High Power Gain Step Recovery - Range Widget [0 1 31]
+ auto underRangeHighPowerGainStepRecovery = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-power-under-range-high-power-gain-step-recovery", "[0 1 31]",
+ "Under Range High Power Gain Step Recovery");
+ if(underRangeHighPowerGainStepRecovery) {
+ powerSection->contentLayout()->addWidget(underRangeHighPowerGainStepRecovery);
+ connect(this, &AgcSetupWidget::readRequested, underRangeHighPowerGainStepRecovery,
+ &IIOWidget::readAsync);
+ }
+
+ // Under Range Low Power Gain Step Recovery - Range Widget [0 1 31]
+ auto underRangeLowPowerGainStepRecovery = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-power-under-range-low-power-gain-step-recovery", "[0 1 31]",
+ "Under Range Low Power Gain Step Recovery");
+ if(underRangeLowPowerGainStepRecovery) {
+ powerSection->contentLayout()->addWidget(underRangeLowPowerGainStepRecovery);
+ connect(this, &AgcSetupWidget::readRequested, underRangeLowPowerGainStepRecovery,
+ &IIOWidget::readAsync);
+ }
+
+ // Power Measurement Duration - Range Widget [0 1 31]
+ auto powerMeasurementDuration = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-power-power-measurement-duration", "[0 1 31]", "Power Measurement Duration");
+ if(powerMeasurementDuration) {
+ powerSection->contentLayout()->addWidget(powerMeasurementDuration);
+ connect(this, &AgcSetupWidget::readRequested, powerMeasurementDuration, &IIOWidget::readAsync);
+ }
+
+ // RX1/RX2 TDD Power Controls - Two-column layout
+ QHBoxLayout *tddColumnsLayout = new QHBoxLayout();
+ tddColumnsLayout->setContentsMargins(0, 0, 0, 0);
+ tddColumnsLayout->setSpacing(20);
+
+ // Create RX1 TDD column (left)
+ QWidget *rx1TddColumn = createRxTddPowerGroup(1, powerSection);
+ tddColumnsLayout->addWidget(rx1TddColumn);
+
+ // Create RX2 TDD column (right)
+ QWidget *rx2TddColumn = createRxTddPowerGroup(2, powerSection);
+ tddColumnsLayout->addWidget(rx2TddColumn);
+
+ // Create container widget for TDD columns layout
+ QWidget *tddColumnsContainer = new QWidget();
+ tddColumnsContainer->setLayout(tddColumnsLayout);
+
+ // Add TDD columns container to power section
+ powerSection->contentLayout()->addWidget(tddColumnsContainer);
+
+ // Upper0 Power Thresh - Range Widget [0 1 127]
+ auto upper0PowerThresh = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-power-upper0-power-thresh", "[0 1 127]", "Upper0 Power Thresh");
+ if(upper0PowerThresh) {
+ powerSection->contentLayout()->addWidget(upper0PowerThresh);
+ connect(this, &AgcSetupWidget::readRequested, upper0PowerThresh, &IIOWidget::readAsync);
+ }
+
+ // Upper1 Power Thresh - Range Widget [0 1 15]
+ auto upper1PowerThresh = Adrv9009WidgetFactory::createRangeWidget(
+ m_device, "adi,rxagc-power-upper1-power-thresh", "[0 1 15]", "Upper1 Power Thresh");
+ if(upper1PowerThresh) {
+ powerSection->contentLayout()->addWidget(upper1PowerThresh);
+ connect(this, &AgcSetupWidget::readRequested, upper1PowerThresh, &IIOWidget::readAsync);
+ }
+
+ // Power Log Shift - Checkbox
+ auto powerLogShift = Adrv9009WidgetFactory::createCheckboxWidget(m_device, "adi,rxagc-power-power-log-shift",
+ "Power Log Shift");
+ if(powerLogShift) {
+ powerSection->contentLayout()->addWidget(powerLogShift);
+ connect(this, &AgcSetupWidget::readRequested, powerLogShift, &IIOWidget::readAsync);
+ }
+
+ contentLayout->addWidget(powerSection);
+
+ // Add spacer to push sections to top
+ contentLayout->addItem(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
+
+ // Set up scroll area
+ scrollArea->setWidget(contentWidget);
+ mainLayout->addWidget(scrollArea);
+
+ qDebug(CAT_AGCSETUP) << "AGC Setup widget created with 63 attributes in 3 collapsible sections";
+}
+
+QWidget *AgcSetupWidget::createRxTddPowerGroup(int channel, QWidget *parent)
+{
+ // Create container widget for RX channel TDD power controls
+ QWidget *channelWidget = new QWidget(parent);
+ Style::setStyle(channelWidget, style::properties::widget::border);
+
+ // Create vertical layout for this channel
+ QVBoxLayout *channelLayout = new QVBoxLayout(channelWidget);
+ channelLayout->setContentsMargins(10, 10, 10, 10);
+ channelLayout->setSpacing(10);
+
+ // Add header label
+ QLabel *headerLabel = new QLabel(QString("RX%1").arg(channel));
+ Style::setStyle(headerLabel, style::properties::label::menuMedium);
+ headerLabel->setAlignment(Qt::AlignCenter);
+ channelLayout->addWidget(headerLabel);
+
+ // Create widgets based on channel number
+ QString durationAttr = QString("adi,rxagc-power-rx%1-tdd-power-meas-duration").arg(channel);
+ QString delayAttr = QString("adi,rxagc-power-rx%1-tdd-power-meas-delay").arg(channel);
+
+ // TDD Power Meas Duration - Range Widget [0 1 65535]
+ auto durationWidget = Adrv9009WidgetFactory::createRangeWidget(m_device, durationAttr, "[0 1 65535]",
+ "TDD POWER MEAS DURATION");
+ if(durationWidget) {
+ channelLayout->addWidget(durationWidget);
+ connect(this, &AgcSetupWidget::readRequested, durationWidget, &IIOWidget::readAsync);
+ }
+
+ // TDD Power Meas Delay - Range Widget [0 1 65535]
+ auto delayWidget =
+ Adrv9009WidgetFactory::createRangeWidget(m_device, delayAttr, "[0 1 65535]", "TDD POWER MEAS DELAY");
+ if(delayWidget) {
+ channelLayout->addWidget(delayWidget);
+ connect(this, &AgcSetupWidget::readRequested, delayWidget, &IIOWidget::readAsync);
+ }
+
+ return channelWidget;
+}
+
+QWidget *AgcSetupWidget::createAgcRxChannelGroup(const QString &baseAttr, const QString &displayName,
+ const QString &range, QWidget *parent)
+{
+ // Create container widget with proper Scopy styling
+ QWidget *channelWidget = new QWidget(parent);
+ Style::setStyle(channelWidget, style::properties::widget::border);
+
+ // Create horizontal layout for RX1/RX2 columns
+ QHBoxLayout *channelLayout = new QHBoxLayout(channelWidget);
+ channelLayout->setContentsMargins(10, 10, 10, 10);
+ channelLayout->setSpacing(20);
+
+ // Add combined label with proper Scopy styling hierarchy
+ QLabel *headerLabel = new QLabel(QString("RX1/RX2 %1").arg(displayName));
+ Style::setStyle(headerLabel, style::properties::label::menuMedium);
+ headerLabel->setAlignment(Qt::AlignCenter);
+ channelLayout->addWidget(headerLabel);
+
+ // Create RX1 widget
+ QString rx1Attr = QString(baseAttr).arg(1);
+ auto rx1Widget =
+ Adrv9009WidgetFactory::createRangeWidget(m_device, rx1Attr, range, QString("RX1 %1").arg(displayName));
+ if(rx1Widget) {
+ channelLayout->addWidget(rx1Widget);
+ connect(this, &AgcSetupWidget::readRequested, rx1Widget, &IIOWidget::readAsync);
+ }
+
+ // Create RX2 widget
+ QString rx2Attr = QString(baseAttr).arg(2);
+ auto rx2Widget =
+ Adrv9009WidgetFactory::createRangeWidget(m_device, rx2Attr, range, QString("RX2 %1").arg(displayName));
+ if(rx2Widget) {
+ channelLayout->addWidget(rx2Widget);
+ connect(this, &AgcSetupWidget::readRequested, rx2Widget, &IIOWidget::readAsync);
+ }
+
+ return channelWidget;
+}