]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Finalized things.
authorc vw <dl1ycf@darc.de>
Fri, 26 Jul 2019 16:05:53 +0000 (18:05 +0200)
committerc vw <dl1ycf@darc.de>
Fri, 26 Jul 2019 16:05:53 +0000 (18:05 +0200)
Makefile
Makefile.mac
README.MacOS
alex.h
new_protocol.c
old_discovery.c
old_protocol.c
ps_menu.c
radio.c
rx_menu.c
transmitter.c

index f3a8cf4c079a4eeeb41fd264b59c25c96d0d29b0..8bf0d1438b2bdc2a9a4c47a1bceebba2efe96ecb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -33,9 +33,6 @@ GIT_VERSION := $(shell git describe --abbrev=0 --tags)
 # uncomment the line below to include support for STEMlab discovery (WITHOUT AVAHI)
 #STEMLAB_DISCOVERY=STEMLAB_DISCOVERY_NOAVAHI
 
-# uncommment this line for circumventing problems with RedPitya HPSDR apps.
-#STEMLAB_FIX_OPTION=-DSTEMLAB_FIX
-
 # uncomment the line below to include support for Pi SDR
 #PI_SDR_INCLUDE=PI_SDR
 
@@ -214,7 +211,7 @@ AUDIO_LIBS=-lasound
 
 OPTIONS=-g -Wno-deprecated-declarations $(MIDI_OPTIONS) $(PURESIGNAL_OPTIONS) $(REMOTE_OPTIONS) $(USBOZY_OPTIONS) \
        $(I2C_OPTIONS) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(RADIOBERRY_OPTIONS) \
-       $(PI_SDR_OPTIONS) $(PSK_OPTIONS) $(STEMLAB_OPTIONS) $(STEMLAB_FIX_OPTION) \
+       $(PI_SDR_OPTIONS) $(PSK_OPTIONS) $(STEMLAB_OPTIONS) \
        -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(DEBUG_OPTION) -O3
 
 LIBS=-lrt -lm -lwdsp -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(PSKLIBS) $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS) $(STEMLAB_LIBS) $(MIDI_LIBS)
index e3fc0509c6c37c2bebcd56d6aeb23b6e6b4551f4..0095644330008beaa36c6408b520e43ab55098ec 100644 (file)
@@ -30,9 +30,6 @@ PURESIGNAL_INCLUDE=PURESIGNAL
 # uncomment the line below to include support for STEMlab discovery (WITHOUT AVAHI)
 STEMLAB_DISCOVERY=STEMLAB_DISCOVERY_NOAVAHI
 
-# uncommment this line for circumventing problems with RedPitya HPSDR apps.
-STEMLAB_FIX_OPTION=-DSTEMLAB_FIX
-
 # uncomment the line below to include support for Pi SDR
 #PI_SDR_INCLUDE=PI_SDR
 
@@ -199,7 +196,7 @@ PORTAUDIO_OPTIONS=-DPORTAUDIO
 AUDIO_LIBS=-lportaudio
 
 OPTIONS=-g -Wno-deprecated-declarations $(MIDI_OPTIONS) $(PURESIGNAL_OPTIONS) $(REMOTE_OPTIONS) $(USBOZY_OPTIONS) $(I2C_OPTIONS) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) \
-                $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(RADIOBERRY_OPTIONS) $(PI_SDR_OPTIONS) $(PSK_OPTIONS) $(STEMLAB_OPTIONS) $(STEMLAB_FIX_OPTION) \
+                $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(RADIOBERRY_OPTIONS) $(PI_SDR_OPTIONS) $(PSK_OPTIONS) $(STEMLAB_OPTIONS) \
                 -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(PORTAUDIO_OPTIONS) $(DEBUG_OPTION) -O3
 
 LIBS=-lm -lwdsp -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(PSKLIBS) $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS) $(STEMLAB_LIBS) $(MIDI_LIBS)
index b2a88d2096f4d33ffb183cdbe04f56552ac80d08..02253d704c95ed0552d3a2d9e72ff3faea55f2d5 100644 (file)
@@ -107,7 +107,6 @@ That's easy. Just adjust the Makefile according to the instructions found there
 and type "make". In my case (I have a HAMLAB RedPitaya-based SDR box), I need
 the following options in the Makefile (and have all others commented out):
 
-STEMLAB_FIX_OPTION=-DSTEMLAB_FIX
 STEMLAB_DISCOVERY=STEMLAB_DISCOVERY_MAC
 
 
diff --git a/alex.h b/alex.h
index ca9c38b1196211dc822e63a8bf5648f87d6edb6e..6341cac30cfdf2f585b0f73b4d2f5196d5bcd07a 100644 (file)
--- a/alex.h
+++ b/alex.h
 // For ANAN-7000/8000, there are furthermore ALEX1 bits for the filter
 // board of the second RX.
 //
+// One note about bit 11 (controlling relay K36)
+//
+// On older (Rev 15/16) filter boards, K36 switches an output (ByPass)
+// On newer (Rev 24)    filter boards, K36 switches an input  (ByPass)
+//
+// That is, we use bit 11 ONLY when "RX BYPASS" is selected as the *input*
+// for the PS feedback signal. If you select "RX BYPASS" for the old
+// ANAN-100 boards PS will not work, you have to use EXT1.
+//
+//
 #define ALEX_RX_ANTENNA_NONE   0x00000000              // route Ant1,2,2 to RX1
-#define ALEX_RX_ANTENNA_XVTR   0x00000900              // route XVTR-in  to RX1
-#define ALEX_RX_ANTENNA_EXT1   0x00000A00              // route EXT1     to RX1
-#define ALEX_RX_ANTENNA_EXT2   0x00000C00              // jOUTE EXT2     to RX1
-#define ALEX_RX_ANTENNA_BYPASS 0x00000800              // disconnect RX1 from Ant1,2,3
+#define ALEX_RX_ANTENNA_XVTR   0x00000100              // route XVTR-in  to RX1 (bit 8)
+#define ALEX_RX_ANTENNA_EXT1   0x00000200              // route EXT1     to RX1 (bit 9)
+#define ALEX_RX_ANTENNA_EXT2   0x00000400              // route EXT2     to RX1 (bit 10)
+#define ALEX_RX_ANTENNA_BYPASS 0x00000800              // connect BYPASS to RX1 (bit 11)
 
 #define ALEX_TX_ANTENNA_1      0x01000000              // route TX to ANT1
 #define ALEX_TX_ANTENNA_2      0x02000000              // route TX to ANT2
index 5d83fa3ed2ddf4d19f8cd48ebdd66cb389eac5eb..dc784c3affb684da6bf965e52336beead5a5325e 100644 (file)
@@ -816,6 +816,31 @@ static void new_protocol_high_priority() {
     long alex0=0x00000000;
     long alex1=0x00000000;
 
+    if (device != NEW_DEVICE_ORION2) {
+      //
+      // ANAN7000 and 8000 do not have ALEX attenuators.
+      // Even worse, ALEX0(14) bit used to control these attenuators
+      // on ANAN-10/100/200 is now used differently.
+      //
+      // Note: ALEX attenuators are not much used anyway since we
+      //       have step attenuators on most boards.
+      //
+      switch (receiver[0]->alex_attenuation) {
+       case 0:
+         alex0 |= ALEX_ATTENUATION_0dB;
+         break;
+       case 1:
+         alex0 |= ALEX_ATTENUATION_10dB;
+         break;
+       case 2:
+         alex0 |= ALEX_ATTENUATION_20dB;
+         break;
+       case 3:
+         alex0 |= ALEX_ATTENUATION_30dB;
+         break;
+      }
+    }
+
     if(isTransmitting()) {
       alex0 |= ALEX_TX_RELAY;
       if(transmitter->puresignal) {
@@ -856,8 +881,14 @@ static void new_protocol_high_priority() {
       default:
 //
 //     Old (ANAN-100/200) high-pass filters
+//      Bypass HPFs while using EXT1 for PURESIGNAL feedback!
 //
-        if(rxFrequency<1800000L) {
+       i=0;  // flag used here for "filter bypass"
+       if (rxFrequency<1800000L) i=1;
+#ifdef PURESIGNAL
+       if (isTransmitting() && transmitter->puresignal && receiver[PS_RX_FEEDBACK]->alex_antenna == 6) i=1;
+#endif
+        if (i) {
           alex0|=ALEX_BYPASS_HPF;
         } else if(rxFrequency<6500000L) {
           alex0|=ALEX_1_5MHZ_HPF;
@@ -929,12 +960,15 @@ static void new_protocol_high_priority() {
 //  ANAN-7000 routes signals differently (these bits have no function on ANAN-80000)
 //            and uses ALEX0(14) to connnect Ext/XvrtIn to the RX.
 //
-    i=receiver[0]->alex_antenna;
+    i=receiver[0]->alex_antenna;                       // 0,1,2  or 3,4,5
+#ifdef PURESIGNAL
     if (isTransmitting() && transmitter->puresignal) {
-       i=receiver[PS_RX_FEEDBACK]->alex_antenna;   // 0, 3, or 4
+       i=receiver[PS_RX_FEEDBACK]->alex_antenna;       // 0, 6, or 7
     }
+#endif
     if (device == NEW_DEVICE_ORION2) i +=100;
     switch(i) {
+       case 6:  // EXT 1 for PS feedback
         case 3:  // EXT 1
           alex0|=ALEX_RX_ANTENNA_EXT1;
           break;
@@ -944,32 +978,33 @@ static void new_protocol_high_priority() {
         case 5:  // XVTR
             alex0|=ALEX_RX_ANTENNA_XVTR;
           break;
+       case 7: // RX_Bypass_In for PS feedback
+          alex0|=ALEX_RX_ANTENNA_BYPASS;
+          break;
        case 103:       // EXT1 on ANAN-7000
+       case 106:       // EXT1 on ANAN-7000 for PS feedback
          alex0|=ALEX_ANAN7000_RX_ANT_EXT1;
          break;
-       case 104:       // EXT2 means RxBypass on ANAN-7000
-         alex0|=ALEX_ANAN7000_RX_ANT_BYPASS;
+       case 104:
+         // no EXT2 jacket on ANAN7000!
          break;
        case 105:
          alex0|=ALEX_ANAN7000_RX_ANT_XVTR;
          break;
+       case 107:       // RxBypassIn on ANAN-7000
+         alex0|=ALEX_ANAN7000_RX_ANT_BYPASS;
+         break;
     }
 
 //
 //  Now we set the bits for Ant1/2/3 (RX and TX may be different)
-//  If RX is from none of Ant1/2/3, do not switch (leave these relays
-//  in TX state)
 //
-    if(isTransmitting() || (receiver[0]->alex_antenna > 2)) {
+    if(isTransmitting()) {
       i=transmitter->alex_antenna;
     } else {
       i=receiver[0]->alex_antenna;
     }
-    // i has value 0, 1, or 2.
     switch(i) {
-      default:
-       // should not happen, ignore silently and connect to ANT1
-       /* FALLTHROUGH */
       case 0:  // ANT 1
         alex0|=ALEX_TX_ANTENNA_1;
         break;
@@ -979,6 +1014,15 @@ static void new_protocol_high_priority() {
       case 2:  // ANT 3
         alex0|=ALEX_TX_ANTENNA_3;
         break;
+      default:
+       // this should not happen in TX case. Out of paranoia,
+        // connect ANT1 in this case
+       if (isTransmitting()) {
+         fprintf(stderr,"WARNING: illegal TX antenna chosen, using ANT1\n");
+         transmitter->alex_antenna=0;
+          alex0|=ALEX_TX_ANTENNA_1;
+       }
+       break;
     }
 
     high_priority_buffer_to_radio[1432]=(alex0>>24)&0xFF;
@@ -992,7 +1036,15 @@ static void new_protocol_high_priority() {
 //  Orion2 boards: set RX2 filters according ro VFOB frequency
 //
     if (device == NEW_DEVICE_ORION2) {
-        rxFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo;
+       //
+       // Note that while using DIVERSITY, the second RX filter settings must match
+       // those of the first RX
+       //
+       if (diversity_enabled) {
+          rxFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo;
+       } else {
+          rxFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo;
+       }
 //
 //      new ANAN-7000/8000 band-pass RX filters
 //      This info comes from file bpf2_select.v in the
index 086a3b9a0ea7426cdd37ce47f56dd0b26754a18a..48c48e59c0ab4d421ec7cfa9016a1d7fdfde117b 100644 (file)
@@ -428,8 +428,8 @@ fprintf(stderr,"discover_receive_thread\n");
                             strcpy(discovered[devices].name,"Orion2");
                             break;
                        case DEVICE_STEMLAB:
-                           // This is in principle the same as HERMES so pretend a HERMES
-                           discovered[devices].device = DEVICE_HERMES;
+                           // This is in principle the same as HERMES but has two ADCs
+                           // (and therefore, can do DIVERSITY).
                             strcpy(discovered[devices].name,"STEMlab");
                             break;
                         default:
index 38b16c69640b51b1ec5f635b8a2bc4197ea7425b..42f0b6bb6f660f1f36f47fb3f1db420836e32c43 100644 (file)
@@ -535,29 +535,189 @@ static gpointer receive_thread(gpointer arg) {
   return NULL;
 }
 
+//
+// To avoid overloading code with handling all the different cases
+// at various places,
+// we define here the channel number of the receivers, as well as the
+// number of HPSDR receivers to use (up to 5)
+// These are FIXED numbers and depend on the device and whether the code
+// is compiled with or without PURESIGNAL
+// Furthermore, we provide a function that determines the frequency for
+// a given (HPSDR) receiver. This makes the code below much more transparent.
+//
+
+static int rx_feedback_receiver() {
+  //
+  // Depending on the device, return channel number of RX feedback receiver
+  //
+  int ret;
+  switch (device) {
+    case DEVICE_METIS:
+      ret=0;
+      break;
+    case DEVICE_HERMES:
+    case DEVICE_STEMLAB:
+      ret=2;
+      break;
+    case DEVICE_ANGELIA:
+    case DEVICE_ORION:
+    case DEVICE_ORION2:
+      ret=3;
+    default:
+      ret=0;
+      break;
+  }
+  return ret;
+}
+
+static int tx_feedback_receiver() {
+  //
+  // Depending on the device, return channel number of RX feedback receiver
+  //
+  int ret;
+  switch (device) {
+    case DEVICE_METIS:
+      ret=1;
+      break;
+    case DEVICE_HERMES:
+    case DEVICE_STEMLAB:
+      ret=3;
+      break;
+    case DEVICE_ANGELIA:
+    case DEVICE_ORION:
+    case DEVICE_ORION2:
+      ret=4;
+    default:
+      ret=1;
+      break;
+  }
+  return ret;
+}
+
+static int first_receiver() {
+  //
+  // Depending on the device and whether we compiled for PURESIGNAL,
+  // return the number of the first receiver
+  //
+  return 0;
+}
+
+static int second_receiver() {
+  //
+  // Depending on the device and whether we compiled for PURESIGNAL,
+  // return the number of the second receiver
+  //
+#ifdef PURESIGNAL
+  return 2;
+#else
+  return 1;
+#endif
+}
+
+static long long channel_freq(int chan) {
+  //
+  // Depending on PURESIGNAL and DIVERSITY, return
+  // the frequency associated with the current HPSDR
+  // RX channel (0 <= chan <= 4).
+  // Note that for the RX channels which the firmware
+  // associates with the TX DAC the frequency need not
+  // be set.
+  //
+  // This function returns the TX frequency if chan is
+  // outside the allowed range, and thus can be used
+  // to determine the TX frequency.
+  //
+  int v;
+  long long freq;
+
+  switch (chan) {
+#ifdef PURESIGNAL
+    case 0:
+    case 1:
+      v=receiver[0]->id;
+      break;
+    case 2:
+    case 3:
+      if (diversity_enabled) {
+       v=receiver[0]->id;
+      } else {
+       v=receiver[1]->id;
+      }
+      break;
+#else
+    case 0:
+      v=receiver[0]->id;
+      break;
+    case 1:
+      if (diversity_enabled) {
+       v=receiver[0]->id;
+      } else {
+       v=receiver[1]->id;
+      }
+      break;
+#endif
+  }
+  if (v < 0) {
+    //
+    // v=-1 indicates that there is no VFO associated,
+    // in this case we take the TX frequency. So we can use this
+    // function also to determine the TX frequency
+    //
+    if(active_receiver->id==VFO_A) {
+      if(split) {
+       freq=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset;
+      } else {
+       freq=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset;
+      }
+    } else {
+      if(split) {
+       freq=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset;
+      } else {
+       freq=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset;
+      }
+    }
+  } else {
+    //
+    // determine frequency associated with VFO v
+    //
+    freq=vfo[v].frequency-vfo[v].lo;
+    if(vfo[v].rit_enabled) {
+      freq+=vfo[v].rit;
+    }
+    if(vfo[v].mode==modeCWU) {
+      freq-=(long long)cw_keyer_sidetone_frequency;
+    } else if(vfo[v].mode==modeCWL) {
+      freq+=(long long)cw_keyer_sidetone_frequency;
+    }
+  }
+  return freq;
+}
+
 static int how_many_receivers() {
   //
   // Depending on how the program is compiled and which board we have,
   // we use a FIXED number of receivers except for RADIOBERRY and PI_SDR,
   // where the number may be dynamically changed
   //
-  int num;
+  int ret;
 #if defined(RADIOBERRY) || defined(PI_SDR)
-        num = receivers;   // 1 or 2
+        ret = receivers;     // 1 or 2
 #else
-        num = RECEIVERS;     // 2
+        ret = RECEIVERS;     // 2
 #endif
 
 #ifdef PURESIGNAL
     // for PureSignal, the number of receivers needed is hard-coded below.
-    // we need at least 3 (for RX), and up to 5 for Orion2 boards, since
-    // the TX DAC channel is hard-wired to RX5.
-    num = 3;
-    if (device == DEVICE_HERMES) num = 4;
-    if (device == DEVICE_ANGELIA || device == DEVICE_ORION || device == DEVICE_ORION2) num = 5;
+    // we need at least 2, and up to 5 for Orion2 boards. This is so because
+    // the TX DAC is hard-wired to RX4 for HERMES,STEMLAB and to RX5 for ANGELIA
+    // and beyond.
+    ret = 2;  // METIS?
+    if (device == DEVICE_HERMES  || device == DEVICE_STEMLAB) ret = 4;
+    if (device == DEVICE_ANGELIA || device == DEVICE_ORION || device == DEVICE_ORION2) ret = 5;
 #endif
-    return num;
+    return ret;
 }
+
 static void process_ozy_input_buffer(unsigned char  *buffer) {
   int i,j;
   int r;
@@ -586,6 +746,10 @@ static void process_ozy_input_buffer(unsigned char  *buffer) {
   int tx_vfo=split?VFO_B:VFO_A;
 
   int num_hpsdr_receivers=how_many_receivers();
+  int rxfdbk = rx_feedback_receiver();
+  int txfdbk = tx_feedback_receiver();
+  int rx1channel = first_receiver();
+  int rx2channel = second_receiver();
 
   if(buffer[b++]==SYNC && buffer[b++]==SYNC && buffer[b++]==SYNC) {
     // extract control bytes
@@ -661,114 +825,55 @@ static void process_ozy_input_buffer(unsigned char  *buffer) {
         left_sample_double=(double)left_sample/8388607.0; // 24 bit sample 2^23-1
         right_sample_double=(double)right_sample/8388607.0; // 24 bit sample 2^23-1
 
-#ifdef PURESIGNAL
        if (isTransmitting() && transmitter->puresignal) {
          //
-         // case: transmitting with PURESIGNAL. Get sample pairs and feed to pscc
+         // transmitting with PURESIGNAL. Get sample pairs and feed to pscc
          //
-          switch(r) {
-            case 0:
-              if(device==DEVICE_METIS)  {
-                left_sample_double_rx=left_sample_double;
-                right_sample_double_rx=right_sample_double;
-              }
-              break;
-            case 1:
-              if(device==DEVICE_METIS)  {
-                left_sample_double_tx=left_sample_double;
-                right_sample_double_tx=right_sample_double;
-                add_ps_iq_samples(transmitter, left_sample_double_tx,right_sample_double_tx,left_sample_double_rx,right_sample_double_rx);
-              }
-              break;
-            case 2:
-              if(device==DEVICE_HERMES)  {
-                left_sample_double_rx=left_sample_double;
-                right_sample_double_rx=right_sample_double;
-              }
-              break;
-            case 3:
-              if(device==DEVICE_HERMES)  {
-                left_sample_double_tx=left_sample_double;
-                right_sample_double_tx=right_sample_double;
-                add_ps_iq_samples(transmitter, left_sample_double_tx,right_sample_double_tx,left_sample_double_rx,right_sample_double_rx);
-              } else if(device==DEVICE_ANGELIA || device==DEVICE_ORION || device==DEVICE_ORION2) {
-                left_sample_double_rx=left_sample_double;
-                right_sample_double_rx=right_sample_double;
-              }
-              break;
-            case 4:
-              if(device==DEVICE_ANGELIA || device==DEVICE_ORION || device==DEVICE_ORION2) {
-                left_sample_double_tx=left_sample_double;
-                right_sample_double_tx=right_sample_double;
-                add_ps_iq_samples(transmitter, left_sample_double_tx,right_sample_double_tx,left_sample_double_rx,right_sample_double_rx);
-              }
-              break;
+         if (r == rxfdbk) {
+            left_sample_double_rx=left_sample_double;
+            right_sample_double_rx=right_sample_double;
+          } else if (r == txfdbk) {
+            left_sample_double_tx=left_sample_double;
+            right_sample_double_tx=right_sample_double;
           }
-        }
-        if (!isTransmitting() && diversity_enabled) {
-         //
-         // case: compiled for PURESIGNAL and RX with DIVERSITY. Feed sample pair to diversity mixer for RX1 and original RX2 sample to RX2
-         //
-          switch(r) {
-            case 0:
-              left_sample_double_rx=left_sample_double;
-              right_sample_double_rx=right_sample_double;
-              break;
-            case 2:
-              left_sample_double_tx=left_sample_double;
-              right_sample_double_tx=right_sample_double;
-              add_div_iq_samples(receiver[0], left_sample_double_rx,right_sample_double_rx,left_sample_double_tx,right_sample_double_tx);
-              if (receivers >1) add_iq_samples(receiver[1], left_sample_double,right_sample_double);
-              break;
+         // this is pure paranoia, it allows for txfdbk < rxfdbk
+          if (r+1 == num_hpsdr_receivers) {
+            add_ps_iq_samples(transmitter, left_sample_double_tx,right_sample_double_tx,left_sample_double_rx,right_sample_double_rx);
           }
         }
-        if (!isTransmitting() && !diversity_enabled) {
+
+       if (!isTransmitting() && diversity_enabled) {
          //
-         // case: compiled for PURESIGNAL and RX without DIVERSITY. Feed samples to RX1 and RX2
+         // receiving with DIVERSITY. Get sample pairs and feed to diversity mixer
          //
-          switch(r) {
-            case 0:
-              add_iq_samples(receiver[0], left_sample_double,right_sample_double);
-              break;
-            case 2:
-              if (receivers >1) add_iq_samples(receiver[1], left_sample_double,right_sample_double);
-              break;
+          if (r == rx1channel) {
+            left_sample_double_rx=left_sample_double;
+            right_sample_double_rx=right_sample_double;
+          } else if (r == rx2channel) {
+            left_sample_double_tx=left_sample_double;
+            right_sample_double_tx=right_sample_double;
           }
-        }
-#else
-        // no PURESIGNAL
-        if (diversity_enabled) {
-         //
-         // case: compiled without PURESIGNAL and using DIVERSITY: Feed sample pair to diversity mixer for RX1 and original RX2 sample to RX2
-         //
-          switch(r) {
-            case 0:
-              left_sample_double_rx=left_sample_double;
-              right_sample_double_rx=right_sample_double;
-              break;
-            case 1:
-              left_sample_double_tx=left_sample_double;
-              right_sample_double_tx=right_sample_double;
-              add_div_iq_samples(receiver[0], left_sample_double_rx,right_sample_double_rx,left_sample_double_tx,right_sample_double_tx);
-              if (receivers >1) add_iq_samples(receiver[1], left_sample_double,right_sample_double);
-              break;
+         // this is pure paranoia, it allows for div_main < div_aux
+          if (r+1 == num_hpsdr_receivers) {
+            add_div_iq_samples(receiver[0], left_sample_double_rx,right_sample_double_rx,left_sample_double_tx,right_sample_double_tx);
+           // if we have a second receiver, display "auxiliary" receiver as well
+            if (receivers >1) add_iq_samples(receiver[1], left_sample_double_tx,right_sample_double_tx);
           }
-        }
-        if (!diversity_enabled) {
+       }
+
+        if (!isTransmitting() && !diversity_enabled) {
          //
-         // case: compiled without PURESIGNAL and not using DIVERSITY: Feed samples to RX1 and RX2
+         // RX without DIVERSITY. Feed samples to RX1 and RX2
          //
-          switch(r) {
-            case 0:
-              add_iq_samples(receiver[0], left_sample_double,right_sample_double);
-              break;
-            case 1:
-              if (receivers >1) add_iq_samples(receiver[1], left_sample_double,right_sample_double);
-              break;
+          if (r == rx1channel) {
+             add_iq_samples(receiver[0], left_sample_double,right_sample_double);
+          } else if (r == rx2channel ]] receivers > 1) {
+             add_iq_samples(receiver[1], left_sample_double,right_sample_double);
           }
-       }
-#endif
-      }
+        }
+      } // end of loop over the receiver channels
+
+      // TX without PURESIGNAL: receivers are shut down -- do nothing
 
       mic_sample  = (short)(buffer[b++]<<8);
       mic_sample |= (short)(buffer[b++]&0xFF);
@@ -1002,17 +1107,21 @@ void ozy_send_buffer() {
     //
     if (isTransmitting() && transmitter->puresignal) i=receiver[PS_RX_FEEDBACK]->alex_antenna;
     switch(i) {
-      case 3:  // Alex: RX2 IN, ANAN: EXT1, ANAN7000: still uses internal feedback 
-        output_buffer[C3]|=0x80;
+      case 6:  // EXT1 used for PS feedback
+      case 3:  // EXT1 (RX2_IN)
+        output_buffer[C3]|=0x40;
         break;
-      case 4:  // Alex: RX1 IN, ANAN: EXT2, ANAN7000: RX BYPASS
-        output_buffer[C3]|=0xA0;
+      case 4:  // EXT2 (RX1_IN)
+        output_buffer[C3]|=0x20;
         break;
       case 5:  // XVTR
-        output_buffer[C3]|=0xE0;
+        output_buffer[C3]|=0x60;
         break;
+      case 7:  // RX Bypass In
+        output_buffer[C3]|=0x80;
+       break;
       default:
-       // RX1_OUT and RX1_ANT bits remain zero
+       // RX1_ANT bits remain zero
         break;
     }
 
@@ -1072,20 +1181,7 @@ void ozy_send_buffer() {
     switch(command) {
       case 1: // tx frequency
         output_buffer[C0]=0x02;
-        long long txFrequency;
-        if(active_receiver->id==VFO_A) {
-          if(split) {
-            txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset;
-          } else {
-            txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset;
-          }
-        } else {
-          if(split) {
-            txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset;
-          } else {
-            txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset;
-          }
-        }
+        long long txFrequency=channel_freq(-1);
         output_buffer[C1]=txFrequency>>24;
         output_buffer[C2]=txFrequency>>16;
         output_buffer[C3]=txFrequency>>8;
@@ -1094,51 +1190,14 @@ void ozy_send_buffer() {
       case 2: // rx frequency
         if(current_rx<num_hpsdr_receivers) {
           output_buffer[C0]=0x04+(current_rx*2);
-#ifdef PURESIGNAL
-          int v=receiver[current_rx/2]->id;
-         // for the "last" receiver, v is out of range. In this case,
-         // use TX frequency also while receiving
-          if((isTransmitting() && transmitter->puresignal) || (v >= MAX_VFOS)) {
-            long long txFrequency;
-            if(active_receiver->id==VFO_A) {
-              if(split) {
-                txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset;
-              } else {
-                txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset;
-              }
-            } else {
-              if(split) {
-                txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset;
-              } else {
-                txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset;
-              }
-            }
-            output_buffer[C1]=txFrequency>>24;
-            output_buffer[C2]=txFrequency>>16;
-            output_buffer[C3]=txFrequency>>8;
-            output_buffer[C4]=txFrequency;
-          } else {
-#else
-          int v=receiver[current_rx]->id;
-#endif
-            long long rxFrequency=vfo[v].frequency-vfo[v].lo;
-            if(vfo[v].rit_enabled) {
-              rxFrequency+=vfo[v].rit;
-            }
-            if(vfo[v].mode==modeCWU) {
-              rxFrequency-=(long long)cw_keyer_sidetone_frequency;
-            } else if(vfo[v].mode==modeCWL) {
-              rxFrequency+=(long long)cw_keyer_sidetone_frequency;
-            }
-            output_buffer[C1]=rxFrequency>>24;
-            output_buffer[C2]=rxFrequency>>16;
-            output_buffer[C3]=rxFrequency>>8;
-            output_buffer[C4]=rxFrequency;
-#ifdef PURESIGNAL
-          }
-#endif
+         long long rxFrequency=channel_freq(current_rx);
+          output_buffer[C1]=rxFrequency>>24;
+          output_buffer[C2]=rxFrequency>>16;
+          output_buffer[C3]=rxFrequency>>8;
+          output_buffer[C4]=rxFrequency;
           current_rx++;
         }
+       // if we have reached the last RX channel, wrap around
         if(current_rx>=num_hpsdr_receivers) {
           current_rx=0;
         }
@@ -1147,7 +1206,6 @@ void ozy_send_buffer() {
         {
         BAND *band=band_get_current_band();
         int power=0;
-#ifdef STEMLAB_FIX
        //
        // Some HPSDR apps for the RedPitaya generate CW inside the FPGA, but while
        // doing this, DriveLevel changes are processed by the server, but do not become effective.
@@ -1162,9 +1220,6 @@ void ozy_send_buffer() {
           mode=vfo[0].mode;
         }
         if(isTransmitting() || (mode == modeCWU) || (mode == modeCWL)) {
-#else
-        if(isTransmitting()) {
-#endif
           if(tune && !transmitter->tune_use_drive) {
             power=(int)((double)transmitter->drive_level/100.0*(double)transmitter->tune_percent);
           } else {
@@ -1220,7 +1275,8 @@ void ozy_send_buffer() {
         output_buffer[C3]=0x00;
         output_buffer[C4]=0x00;
   
-        if(radio->device==DEVICE_HERMES || radio->device==DEVICE_ANGELIA || radio->device==DEVICE_ORION || radio->device==DEVICE_ORION2) {
+        if(device==DEVICE_HERMES || device==DEVICE_ANGELIA || device==DEVICE_ORION
+                                 || device==DEVICE_ORION2  || device == DEVICE_STEMLAB) {
          // if attenuation is zero, then disable attenuator
          i = adc_attenuation[receiver[0]->adc] & 0x1F;
           if (i >0) output_buffer[C4]=0x20| i;
@@ -1235,7 +1291,8 @@ void ozy_send_buffer() {
         output_buffer[C0]=0x16;
         output_buffer[C1]=0x00;
         if(receivers==2) {
-          if(radio->device==DEVICE_HERMES || radio->device==DEVICE_ANGELIA || radio->device==DEVICE_ORION || radio->device==DEVICE_ORION2) {
+          if(device==DEVICE_HERMES || device==DEVICE_ANGELIA || device==DEVICE_ORION
+                                   || device==DEVICE_ORION2  || device==DEVICE_STEMLAB) {
            // if attenuation is zero, then disable attenuator
            i = adc_attenuation[receiver[1]->adc] & 0x1F;
             if (i > 0) output_buffer[C1]=0x20|i;
@@ -1449,6 +1506,7 @@ static int metis_write(unsigned char ep,unsigned char* buffer,int length) {
 }
 
 static void metis_restart() {
+  int i;
   //
   // In TCP-ONLY mode, we possibly need to re-connect
   // since if we come from a METIS-stop, the server
@@ -1463,34 +1521,17 @@ static void metis_restart() {
   // reset current rx
   current_rx=0;
 
-#ifdef STEMLAB_FIX
   // 
   // Some (older) HPSDR apps on the RedPitaya have very small
   // buffers that over-run if too much data is sent
   // to the RedPitaya *before* sending a METIS start packet.
-  // Therefore we send only four OZY buffers here.
+  // We fill the DUC FIFO here with about 500 samples before
+  // starting.
   //
-  command=1;   // ship out a "C0=0" and a "set tx" command
-  ozy_send_buffer();
-  ozy_send_buffer();
-  command=2;  // ship out a "C0=0" and a "set rx" command for RX1
-  ozy_send_buffer();
-  ozy_send_buffer();
-
-  current_rx=0;
-  command=1;
-#else
-  // DL1YCF: this is the original code, which does not do what it pretends ....
-  // send commands twice
   command=1;
-  do {
+  for (i=1; i<8; i++) {
     ozy_send_buffer();
-  } while (command!=1);
-
-  do {
-    ozy_send_buffer();
-  } while (command!=1);
-#endif
+  }
 
   sleep(1);
 
index acadd84299be4f7a5c36fe26b87d716e0e25cf2a..fb80d26444474b911a23c44005451799c3c302ff 100644 (file)
--- a/ps_menu.c
+++ b/ps_menu.c
@@ -261,15 +261,21 @@ static int info_thread(gpointer arg) {
 }
 
 //
-// Set "RX1 ANT", "RX1 OUT", and ADC settings for the PS feedback signal
+// select route for PS feedback signal.
+// note: we need new code numbers such that we can
+//       distinguish "normal RX" and "feedback" use
+//       of EXT1. In the latter case, any RX filters have
+//       to by bypassed, which is of particular importance
+//       on the 6m band.
+//       
 //
 static void ps_ant_cb(GtkWidget *widget, gpointer data) {
   int val = (int) (uintptr_t) data;
   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
     switch (val) {
-      case 0:  // AUTO (Internal), feedback goes to first ADC
-      case 3:  // EXT1,            feedback goes to first ADC
-      case 4:  // EXT2,            feedback goes to first ADC
+      case 0:  // Internal
+      case 6:  // EXT1; RX filters switched to "BYPASS"
+      case 7:  // Bypass
        receiver[PS_RX_FEEDBACK]->alex_antenna = val;
        if (protocol == NEW_PROTOCOL) {
          schedule_high_priority();
@@ -330,7 +336,6 @@ static void twotone_cb(GtkWidget *widget, gpointer data) {
 void ps_menu(GtkWidget *parent) {
   GtkWidget *b;
   int i;
-  const char *cp;
 
   parent_window=parent;
 
@@ -420,15 +425,17 @@ void ps_menu(GtkWidget *parent) {
   //
   // AUTO              Using internal feedback (to ADC0)
   // EXT1              Using EXT1 jacket (to ADC0), ANAN-7000: still uses AUTO
-  // EXT2              Using EXT2 jacket (to ADC0), ANAN-7000: "EXT2 is called RX Bypass"
-  // RX2               Using RX2  jacket (to ADC1)
+  // BYPASS            Using BYPASS. Not available with ANAN-100/200 up to Rev. 16 filter boards
+  //
+  // In fact, we provide the possibility of using EXT1 only to support these older
+  // (before February, 2015) ANAN-100/200 devices.
   //
   GtkWidget *ps_ant_label=gtk_label_new("PS FeedBk ANT:");
   gtk_widget_show(ps_ant_label);
   gtk_grid_attach(GTK_GRID(grid), ps_ant_label, col, row, 1, 1);
   col++;
 
-  GtkWidget *ps_ant_auto=gtk_radio_button_new_with_label(NULL,"AUTO");
+  GtkWidget *ps_ant_auto=gtk_radio_button_new_with_label(NULL,"Internal");
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ps_ant_auto), 
     (receiver[PS_RX_FEEDBACK]->alex_antenna == 0) );
   gtk_widget_show(ps_ant_auto);
@@ -438,23 +445,18 @@ void ps_menu(GtkWidget *parent) {
 
   GtkWidget *ps_ant_ext1=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ps_ant_auto),"EXT1");
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ps_ant_ext1),
-    (receiver[PS_RX_FEEDBACK]->alex_antenna==3) );
+    (receiver[PS_RX_FEEDBACK]->alex_antenna==6) );
   gtk_widget_show(ps_ant_ext1);
   gtk_grid_attach(GTK_GRID(grid), ps_ant_ext1, col, row, 1, 1);
-  g_signal_connect(ps_ant_ext1,"toggled", G_CALLBACK(ps_ant_cb), (gpointer) (long) 3);
+  g_signal_connect(ps_ant_ext1,"toggled", G_CALLBACK(ps_ant_cb), (gpointer) (long) 6);
   col++;
 
-  cp="EXT2";
-  // On ANAN-7000 there is no EXT2 jacket. This function is now called "RX ByPass"
-  // On ANAN-8000 this must be done by physical re-wiring
-  if ((protocol == ORIGINAL_PROTOCOL && device == DEVICE_ORION2) || 
-      (protocol == NEW_PROTOCOL      && device == NEW_DEVICE_ORION2))  cp="RxByPass";
-  GtkWidget *ps_ant_ext2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ps_ant_auto),cp);
+  GtkWidget *ps_ant_ext2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ps_ant_auto),"ByPass IN");
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ps_ant_ext2),
-    (receiver[PS_RX_FEEDBACK]->alex_antenna==4) );
+    (receiver[PS_RX_FEEDBACK]->alex_antenna==7) );
   gtk_widget_show(ps_ant_ext2);
   gtk_grid_attach(GTK_GRID(grid), ps_ant_ext2, col, row, 1, 1);
-  g_signal_connect(ps_ant_ext2,"toggled", G_CALLBACK(ps_ant_cb), (gpointer) (long) 4);
+  g_signal_connect(ps_ant_ext2,"toggled", G_CALLBACK(ps_ant_cb), (gpointer) (long) 7);
   col++;
 
   row++;
diff --git a/radio.c b/radio.c
index c719191ec15ba9cf083fab18294aaf89e0c45bfe..3abb01dde357e821d0f53734af30093618328baf 100644 (file)
--- a/radio.c
+++ b/radio.c
@@ -492,9 +492,7 @@ void start_radio() {
   switch(protocol) {
     case ORIGINAL_PROTOCOL:
       switch(device) {
-        case DEVICE_METIS:
-          n_adc=1;  // No support for multiple MERCURY cards on a single ATLAS bus.
-          break;
+        case DEVICE_METIS: // No support for multiple MERCURY cards on a single ATLAS bus.
         case DEVICE_HERMES:
         case DEVICE_HERMES_LITE:
           n_adc=1;
index 4cff08f7be0bbe956444a86e7f2388b4815a4637..6ac0d1ff6ca6687e360ba16f5535aec24e5e33bf 100644 (file)
--- a/rx_menu.c
+++ b/rx_menu.c
@@ -32,6 +32,7 @@
 #include "radio.h"
 #include "receiver.h"
 #include "sliders.h"
+#include "new_protocol.h"
 
 static GtkWidget *parent_window=NULL;
 
@@ -59,14 +60,23 @@ static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_d
 
 static void dither_cb(GtkWidget *widget, gpointer data) {
   active_receiver->dither=active_receiver->dither==1?0:1;
+  if (protocol == NEW_PROTOCOL) {
+    schedule_high_priority();
+  }
 }
 
 static void random_cb(GtkWidget *widget, gpointer data) {
   active_receiver->random=active_receiver->random==1?0:1;
+  if (protocol == NEW_PROTOCOL) {
+    schedule_high_priority();
+  }
 }
 
 static void preamp_cb(GtkWidget *widget, gpointer data) {
   active_receiver->preamp=active_receiver->preamp==1?0:1;
+  if (protocol == NEW_PROTOCOL) {
+    schedule_high_priority();
+  }
 }
 
 static void alex_att_cb(GtkWidget *widget, gpointer data) {
@@ -243,8 +253,7 @@ void rx_menu(GtkWidget *parent) {
   // On SDRs other than CHARLY25, preamps or Alex attenuators may be present or not, and we
   // do not try to find out whether they are. This would overload the code, and we then
   // also must have a menu to check e.g. which ANAN model is actually present.
-  // Instead, we offer these checkboxes in either case and must rely on the user
-  // not playing around with features that are not there.
+  // Instead, we offer these checkboxes in either case.
   //
   // NOTE: Preamps are not present on most current HPSDR models, and ALEX attenuators
   //       are not present e.g. in ANAN-7000.
index bc4cf61255c3bf845bea74ee202c2837dda87452..68b70821449c7c6784a48a31f32c8d2511477dc6 100644 (file)
@@ -369,6 +369,7 @@ static gboolean update_display(gpointer data) {
           constant2=0.09;
           break;
         case DEVICE_HERMES:
+        case DEVICE_STEMLAB:
           constant1=3.3;
           constant2=0.095;
           break;