diff --git a/plugins/adrv9002.c b/plugins/adrv9002.c
index c2f3d8e6..d95e9091 100644
--- a/plugins/adrv9002.c
+++ b/plugins/adrv9002.c
@@ -37,6 +37,7 @@
#define NUM_MAX_ORX_WIDGETS 3
#define NUM_MAX_DDS 2
#define NUM_MAX_ADC 2
+#define NUM_DEVICE_MAX_WIDGETS 1
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -111,6 +112,8 @@ struct plugin_private {
char last_profile[PATH_MAX];
char last_stream[PATH_MAX];
struct adrv9002_gtklabel temperature;
+ struct iio_widget device_w[NUM_DEVICE_MAX_WIDGETS];
+ int num_widgets;
/* rx */
struct adrv9002_rx rx_widgets[ADRV9002_NUM_CHANNELS];
/* tx */
@@ -392,6 +395,24 @@ static void adrv9002_save_carrier_freq(GtkWidget *widget, struct adrv9002_common
iio_widget_update_block_signals_by_data(&chan->carrier);
}
+static void adrv9002_show_help(GtkWidget *widget, void *unused)
+{
+ dialog_box_message_info(widget, "Initial Calibrations Help",
+"off: Initial calibrations won't run automatically.\n"
+"auto: Initial calibrations will run automatically for Carrier changes bigger or equal to 100MHz.\n\n"
+"To manually run the calibrations, press the \"Calibrate now\" button!");
+}
+
+static void adrv9002_run_cals(GtkWidget *widget, struct plugin_private *priv)
+{
+ ssize_t ret;
+
+ ret = iio_device_attr_write(priv->adrv9002, "initial_calibrations", "run");
+ if (ret < 0)
+ dialog_box_message_error(widget, "Initial Calibrations",
+ "Failed to re-run Initial Calibrations");
+}
+
static double adrv9002_bbdc_loop_gain_convert(double val, bool updating)
{
double loop_gain;
@@ -1382,6 +1403,28 @@ static void adrv9002_api_version_report(struct plugin_private *priv)
gtk_label_set_label(gapi, api_version);
}
+static void adrv9002_initial_calibrations_init(struct plugin_private *priv)
+{
+ GObject *run = gtk_builder_get_object(priv->builder, "initial_calibrations_run");
+ GObject *help = gtk_builder_get_object(priv->builder, "initial_calibrations_help");
+ int n_w = priv->num_widgets;
+
+ /* initial calibrations */
+ adrv9002_combo_box_init(&priv->device_w[priv->num_widgets++], "initial_calibrations",
+ "initial_calibrations", "initial_calibrations_available", priv, NULL);
+
+ /*
+ * This will remove the "run" option from the list. Let's provide a dedicated button for
+ * it since the driver never reads back "run" from the attribute and that would make for
+ * a poor user experience. With a dedicated button, we can also tell if some error occurred
+ * or not...
+ */
+ gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(priv->device_w[n_w].widget), 2);
+
+ g_signal_connect(run, "clicked", G_CALLBACK(adrv9002_run_cals), priv);
+ g_signal_connect(help, "clicked", G_CALLBACK(adrv9002_show_help), NULL);
+}
+
static GtkWidget *adrv9002_init(struct osc_plugin *plugin, GtkWidget *notebook,
const char *ini_fn)
{
@@ -1490,6 +1533,8 @@ static GtkWidget *adrv9002_init(struct osc_plugin *plugin, GtkWidget *notebook,
adrv9002_gtk_label_init(priv, &priv->temperature, temp, "input", "temperature", 1000);
+ adrv9002_initial_calibrations_init(priv);
+
/* init dds container */
ret = adrv9002_dds_init(priv);
if (ret)
@@ -1519,6 +1564,12 @@ static GtkWidget *adrv9002_init(struct osc_plugin *plugin, GtkWidget *notebook,
priv->tx_widgets[i].num_widgets,
G_CALLBACK(iio_widget_save_block_signals_by_data_cb));
}
+
+ /* device widgets */
+ iio_update_widgets(priv->device_w, priv->num_widgets);
+ iio_make_widgets_update_signal_based(priv->device_w, priv->num_widgets,
+ G_CALLBACK(iio_widget_save_block_signals_by_data_cb));
+
/* update dac */
for (i = 0; i < priv->n_dacs; i++)
dac_data_manager_update_iio_widgets(priv->dac_manager[i].dac_tx_manager);