From 0b4ef7e4d04ff3861b007c94766c4269cfe1c2bc Mon Sep 17 00:00:00 2001
From: DL1YCF <dl1ycf@darc.de>
Date: Thu, 30 Dec 2021 12:04:56 +0100
Subject: [PATCH] Split "radio_band_changed" into "set_alex_antennas" and
 "tx_vfo_changed".

---
 ant_menu.c   |  4 ++--
 radio.c      | 53 +++++++++++++++++++++++++++++++++-------------------
 radio_menu.c |  2 +-
 receiver.c   |  6 +++++-
 vfo.c        | 39 +++++++++++++++++++-------------------
 5 files changed, 62 insertions(+), 42 deletions(-)

diff --git a/ant_menu.c b/ant_menu.c
index 28bf6e9..681b313 100644
--- a/ant_menu.c
+++ b/ant_menu.c
@@ -65,7 +65,7 @@ static void rx_ant_cb(GtkToggleButton *widget, gpointer data) {
     int ant=(GPOINTER_TO_UINT(data))&0xF;
     BAND *band=band_get_band(b);
     band->alexRxAntenna=ant;
-    radio_band_changed();
+    set_alex_antennas();
   }
 }
 
@@ -99,7 +99,7 @@ static void tx_ant_cb(GtkToggleButton *widget, gpointer data) {
     int ant=(GPOINTER_TO_UINT(data))&0xF;
     BAND *band=band_get_band(b);
     band->alexTxAntenna=ant;
-    radio_band_changed();
+    set_alex_antennas();
   }
 }
 
diff --git a/radio.c b/radio.c
index ea18a72..2b0ec24 100644
--- a/radio.c
+++ b/radio.c
@@ -1902,19 +1902,15 @@ void set_attenuation(int value) {
     }
 }
 
-//
-// Upon each band change, the TX mode needs be specified again.
-// For HPSDR, one also needs new RX/TX antenna and PA calibration/disable settings.
-// For TX, this must also happen when changing the active receiver or the "split" status.
-// To avoid code duplications, the necessary actions are bundled here.
-// If the attenuation is stored with the band, this should also be adjusted here
-//
-void radio_band_changed() {
+void set_alex_antennas() {
+  //
+  // Obtain band of VFO-A and transmitter, set ALEX RX/TX antennas
+  // This function is a no-op when running SOAPY.
+  // This function also takes care of updating the PA dis/enable
+  // status for P2.
+  //
   BAND *band;
   if (protocol == ORIGINAL_PROTOCOL || protocol == NEW_PROTOCOL) {
-    //
-    // Obtain band of VFO-A and transmitter, set ALEX RX/TX antennas
-    //
     band=band_get_band(vfo[VFO_A].band);
     receiver[0]->alex_antenna=band->alexRxAntenna;
     receiver[0]->alex_attenuation=band->alexAttenuation;
@@ -1924,21 +1920,38 @@ void radio_band_changed() {
       transmitter->alex_antenna=band->alexTxAntenna;
     }
   }
+  if (protocol == NEW_PROTOCOL) {
+    schedule_high_priority();         // possibly update RX/TX antennas
+    schedule_general();               // possibly update PA disable
+  }
+}
+
+void tx_vfo_changed() {
+  //
+  // When changing the active receiver or changing the split status,
+  // the VFO that controls the transmitter my flip between VFOA/VFOB.
+  // In these cases, we have to update the TX mode,
+  // and re-calculate the drive level from the band-specific PA calibration
+  // values. For SOAPY, the only thing to do is the update the TX mode.
+  //
+  // Note each time tx_vfo_changed() is called, calling set_alex_antennas()
+  // is also due.
+  //
   if (can_transmit) {
     tx_set_mode(transmitter,get_tx_mode());
     calcDriveLevel();
   }
-
   if (protocol == NEW_PROTOCOL) {
     schedule_high_priority();         // possibly update RX/TX antennas
     schedule_general();               // possibly update PA disable
   }
 }
 
-//
-// For HPSDR, only receiver[0]->alex_attenuation has an effect
-//
 void set_alex_attenuation(int v) {
+    //
+    // The value of the "old" ALEX step-attenuator is stored in
+    // the receiver[0] data structure
+    //
     BAND *band;
     if (protocol == ORIGINAL_PROTOCOL || protocol == NEW_PROTOCOL) {
       //
@@ -1954,13 +1967,15 @@ void set_alex_attenuation(int v) {
     }
 }
 
-//
-// Interface to set split state
-//
 void radio_set_split(int val) {
+  //
+  // "split" *must only* be set through this interface,
+  // since it may change the TX band
+  //
   if (can_transmit) {
     split=val;
-    radio_band_changed();
+    tx_vfo_changed();
+    set_alex_antennas();
     g_idle_add(ext_vfo_update, NULL);
   }
 }
diff --git a/radio_menu.c b/radio_menu.c
index 4e69074..f7071fe 100644
--- a/radio_menu.c
+++ b/radio_menu.c
@@ -294,7 +294,7 @@ void load_filters(void) {
     case APOLLO:
     case CHARLY25:
         // This is most likely not necessary here, but can do no harm
-        radio_band_changed();
+        set_alex_antennas();
         break;
     case NONE:
         break;
diff --git a/receiver.c b/receiver.c
index c14e1af..d350565 100644
--- a/receiver.c
+++ b/receiver.c
@@ -94,7 +94,11 @@ void receiver_set_active(RECEIVER *rx) {
   g_idle_add(ext_vfo_update,NULL);
   g_idle_add(zoompan_active_receiver_changed,NULL);
   g_idle_add(sliders_active_receiver_changed,NULL);
-  radio_band_changed();
+  //
+  // Changing the active receiver flips the TX vfo
+  //
+  tx_vfo_changed();
+  set_alex_antennas();
 }
 
 gboolean receiver_button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data) {
diff --git a/vfo.c b/vfo.c
index 85828be..90bdea5 100644
--- a/vfo.c
+++ b/vfo.c
@@ -438,18 +438,18 @@ void vfo_band_changed(int id,int b) {
       }
       break;
   }
-  radio_band_changed();
-
-  switch(protocol) {
-    case NEW_PROTOCOL:
-      schedule_general();
-      break;
+  tx_vfo_changed(); 
+  set_alex_antennas();  // This includes scheduling hiprio and general packets
 #ifdef SOAPYSDR
-    case SOAPYSDR_PROTOCOL:
-      soapy_protocol_set_rx_frequency(active_receiver,id);
-      break;
-#endif
+  //
+  // This is strange, since it already done via receiver_vfo_changed()
+  // correctly and the present code seems to be wrong if
+  // (receivers == 1 && id == 1) or (receivers == 2 && id == 0)
+  //
+  if (protocol == SOAPYSDR_PROTOCOL) {
+    soapy_protocol_set_rx_frequency(active_receiver,id);
   }
+#endif
   g_idle_add(ext_vfo_update,NULL);
 }
 
@@ -477,13 +477,9 @@ void vfo_bandstack_changed(int b) {
       }
       break;
   }
-  //
-  // I do not think the band can change within this function.
-  // But out of paranoia, I consider this possiblity here
-  //
-  radio_band_changed();
+  tx_vfo_changed(); 
+  set_alex_antennas();  // This includes scheduling hiprio and general packets
   g_idle_add(ext_vfo_update,NULL);
-
 }
 
 void vfo_mode_changed(int m) {
@@ -567,7 +563,8 @@ void vfo_a_to_b() {
   if(receivers==2) {
     receiver_vfo_changed(receiver[1]);
   }
-  radio_band_changed();
+  tx_vfo_changed();
+  set_alex_antennas();  // This includes scheduling hiprio and general packets
   g_idle_add(ext_vfo_update,NULL);
 }
 
@@ -585,7 +582,8 @@ void vfo_b_to_a() {
   vfo[VFO_A].offset=vfo[VFO_B].offset;
 
   receiver_vfo_changed(receiver[0]);
-  radio_band_changed();
+  tx_vfo_changed();
+  set_alex_antennas();  // This includes scheduling hiprio and general packets
   g_idle_add(ext_vfo_update,NULL);
 }
 
@@ -642,7 +640,8 @@ void vfo_a_swap_b() {
   if(receivers==2) {
     receiver_vfo_changed(receiver[1]);
   }
-  radio_band_changed();
+  tx_vfo_changed();
+  set_alex_antennas();  // This includes scheduling hiprio and general packets
   g_idle_add(ext_vfo_update,NULL);
 }
 
@@ -1518,6 +1517,8 @@ void vfo_set_frequency(int v,long long f) {
     if (receivers == 2) {
       // VFO v controls a running  WDSP receiver,
       // need to "manually change" it.
+      // DO NOT DO IT HERE. Better add a "RECEIVER *rx" argument
+      // to setFrequency in radio.c
     }
   }
   g_idle_add(ext_vfo_update, NULL);
-- 
2.45.2