]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Many Fixes
authorJohn Melton G0ORX <john.d.melton@googlemail.com>
Fri, 5 Mar 2021 11:25:33 +0000 (11:25 +0000)
committerJohn Melton G0ORX <john.d.melton@googlemail.com>
Fri, 5 Mar 2021 11:25:33 +0000 (11:25 +0000)
24 files changed:
Makefile
README.md
actions.c
adc.h
gpio.c
gpio.h
i2c.c
meter.c
midi3.c
midi_menu.c
old_protocol.c
radio.c
radio.h
radio_menu.c
receiver.c
receiver.h
release/pihpsdr/install.sh
release/pihpsdr/libwdsp.so
rx_panadapter.c
sliders.c
soapy_protocol.c
switch_menu.c
toolbar.c
toolbar.h

index 742ecf56e806e57dddb7893f786909fe6858dceb..ec8c1858958ce9dcede3b0511aba4fabcf90e1f4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,17 +16,20 @@ GIT_VERSION := $(shell git describe --abbrev=0 --tags)
 #
 GPIO_INCLUDE=GPIO
 
-# uncomment the line below to include USB Ozy support
-# USBOZY_INCLUDE=USBOZY
-
 # uncomment the line below to include Pure Signal support
 PURESIGNAL_INCLUDE=PURESIGNAL
 
+# uncomment the line below to include MIDI support
+MIDI_INCLUDE=MIDI
+
+# uncomment the line below to include USB Ozy support
+# USBOZY_INCLUDE=USBOZY
+
 # uncomment the line to below include support local CW keyer
 #LOCALCW_INCLUDE=LOCALCW
 
 # uncomment the line below for SoapySDR
-SOAPYSDR_INCLUDE=SOAPYSDR
+#SOAPYSDR_INCLUDE=SOAPYSDR
 
 # uncomment the line to below include support for sx1509 i2c expander
 #SX1509_INCLUDE=sx1509
@@ -37,8 +40,6 @@ SOAPYSDR_INCLUDE=SOAPYSDR
 # uncomment the line below to include support for STEMlab discovery (WITHOUT AVAHI)
 #STEMLAB_DISCOVERY=STEMLAB_DISCOVERY_NOAVAHI
 
-# uncomment the line below to include MIDI support
-MIDI_INCLUDE=MIDI
 
 # uncomment the line below for various debug facilities
 #DEBUG_OPTION=-D DEBUG
@@ -203,7 +204,8 @@ AUDIO_SOURCES=portaudio.c
 AUDIO_OBJS=portaudio.o
 endif
 
-CFLAGS=        -g -Wno-deprecated-declarations -O3
+//CFLAGS=      -g -Wno-deprecated-declarations -O3
+CFLAGS=        -g -Wno-deprecated-declarations
 OPTIONS=$(SMALL_SCREEN_OPTIONS) $(MIDI_OPTIONS) $(PURESIGNAL_OPTIONS) $(REMOTE_OPTIONS) $(USBOZY_OPTIONS) \
        $(GPIO_OPTIONS) $(GPIOD_OPTIONS) $(SOAPYSDR_OPTIONS) $(LOCALCW_OPTIONS) \
        $(STEMLAB_OPTIONS) \
@@ -461,9 +463,9 @@ $(PROGRAM):  $(OBJS) $(AUDIO_OBJS) $(REMOTE_OBJS) $(USBOZY_OBJS) $(SOAPYSDR_OBJS
 .PHONY:        all
 all:   prebuild  $(PROGRAM) $(HEADERS) $(AUDIO_HEADERS) $(USBOZY_HEADERS) $(SOAPYSDR_HEADERS) \
        $(LOCALCW_HEADERS) \
-       $(PURESIGNAL_HEADERS) $(MIDI_HEADERS) $(STEMLAB_HEADERS) $(SERVER_HEADERS)\
+       $(PURESIGNAL_HEADERS) $(MIDI_HEADERS) $(STEMLAB_HEADERS) $(SERVER_HEADERS) \
        $(AUDIO_SOURCES) $(SOURCES) \
-       $(USBOZY_SOURCES) $(SOAPYSDR_SOURCES) $(LOCALCW_SOURCE)
+       $(USBOZY_SOURCES) $(SOAPYSDR_SOURCES) $(LOCALCW_SOURCE) \
        $(PURESIGNAL_SOURCES) $(MIDI_SOURCES) $(STEMLAB_SOURCES) $(SERVER_SOURCES)
 
 .PHONY:        prebuild
index bf7f0cd5b9471c647b6a6c8e18a2834441f6a3e7..281d6edfaa20e3ba399434e5e8a71d80d12ccbda 100644 (file)
--- a/README.md
+++ b/README.md
@@ -3,9 +3,6 @@ Raspberry Pi 3 standalone code for HPSDR
 
 Supports both the old and new ethernet protocols.
 
-Download release/documentation/pihpsdr-install.pdf for instructions to install on RPi3.
+See the Wiki (https://github.com/g0orx/pihpsdr/wiki) for more information about building and running piHPSDR.
 
-wget https://github.com/g0orx/pihpsdr/blob/master/release/documentation/pihpsdr-install.pdf
-
-Full download using git into your HOME folder: 
-git clone https://github.com/g0orx/pihpsdr.git
+Note: the latest source code is in the gpiod branch.
index 61b1d10800e87e9c091551cc1820123a59ff7711..2c819dd302944a4fb2216a03c4c8fe3000007c0a 100644 (file)
--- a/actions.c
+++ b/actions.c
@@ -4,7 +4,6 @@
 #include "discovery.h"
 #include "receiver.h"
 #include "sliders.h"
-#include "toolbar.h"
 #include "band_menu.h"
 #include "diversity_menu.h"
 #include "vfo.h"
@@ -29,6 +28,7 @@
 #include "zoompan.h"
 #include "actions.h"
 #include "gpio.h"
+#include "toolbar.h"
 
 char *encoder_string[ENCODER_ACTIONS] = {
   "NO ACTION",
@@ -38,7 +38,7 @@ char *encoder_string[ENCODER_ACTIONS] = {
   "AGC GAIN",
   "AGC GAIN RX1",
   "AGC GAIN RX2",
-  "ATTENUATION/RX GAIN",
+  "ATTENUATION",
   "COMP",
   "CW FREQUENCY",
   "CW SPEED",
@@ -81,7 +81,7 @@ char *sw_string[SWITCH_ACTIONS] = {
   "",
   "A TO B",
   "A SWAP B",
-  "AGC",
+  "AGC +",
   "ANF",
   "B TO A",
   "BAND -",
@@ -93,18 +93,18 @@ char *sw_string[SWITCH_ACTIONS] = {
   "DUPLEX",
   "FILTER -",
   "FILTER +",
-  "FUNCTION",
+  "FUNCT",
   "LOCK",
-  "MENU AGC",
-  "MENU BAND",
-  "MENU BSTACK",
-  "MENU DIV",
-  "MENU FILTER",
-  "MENU FREQUENCY",
-  "MENU MEMORY",
-  "MENU MODE",
-  "MENU NOISE",
-  "MENU PS",
+  "AGC",
+  "BAND",
+  "BSTACK",
+  "DIV",
+  "FILTER",
+  "FREQUENCY",
+  "MEMORY",
+  "MODE",
+  "NOISE",
+  "PS",
   "MODE -",
   "MODE +",
   "MOX",
@@ -122,9 +122,9 @@ char *sw_string[SWITCH_ACTIONS] = {
   "SAT",
   "SNB",
   "SPLIT",
-  "TUNE",
+  "TUN",
   "TUNE FULL",
-  "TUNE MEMORY",
+  "TUNE MEM",
   "TWO TONE",
   "XIT",
   "XIT CL",
@@ -237,7 +237,8 @@ int encoder_action(void *data) {
       set_af_gain(1,value);
       break;
     case ENCODER_RF_GAIN:
-      value=active_receiver->rf_gain;
+      //value=active_receiver->gain;
+      value=adc[active_receiver->id].gain;
       value+=a->val;
       if(value<0.0) {
         value=0.0;
@@ -247,7 +248,8 @@ int encoder_action(void *data) {
       set_rf_gain(active_receiver->id,value);
       break;
     case ENCODER_RF_GAIN_RX1:
-      value=receiver[0]->rf_gain;
+      //value=receiver[0]->rf_gain;
+      value=adc[receiver[0]->id].gain;
       value+=a->val;
       if(value<0.0) {
         value=0.0;
@@ -257,7 +259,8 @@ int encoder_action(void *data) {
       set_rf_gain(0,value);
       break;
     case ENCODER_RF_GAIN_RX2:
-      value=receiver[1]->rf_gain;
+      //value=receiver[1]->rf_gain;
+      value=adc[receiver[1]->id].gain;
       value+=a->val;
       if(value<0.0) {
         value=0.0;
@@ -500,13 +503,26 @@ int switch_action(void *data) {
   if(a->state==PRESSED) {
     switch(a->action) {
       case FUNCTION:
-        if(controller==NO_CONTROLLER || controller==CONTROLLER1) {
-          function++;
-          if(function>=MAX_FUNCTIONS) {
-            function=0;
-          }
-          switches=switches_controller1[function];
-          update_toolbar_labels();
+       switch(controller) {
+          case NO_CONTROLLER:
+          case CONTROLLER1:
+            function++;
+            if(function>=MAX_FUNCTIONS) {
+              function=0;
+            }
+            toolbar_switches=switches_controller1[function];
+            switches=switches_controller1[function];
+            update_toolbar_labels();
+           break;
+         case CONTROLLER2_V1:
+         case CONTROLLER2_V2:
+            function++;
+            if(function>=MAX_FUNCTIONS) {
+              function=0;
+            }
+            toolbar_switches=switches_controller1[function];
+            update_toolbar_labels();
+           break;
         }
         break;
       case TUNE:
diff --git a/adc.h b/adc.h
index 8c0be6caa64322f06e82951447e41ad0a9094c3a..9f067d194cfee0b40e9fdeea059ca2bdc60e35b6 100644 (file)
--- a/adc.h
+++ b/adc.h
@@ -67,6 +67,8 @@ typedef struct _adc {
   gboolean enable_step_attenuation;
 #ifdef SOAPYSDR
   gdouble gain;
+  gdouble min_gain;
+  gdouble max_gain;
   gboolean agc;
 #endif
 } ADC;
diff --git a/gpio.c b/gpio.c
index 5674cca9ea540c2e5cf6de5c8923c64b4e95130e..1509d1fab3dfb84a7e969cab95d3f82e5045a1bc 100644 (file)
--- a/gpio.c
+++ b/gpio.c
@@ -95,6 +95,38 @@ enum {
   B
 };
 
+// encoder state table
+#define R_START 0x0
+#define R_CW_FINAL 0x1
+#define R_CW_BEGIN 0x2
+#define R_CW_NEXT 0x3
+#define R_CCW_BEGIN 0x4
+#define R_CCW_FINAL 0x5
+#define R_CCW_NEXT 0x6
+
+#define DIR_NONE 0x0
+// Clockwise step.
+#define DIR_CW 0x10
+// Anti-clockwise step.
+#define DIR_CCW 0x20
+
+guchar encoder_state_table[7][4] = {
+  // R_START
+  {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
+  // R_CW_FINAL
+  {R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
+  // R_CW_BEGIN
+  {R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
+  // R_CW_NEXT
+  {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
+  // R_CCW_BEGIN
+  {R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
+  // R_CCW_FINAL
+  {R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
+  // R_CCW_NEXT
+  {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
+};
+
 #ifdef GPIO
 char *consumer="pihpsdr";
 
@@ -112,370 +144,205 @@ int I2C_INTERRUPT=15;
 int monitor_lines[MAX_LINES];
 int lines=0;
 
-long settle_time=150;  // ms
+long settle_time=50;  // ms
 
 // VFO Encoder is always last
 
 ENCODER encoders_no_controller[MAX_ENCODERS]={
-  {FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0},
-  {FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0},
-  {FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0},
-  {FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0},
-  {FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0},
+  {FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+  {FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+  {FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+  {FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+  {FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
   };
 
 ENCODER encoders_controller1[MAX_ENCODERS]={
-  {TRUE,TRUE,20,1,26,1,0,ENCODER_AF_GAIN,FALSE,TRUE,0,0,0,0,0,0,TRUE,TRUE,25,MENU_BAND},
-  {TRUE,TRUE,16,1,19,1,0,ENCODER_AGC_GAIN,FALSE,TRUE,0,0,0,0,0,0,TRUE,TRUE,8,MENU_BANDSTACK},
-  {TRUE,TRUE,4,1,21,1,0,ENCODER_DRIVE,FALSE,TRUE,0,0,0,0,0,0,TRUE,TRUE,7,MENU_MODE},
-  {TRUE,TRUE,18,1,17,1,0,ENCODER_VFO,FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0},
-  {FALSE,TRUE,0,1,0,0,1,0,FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0},
+  {TRUE,TRUE,20,1,26,1,0,ENCODER_AF_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,25,MENU_BAND,0L},
+  {TRUE,TRUE,16,1,19,1,0,ENCODER_AGC_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,8,MENU_BANDSTACK,0L},
+  {TRUE,TRUE,4,1,21,1,0,ENCODER_DRIVE,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,7,MENU_MODE,0L},
+  {TRUE,TRUE,18,1,17,1,0,ENCODER_VFO,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+  {FALSE,TRUE,0,1,0,0,1,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
   };
 
 ENCODER encoders_controller2_v1[MAX_ENCODERS]={
-  {TRUE,TRUE,20,1,26,1,0,ENCODER_AF_GAIN,FALSE,TRUE,0,0,0,0,0,0,TRUE,TRUE,22,MENU_BAND},
-  {TRUE,TRUE,4,1,21,1,0,ENCODER_AGC_GAIN,FALSE,TRUE,0,0,0,0,0,0,TRUE,TRUE,27,MENU_BANDSTACK},
-  {TRUE,TRUE,16,1,19,1,0,ENCODER_IF_WIDTH,FALSE,TRUE,0,0,0,0,0,0,TRUE,TRUE,23,MENU_MODE},
-  {TRUE,TRUE,25,1,8,1,0,ENCODER_RIT,FALSE,TRUE,0,0,0,0,0,0,TRUE,TRUE,24,MENU_FREQUENCY},
-  {TRUE,TRUE,18,1,17,1,0,ENCODER_VFO,FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0},
+  {TRUE,TRUE,20,1,26,1,0,ENCODER_AF_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,22,MENU_BAND,0L},
+  {TRUE,TRUE,4,1,21,1,0,ENCODER_AGC_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,27,MENU_BANDSTACK,0L},
+  {TRUE,TRUE,16,1,19,1,0,ENCODER_IF_WIDTH,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,23,MENU_MODE,0L},
+  {TRUE,TRUE,25,1,8,1,0,ENCODER_RIT,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,24,MENU_FREQUENCY,0L},
+  {TRUE,TRUE,18,1,17,1,0,ENCODER_VFO,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
   };
 
 ENCODER encoders_controller2_v2[MAX_ENCODERS]={
-  {TRUE,TRUE,5,1,6,1,0,ENCODER_RF_GAIN,TRUE,TRUE,26,1,20,1,0,ENCODER_AF_GAIN,TRUE,TRUE,22,MENU_BAND},
-  {TRUE,TRUE,9,1,7,1,0,ENCODER_ATTENUATION,TRUE,TRUE,21,1,4,1,0,ENCODER_AGC_GAIN,TRUE,TRUE,27,MENU_MODE},
-  {TRUE,TRUE,11,1,10,1,0,ENCODER_IF_WIDTH,TRUE,TRUE,19,1,16,1,0,ENCODER_IF_SHIFT,TRUE,TRUE,23,MENU_FILTER},
-  {TRUE,TRUE,13,1,12,1,0,ENCODER_XIT,TRUE,TRUE,8,1,25,1,0,ENCODER_RIT,TRUE,TRUE,24,MENU_FREQUENCY},
-  {TRUE,TRUE,18,1,17,1,0,ENCODER_VFO,FALSE,TRUE,0,0,0,0,0,0,FALSE,TRUE,0,0},
+  {TRUE,TRUE,5,1,6,1,0,ENCODER_RF_GAIN,R_START,TRUE,TRUE,26,1,20,1,0,ENCODER_AF_GAIN,R_START,TRUE,TRUE,22,MENU_BAND,0L},
+  {TRUE,TRUE,9,1,7,1,0,ENCODER_ATTENUATION,R_START,TRUE,TRUE,21,1,4,1,0,ENCODER_AGC_GAIN,R_START,TRUE,TRUE,27,MENU_MODE,0L},
+  {TRUE,TRUE,11,1,10,1,0,ENCODER_IF_WIDTH,R_START,TRUE,TRUE,19,1,16,1,0,ENCODER_IF_SHIFT,R_START,TRUE,TRUE,23,MENU_FILTER,0L},
+  {TRUE,TRUE,13,1,12,1,0,ENCODER_XIT,R_START,TRUE,TRUE,8,1,25,1,0,ENCODER_RIT,R_START,TRUE,TRUE,24,MENU_FREQUENCY,0L},
+  {TRUE,TRUE,18,1,17,1,0,ENCODER_VFO,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
   };
 
 ENCODER *encoders=encoders_no_controller;
 
 SWITCH switches_no_controller[MAX_SWITCHES]={
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION},
-  {FALSE,FALSE,0,NO_ACTION}
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L},
+  {FALSE,FALSE,0,NO_ACTION,0L}
   };
 
 SWITCH switches_controller1[MAX_FUNCTIONS][MAX_SWITCHES]={
-  {{TRUE,TRUE,27,MOX},
-   {TRUE,TRUE,13,MENU_BAND},
-   {TRUE,TRUE,12,MENU_BANDSTACK},
-   {TRUE,TRUE,6,MENU_MODE},
-   {TRUE,TRUE,5,MENU_FILTER},
-   {TRUE,TRUE,24,NR},
-   {TRUE,TRUE,23,AGC},
-   {TRUE,TRUE,22,FUNCTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION}},
-  {{TRUE,TRUE,27,MOX},
-   {TRUE,TRUE,13,LOCK},
-   {TRUE,TRUE,12,CTUN},
-   {TRUE,TRUE,6,A_TO_B},
-   {TRUE,TRUE,5,B_TO_A},
-   {TRUE,TRUE,24,A_SWAP_B},
-   {TRUE,TRUE,23,SPLIT},
-   {TRUE,TRUE,22,FUNCTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION}},
-  {{TRUE,TRUE,27,MOX},
-   {TRUE,TRUE,13,MENU_FREQUENCY},
-   {TRUE,TRUE,12,MENU_MEMORY},
-   {TRUE,TRUE,6,RIT},
-   {TRUE,TRUE,5,RIT_PLUS},
-   {TRUE,TRUE,24,RIT_MINUS},
-   {TRUE,TRUE,23,RIT_CLEAR},
-   {TRUE,TRUE,22,FUNCTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION}},
-  {{TRUE,TRUE,27,MOX},
-   {TRUE,TRUE,13,MENU_FREQUENCY},
-   {TRUE,TRUE,12,MENU_MEMORY},
-   {TRUE,TRUE,6,XIT},
-   {TRUE,TRUE,5,XIT_PLUS},
-   {TRUE,TRUE,24,XIT_MINUS},
-   {TRUE,TRUE,23,XIT_CLEAR},
-   {TRUE,TRUE,22,FUNCTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION}},
-  {{TRUE,TRUE,27,MOX},
-   {TRUE,TRUE,13,MENU_FREQUENCY},
-   {TRUE,TRUE,12,SPLIT},
-   {TRUE,TRUE,6,DUPLEX},
-   {TRUE,TRUE,5,SAT},
-   {TRUE,TRUE,24,RSAT},
-   {TRUE,TRUE,23,NO_ACTION},
-   {TRUE,TRUE,22,FUNCTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION}},
-  {{TRUE,TRUE,27,MOX},
-   {TRUE,TRUE,13,TUNE},
-   {TRUE,TRUE,12,TUNE_FULL},
-   {TRUE,TRUE,6,TUNE_MEMORY},
-   {TRUE,TRUE,5,MENU_BAND},
-   {TRUE,TRUE,24,MENU_MODE},
-   {TRUE,TRUE,23,MENU_FILTER},
-   {TRUE,TRUE,22,FUNCTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION},
-   {FALSE,FALSE,0,NO_ACTION}},
+  {{TRUE,TRUE,27,MOX,0L},
+   {TRUE,TRUE,13,MENU_BAND,0L},
+   {TRUE,TRUE,12,MENU_BANDSTACK,0L},
+   {TRUE,TRUE,6,MENU_MODE,0L},
+   {TRUE,TRUE,5,MENU_FILTER,0L},
+   {TRUE,TRUE,24,NR,0L},
+   {TRUE,TRUE,23,AGC,0L},
+   {TRUE,TRUE,22,FUNCTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L}},
+  {{TRUE,TRUE,27,MOX,0L},
+   {TRUE,TRUE,13,LOCK,0L},
+   {TRUE,TRUE,12,CTUN,0L},
+   {TRUE,TRUE,6,A_TO_B,0L},
+   {TRUE,TRUE,5,B_TO_A,0L},
+   {TRUE,TRUE,24,A_SWAP_B,0L},
+   {TRUE,TRUE,23,SPLIT,0L},
+   {TRUE,TRUE,22,FUNCTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L}},
+  {{TRUE,TRUE,27,MOX,0L},
+   {TRUE,TRUE,13,MENU_FREQUENCY,0L},
+   {TRUE,TRUE,12,MENU_MEMORY,0L},
+   {TRUE,TRUE,6,RIT,0L},
+   {TRUE,TRUE,5,RIT_PLUS,0L},
+   {TRUE,TRUE,24,RIT_MINUS,0L},
+   {TRUE,TRUE,23,RIT_CLEAR,0L},
+   {TRUE,TRUE,22,FUNCTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L}},
+  {{TRUE,TRUE,27,MOX,0L},
+   {TRUE,TRUE,13,MENU_FREQUENCY,0L},
+   {TRUE,TRUE,12,MENU_MEMORY,0L},
+   {TRUE,TRUE,6,XIT,0L},
+   {TRUE,TRUE,5,XIT_PLUS,0L},
+   {TRUE,TRUE,24,XIT_MINUS,0L},
+   {TRUE,TRUE,23,XIT_CLEAR,0L},
+   {TRUE,TRUE,22,FUNCTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L}},
+  {{TRUE,TRUE,27,MOX,0L},
+   {TRUE,TRUE,13,MENU_FREQUENCY,0L},
+   {TRUE,TRUE,12,SPLIT,0L},
+   {TRUE,TRUE,6,DUPLEX,0L},
+   {TRUE,TRUE,5,SAT,0L},
+   {TRUE,TRUE,24,RSAT,0L},
+   {TRUE,TRUE,23,NO_ACTION,0L},
+   {TRUE,TRUE,22,FUNCTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L}},
+  {{TRUE,TRUE,27,MOX,0L},
+   {TRUE,TRUE,13,TUNE,0L},
+   {TRUE,TRUE,12,TUNE_FULL,0L},
+   {TRUE,TRUE,6,TUNE_MEMORY,0L},
+   {TRUE,TRUE,5,MENU_BAND,0L},
+   {TRUE,TRUE,24,MENU_MODE,0L},
+   {TRUE,TRUE,23,MENU_FILTER,0L},
+   {TRUE,TRUE,22,FUNCTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L},
+   {FALSE,FALSE,0,NO_ACTION,0L}},
 
   };
 
 SWITCH switches_controller2_v1[MAX_SWITCHES]={
-  {FALSE,FALSE,0,MOX},
-  {FALSE,FALSE,0,TUNE},
-  {FALSE,FALSE,0,PS},
-  {FALSE,FALSE,0,TWO_TONE},
-  {FALSE,FALSE,0,NR},
-  {FALSE,FALSE,0,A_TO_B},
-  {FALSE,FALSE,0,B_TO_A},
-  {FALSE,FALSE,0,MODE_MINUS},
-  {FALSE,FALSE,0,BAND_MINUS},
-  {FALSE,FALSE,0,MODE_PLUS},
-  {FALSE,FALSE,0,BAND_PLUS},
-  {FALSE,FALSE,0,XIT},
-  {FALSE,FALSE,0,NB},
-  {FALSE,FALSE,0,SNB},
-  {FALSE,FALSE,0,LOCK},
-  {FALSE,FALSE,0,CTUN}
+  {FALSE,FALSE,0,MOX,0L},
+  {FALSE,FALSE,0,TUNE,0L},
+  {FALSE,FALSE,0,PS,0L},
+  {FALSE,FALSE,0,TWO_TONE,0L},
+  {FALSE,FALSE,0,NR,0L},
+  {FALSE,FALSE,0,A_TO_B,0L},
+  {FALSE,FALSE,0,B_TO_A,0L},
+  {FALSE,FALSE,0,MODE_MINUS,0L},
+  {FALSE,FALSE,0,BAND_MINUS,0L},
+  {FALSE,FALSE,0,MODE_PLUS,0L},
+  {FALSE,FALSE,0,BAND_PLUS,0L},
+  {FALSE,FALSE,0,XIT,0L},
+  {FALSE,FALSE,0,NB,0L},
+  {FALSE,FALSE,0,SNB,0L},
+  {FALSE,FALSE,0,LOCK,0L},
+  {FALSE,FALSE,0,CTUN,0L}
   };
 
 SWITCH switches_controller2_v2[MAX_SWITCHES]={
-  {FALSE,FALSE,0,MOX},
-  {FALSE,FALSE,0,TUNE},
-  {FALSE,FALSE,0,PS},
-  {FALSE,FALSE,0,TWO_TONE},
-  {FALSE,FALSE,0,NR},
-  {FALSE,FALSE,0,A_TO_B},
-  {FALSE,FALSE,0,B_TO_A},
-  {FALSE,FALSE,0,MODE_MINUS},
-  {FALSE,FALSE,0,BAND_MINUS},
-  {FALSE,FALSE,0,MODE_PLUS},
-  {FALSE,FALSE,0,BAND_PLUS},
-  {FALSE,FALSE,0,XIT},
-  {FALSE,FALSE,0,NB},
-  {FALSE,FALSE,0,SNB},
-  {FALSE,FALSE,0,LOCK},
-  {FALSE,FALSE,0,CTUN}
+  {FALSE,FALSE,0,MOX,0L},
+  {FALSE,FALSE,0,TUNE,0L},
+  {FALSE,FALSE,0,PS,0L},
+  {FALSE,FALSE,0,TWO_TONE,0L},
+  {FALSE,FALSE,0,NR,0L},
+  {FALSE,FALSE,0,A_TO_B,0L},
+  {FALSE,FALSE,0,B_TO_A,0L},
+  {FALSE,FALSE,0,MODE_MINUS,0L},
+  {FALSE,FALSE,0,BAND_MINUS,0L},
+  {FALSE,FALSE,0,MODE_PLUS,0L},
+  {FALSE,FALSE,0,BAND_PLUS,0L},
+  {FALSE,FALSE,0,XIT,0L},
+  {FALSE,FALSE,0,NB,0L},
+  {FALSE,FALSE,0,SNB,0L},
+  {FALSE,FALSE,0,LOCK,0L},
+  {FALSE,FALSE,0,CTUN,0L}
   };
 
 SWITCH *switches=switches_controller1[0];
 
 static int running=0;
 
-/*
-char *encoder_string[ENCODER_ACTIONS] = {
-  "NO ACTION",
-  "AF GAIN",
-  "AF GAIN RX1",
-  "AF GAIN RX2",
-  "AGC GAIN",
-  "AGC GAIN RX1",
-  "AGC GAIN RX2",
-  "ATTENUATION/RX GAIN",
-  "COMP",
-  "CW FREQUENCY",
-  "CW SPEED",
-  "DIVERSITY GAIN",
-  "DIVERSITY GAIN (coarse)",
-  "DIVERSITY GAIN (fine)",
-  "DIVERSITY PHASE",
-  "DIVERSITY PHASE (coarse)",
-  "DIVERSITY PHASE (fine)",
-  "DRIVE",
-  "IF SHIFT",
-  "IF SHIFT RX1",
-  "IF SHIFT RX2",
-  "IF WIDTH",
-  "IF WIDTH RX1",
-  "IF WIDTH RX2",
-  "MIC GAIN",
-  "PAN",
-  "PANADAPTER HIGH",
-  "PANADAPTER LOW",
-  "PANADAPTER STEP",
-  "RF GAIN",
-  "RF GAIN RX1",
-  "RF GAIN RX2",
-  "RIT",
-  "RIT RX1",
-  "RIT RX2",
-  "SQUELCH",
-  "SQUELCH RX1",
-  "SQUELCH RX2",
-  "TUNE DRIVE",
-  "VFO",
-  "WATERFALL HIGH",
-  "WATERFALL LOW",
-  "XIT",
-  "ZOOM",
-};
-
-char *sw_string[SWITCH_ACTIONS] = {
-  "NO ACTION",
-  "A TO B",
-  "A SWAP B",
-  "AGC",
-  "ANF",
-  "B TO A",
-  "BAND -",
-  "BAND +",
-  "BSTACK -",
-  "BSTACK +",
-  "CTUN",
-  "DIV",
-  "DUPLEX",
-  "FILTER -",
-  "FILTER +",
-  "FUNCTION",
-  "LOCK",
-  "MENU AGC",
-  "MENU BAND",
-  "MENU BSTACK",
-  "MENU DIV",
-  "MENU FILTER",
-  "MENU FREQUENCY",
-  "MENU MEMORY",
-  "MENU MODE",
-  "MENU NOISE",
-  "MENU PS",
-  "MODE -",
-  "MODE +",
-  "MOX",
-  "MUTE",
-  "NB",
-  "NR",
-  "PAN -",
-  "PAN +",
-  "PS",
-  "RIT",
-  "RIT CL",
-  "RIT +",
-  "RIT -",
-  "RSAT",
-  "SAT",
-  "SNB",
-  "SPLIT",
-  "TUNE",
-  "TUNE FULL",
-  "TUNE MEM",
-  "TWO TONE",
-  "XIT",
-  "XIT CL",
-  "XIT +",
-  "XIT -",
-  "ZOOM -",
-  "ZOOM +",
-};
-
-char *sw_cap_string[SWITCH_ACTIONS] = {
-  "",
-  "A>B",
-  "A<>B",
-  "AGC",
-  "ANF",
-  "B>A",
-  "BND-",
-  "BND+",
-  "BST-",
-  "BST+",
-  "CTUN",
-  "DIV",
-  "DUP",
-  "FLT-",
-  "FLT+",
-  "FUNC",
-  "LOCK",
-  "AGC",
-  "BAND",
-  "BSTACK",
-  "DIV",
-  "FILTER",
-  "FREQ",
-  "MEM",
-  "MODE",
-  "NOISE",
-  "PS",
-  "MD-",
-  "MD+",
-  "MOX",
-  "MUTE",
-  "NB",
-  "NR",
-  "PAN-",
-  "PAN+",
-  "PS",
-  "RIT",
-  "RIT0",
-  "RIT+",
-  "RIT-",
-  "RSAT",
-  "SAT",
-  "SNB",
-  "SPLIT",
-  "TUNE",
-  "TUN-F",
-  "TUN-M",
-  "2TONE",
-  "XIT",
-  "XIT0",
-  "XIT+",
-  "XIT-",
-  "ZOOM-",
-  "ZOOM+",
-};
-*/
-
-int *sw_action=NULL;
-
 static GThread *rotary_encoder_thread_id;
 
 static uint64_t epochMilli;
@@ -499,11 +366,13 @@ static gpointer rotary_encoder_thread(gpointer data) {
   ENCODER_ACTION *a;
   int i;
 
-  sleep(2);
+  usleep(250000);
+  g_print("%s\n",__FUNCTION__);
   while(TRUE) {
     g_mutex_lock(&encoder_mutex);
     for(i=0;i<MAX_ENCODERS;i++) {
       if(encoders[i].bottom_encoder_enabled && encoders[i].bottom_encoder_pos!=0) {
+        //g_print("%s: BOTTOM encoder %d pos=%d\n",__FUNCTION__,i,encoders[i].bottom_encoder_pos);
         a=g_new(ENCODER_ACTION,1);
         a->action=encoders[i].bottom_encoder_function;
         a->mode=RELATIVE;
@@ -512,10 +381,11 @@ static gpointer rotary_encoder_thread(gpointer data) {
         encoders[i].bottom_encoder_pos=0;
       }
       if(encoders[i].top_encoder_enabled && encoders[i].top_encoder_pos!=0) {
+        //g_print("%s: TOP encoder %d pos=%d\n",__FUNCTION__,i,encoders[i].top_encoder_pos);
         a=g_new(ENCODER_ACTION,1);
-        a->action=encoders[i].bottom_encoder_function;
+        a->action=encoders[i].top_encoder_function;
         a->mode=RELATIVE;
-        a->val=encoders[i].bottom_encoder_pos;
+        a->val=encoders[i].top_encoder_pos;
         g_idle_add(encoder_action,a);
         encoders[i].top_encoder_pos=0;
       }
@@ -539,22 +409,52 @@ int process_function_switch(void *data) {
 static unsigned long switch_debounce;
 
 static void process_encoder(int e,int l,int addr,int val) {
-//  g_print("%s: encoder=%d level=%d addr=0x%02X val=%d\n",__FUNCTION__,e,l,addr,val);
+  guchar pinstate;
+  //g_print("%s: encoder=%d level=%d addr=0x%02X val=%d\n",__FUNCTION__,e,l,addr,val);
   g_mutex_lock(&encoder_mutex);
   switch(l) {
     case BOTTOM_ENCODER:
       switch(addr) {
         case A:
           encoders[e].bottom_encoder_a_value=val;
-          if(encoders[e].bottom_encoder_a_value==encoders[e].bottom_encoder_b_value) {
-            encoders[e].bottom_encoder_pos++;
-          } else {
-            encoders[e].bottom_encoder_pos--;
+          pinstate=(encoders[e].bottom_encoder_b_value<<1) | encoders[e].bottom_encoder_a_value;
+          encoders[e].bottom_encoder_state=encoder_state_table[encoders[e].bottom_encoder_state&0xf][pinstate];
+          //g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].bottom_encoder_state);
+          switch(encoders[e].bottom_encoder_state&0x30) {
+            case DIR_NONE:
+              break;
+            case DIR_CW:
+              encoders[e].bottom_encoder_pos++;
+              break;
+            case DIR_CCW:
+              encoders[e].bottom_encoder_pos--;
+              break;
+            default:
+              break;
           }
+
           //g_print("%s: %s BOTTOM pos=%d\n",__FUNCTION__,encoder_string[encoders[e].bottom_encoder_function],encoders[e].bottom_encoder_pos);
           break;
         case B:
           encoders[e].bottom_encoder_b_value=val;
+          pinstate=(encoders[e].bottom_encoder_b_value<<1) | encoders[e].bottom_encoder_a_value;
+          encoders[e].bottom_encoder_state=encoder_state_table[encoders[e].bottom_encoder_state&0xf][pinstate];
+          //g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].bottom_encoder_state);
+          switch(encoders[e].bottom_encoder_state&0x30) {
+            case DIR_NONE:
+              break;
+            case DIR_CW:
+              encoders[e].bottom_encoder_pos++;
+              break;
+            case DIR_CCW:
+              encoders[e].bottom_encoder_pos--;
+              break;
+            default:
+              break;
+          }
+
+          //g_print("%s: %s BOTTOM pos=%d\n",__FUNCTION__,encoder_string[encoders[e].bottom_encoder_function],encoders[e].bottom_encoder_pos);
+
           break;
       }
       break;
@@ -562,15 +462,42 @@ static void process_encoder(int e,int l,int addr,int val) {
       switch(addr) {
         case A:
           encoders[e].top_encoder_a_value=val;
-          if(encoders[e].top_encoder_a_value==encoders[e].top_encoder_b_value) {
-            encoders[e].top_encoder_pos++;
-          } else {
-            encoders[e].top_encoder_pos--;
+          pinstate=(encoders[e].top_encoder_b_value<<1) | encoders[e].top_encoder_a_value;
+          encoders[e].top_encoder_state=encoder_state_table[encoders[e].top_encoder_state&0xf][pinstate];
+          //g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].top_encoder_state);
+          switch(encoders[e].top_encoder_state&0x30) {
+            case DIR_NONE:
+              break;
+            case DIR_CW:
+              encoders[e].top_encoder_pos++;
+              break;
+            case DIR_CCW:
+              encoders[e].top_encoder_pos--;
+              break;
+            default:
+              break;
           }
-          g_print("%s: %s TOP pos=%d\n",__FUNCTION__,encoder_string[encoders[e].top_encoder_function],encoders[e].bottom_encoder_pos);
+          //g_print("%s: %s TOP pos=%d\n",__FUNCTION__,encoder_string[encoders[e].top_encoder_function],encoders[e].top_encoder_pos);
           break;
         case B:
           encoders[e].top_encoder_b_value=val;
+          pinstate=(encoders[e].top_encoder_b_value<<1) | encoders[e].top_encoder_a_value;
+          encoders[e].top_encoder_state=encoder_state_table[encoders[e].top_encoder_state&0xf][pinstate];
+          //g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].top_encoder_state);
+          switch(encoders[e].top_encoder_state&0x30) {
+            case DIR_NONE:
+              break;
+            case DIR_CW:
+              encoders[e].top_encoder_pos++;
+              break;
+            case DIR_CCW:
+              encoders[e].top_encoder_pos--;
+              break;
+            default:
+              break;
+          }
+          //g_print("%s: %s TOP pos=%d\n",__FUNCTION__,encoder_string[encoders[e].top_encoder_function],encoders[e].top_encoder_pos);
+
           break;
       }
       break;
@@ -583,6 +510,7 @@ static void process_edge(int offset,int value) {
   gint t;
   gboolean found;
 
+  //g_print("%s: offset=%d value=%d\n",__FUNCTION__,offset,value);
   found=FALSE;
 #ifdef LOCALCW
   if(ENABLE_CW_BUTTONS) {
@@ -619,7 +547,7 @@ static void process_edge(int offset,int value) {
       found=TRUE;
       break;
     } else if(encoders[i].switch_enabled && encoders[i].switch_address==offset) {
-      g_print("%s: found %d encoder %d switch\n",__FUNCTION__,offset,i);
+      //g_print("%s: found %d encoder %d switch\n",__FUNCTION__,offset,i);
       SWITCH_ACTION *a=g_new(SWITCH_ACTION,1);
       a->action=encoders[i].switch_function;
       a->state=value;
@@ -629,16 +557,25 @@ static void process_edge(int offset,int value) {
     }
   }
 
+  if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
+    if(I2C_INTERRUPT==offset) {
+      if(value==PRESSED) {
+        i2c_interrupt();
+      }
+      found=TRUE;
+    }
+  }
+
   if(!found) {
     for(i=0;i<MAX_SWITCHES;i++) {
       if(switches[i].switch_enabled && switches[i].switch_address==offset) {
         t=millis();
-        g_print("%s: found %d switch %d value=%d t=%d\n",__FUNCTION__,offset,i,value,t);
+        //g_print("%s: found %d switch %d value=%d t=%d\n",__FUNCTION__,offset,i,value,t);
         found=TRUE;
-        if(t<switch_debounce) {
+        if(t<switches[i].switch_debounce) {
           return;
         }
-        switch_debounce=t+settle_time;
+        switches[i].switch_debounce=t+settle_time;
         SWITCH_ACTION *a=g_new(SWITCH_ACTION,1);
         a->action=switches[i].switch_function;
         a->state=value;
@@ -647,6 +584,8 @@ static void process_edge(int offset,int value) {
       }
     }
   }
+
+
   if(!found) {
     g_print("%s: could not find %d\n",__FUNCTION__,offset);
   }
@@ -838,6 +777,7 @@ void gpio_save_state() {
         setProperty(name,value);
       }
     }
+/*
   } else {
     for(int i=0;i<MAX_SWITCHES;i++) {
       sprintf(name,"switches[%d].switch_enabled",i);
@@ -850,6 +790,7 @@ void gpio_save_state() {
       sprintf(value,"%d",switches[i].switch_address);
       setProperty(name,value);
     }
+*/
   }
 
   saveProperties("gpio.props");
@@ -1064,6 +1005,7 @@ int gpio_init() {
   }
 
   if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
+    i2c_init();
     g_print("%s: setup i2c interrupt %d\n",__FUNCTION__,I2C_INTERRUPT);
     if((ret=setup_line(chip,I2C_INTERRUPT,TRUE))<0) {
       goto err;
@@ -1115,6 +1057,7 @@ int gpio_init() {
       g_print("%s: rotary_encoder_thread: id=%p\n",__FUNCTION__,rotary_encoder_thread_id);
     }
   }
+
 #endif
   return 0;
 
diff --git a/gpio.h b/gpio.h
index 5ef78dfef165e683c06e2618d533ed20c855e4ff..a9072f53f409ad4411c37d2c70e66fc528ccbd44 100644 (file)
--- a/gpio.h
+++ b/gpio.h
@@ -33,6 +33,7 @@ typedef struct _encoder {
   gint bottom_encoder_b_value;
   gint bottom_encoder_pos;
   gint bottom_encoder_function;
+  guchar bottom_encoder_state;
   gint top_encoder_enabled;
   gboolean top_encoder_pullup;
   gint top_encoder_address_a;
@@ -41,10 +42,12 @@ typedef struct _encoder {
   gint top_encoder_b_value;
   gint top_encoder_pos;
   gint top_encoder_function;
+  guchar top_encoder_state;
   gboolean switch_enabled;
   gboolean switch_pullup;
   gint switch_address;
   gint switch_function;
+  gulong switch_debounce;
 } ENCODER;
 
 extern ENCODER *encoders;
@@ -54,6 +57,7 @@ typedef struct _switch {
   gboolean switch_pullup;
   gint switch_address;
   gint switch_function;
+  gulong switch_debounce;
 } SWITCH;
 
 extern SWITCH switches_no_controller[MAX_SWITCHES];
diff --git a/i2c.c b/i2c.c
index a0566a8848d97505b50711d175dff650dfef5dda..fe1ab3499c99beca02a0c0d48b7e72b281e96aee 100644 (file)
--- a/i2c.c
+++ b/i2c.c
@@ -92,8 +92,8 @@ void i2c_interrupt() {
           if(i2c_sw[i]==ints) break;
         }
         if(i<16) {
-//g_print("i1c_interrupt: sw=%d action=%d\n",i,sw_action[i]);
-          switch(sw_action[i]) {
+//g_print("i1c_interrupt: sw=%d action=%d\n",i,switches[i].switch_function);
+          switch(switches[i].switch_function) {
             case TUNE:
               if(can_transmit) {
                 int tune=getTune();
diff --git a/meter.c b/meter.c
index e4ae92ce551dc2a54f2beef049a6a6b2e676189e..dbea87a3444794faff1b84ff1203e38e8eae4d80 100644 (file)
--- a/meter.c
+++ b/meter.c
@@ -199,7 +199,8 @@ if(analog_meter) {
       }
 #ifdef SOAPYSDR
       if(protocol==SOAPYSDR_PROTOCOL) {
-       level-=rx->rf_gain;
+        //level-=rx->rf_gain;
+        level-=adc[rx->id].gain;
       }
 #endif
       if (filter_board == CHARLY25) {
@@ -568,7 +569,8 @@ if(analog_meter) {
       }
 #ifdef SOAPYSDR
       if(protocol==SOAPYSDR_PROTOCOL) {
-       level-=rx->rf_gain;
+        //level-=rx->rf_gain;
+        level-=adc[rx->id].gain;
       }
 #endif
       if (filter_board == CHARLY25) {
diff --git a/midi3.c b/midi3.c
index 212f3c632815613a145d5d0a3c2a2f02f45f2059..8c0f2143aa2d6df1cc031c4da39e195ac018f3f9 100644 (file)
--- a/midi3.c
+++ b/midi3.c
@@ -765,7 +765,8 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
             if (type == MIDI_KNOB) {
                 new=val;
             } else  if (type == MIDI_WHEEL) {
-                new=(int)active_receiver->rf_gain+val;
+                //new=(int)active_receiver->rf_gain+val;
+                new=(int)adc[active_receiver->id].gain+val;
             }
             g_idle_add(ext_set_rf_gain, GINT_TO_POINTER((int)new));
            break;
index 2a8548044b8b86704b614cb780505debdda873b9..adf09cd8e6aef2b67ece43d31c9c178c5ecf636e 100644 (file)
@@ -485,6 +485,10 @@ static void add_cb(GtkButton *widget,gpointer user_data) {
   gint type;
   gint action;
 
+  if(str_type==NULL || str_action==NULL) {
+    return;
+  }
+
   if(strcmp(str_type,"KEY")==0) {
     type=MIDI_KEY;
   } else if(strcmp(str_type,"KNOB/SLIDER")==0) {
@@ -871,17 +875,19 @@ static int update(void *data) {
       gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"NONE");
       switch(thisEvent) {
         case EVENT_NONE:
+          gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
           break;
         case MIDI_NOTE:
         case MIDI_PITCH:
           gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"KEY");
+          gtk_combo_box_set_active (GTK_COMBO_BOX(newType),1);
           break;
         case MIDI_CTRL:
           gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"KNOB/SLIDER");
           gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"WHEEL");
+          gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
           break;
       }
-      gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
       gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(newAction));
       gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newAction),NULL,"NONE");
       gtk_combo_box_set_active (GTK_COMBO_BOX(newAction),0);
index 054c2bca0e75bf746100f93f8479fecf7cf06240..d8f931059d53c1abecaa5cf7943f5d0332f5afca 100644 (file)
@@ -1782,7 +1782,9 @@ static int last_power=0;
          // is stored in rx_gain_slider. The firmware uses bit 6
          // of C4 to determine this case.
          //
-          int rxgain = adc_attenuation[active_receiver->adc]+12; // -12..48 to 0..60
+          //int rxgain = adc_attenuation[active_receiver->adc]+12; // -12..48 to 0..60
+          int rxgain = adc[active_receiver->adc].gain+12; // -12..48 to 0..60
+
           if (rxgain <  0) rxgain=0;
           if (rxgain > 60) rxgain=60;
          // encode all 6 bits of RXgain in ATT value and set bit6
@@ -1795,7 +1797,8 @@ static int last_power=0;
           if (isTransmitting()) {
             output_buffer[C4]=0x20 | (transmitter->attenuation & 0x1F);
           } else {
-            output_buffer[C4]=0x20 | (adc_attenuation[0] & 0x1F);
+            //output_buffer[C4]=0x20 | (adc_attenuation[0] & 0x1F);
+            output_buffer[C4]=0x20 | ((int)adc[0].gain & 0x1F);
           } 
         }
        break;
diff --git a/radio.c b/radio.c
index 05c1056ed69c743373ac9b7866cf10336c1ea47f..f0e09b85e7b3416ca2d7afed35ccf43420b530c9 100644 (file)
--- a/radio.c
+++ b/radio.c
@@ -480,14 +480,14 @@ static void create_visual() {
 
 
   GtkWidget *minimize_b=gtk_button_new_with_label("Hide");
-  gtk_widget_override_font(minimize_b, pango_font_description_from_string("FreeSans Bold 10"));
+  gtk_widget_override_font(minimize_b, pango_font_description_from_string("FreeSans Bold 8"));
   gtk_widget_set_size_request (minimize_b, MENU_WIDTH, MENU_HEIGHT);
   g_signal_connect (minimize_b, "button-press-event", G_CALLBACK(minimize_cb), NULL) ;
   gtk_fixed_put(GTK_FIXED(fixed),minimize_b,VFO_WIDTH+METER_WIDTH,y);
   y+=MENU_HEIGHT;
 
   GtkWidget *menu_b=gtk_button_new_with_label("Menu");
-  gtk_widget_override_font(menu_b, pango_font_description_from_string("FreeSans Bold 10"));
+  gtk_widget_override_font(menu_b, pango_font_description_from_string("FreeSans Bold 8"));
   gtk_widget_set_size_request (menu_b, MENU_WIDTH, MENU_HEIGHT);
   g_signal_connect (menu_b, "button-press-event", G_CALLBACK(menu_cb), NULL) ;
   gtk_fixed_put(GTK_FIXED(fixed),menu_b,VFO_WIDTH+METER_WIDTH,y);
@@ -567,24 +567,26 @@ if(!radio_is_remote) {
     calcDriveLevel();
 
 #ifdef PURESIGNAL
-    tx_set_ps_sample_rate(transmitter,protocol==NEW_PROTOCOL?192000:active_receiver->sample_rate);
-    receiver[PS_TX_FEEDBACK]=create_pure_signal_receiver(PS_TX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width);
-    receiver[PS_RX_FEEDBACK]=create_pure_signal_receiver(PS_RX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width);
-    switch (protocol) {
-      case NEW_PROTOCOL:
-        pk = 0.2899;
-        break;
-      case ORIGINAL_PROTOCOL:
-        switch (device) {
-          case DEVICE_HERMES_LITE2:
-            pk = 0.2300;
-            break;
-          default:
-            pk = 0.4067;
-            break;
-        }
+    if(protocol==NEW_PROTOCOL || protocol==ORIGINAL_PROTOCOL) {
+      tx_set_ps_sample_rate(transmitter,protocol==NEW_PROTOCOL?192000:active_receiver->sample_rate);
+      receiver[PS_TX_FEEDBACK]=create_pure_signal_receiver(PS_TX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width);
+      receiver[PS_RX_FEEDBACK]=create_pure_signal_receiver(PS_RX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width);
+      switch (protocol) {
+        case NEW_PROTOCOL:
+          pk = 0.2899;
+          break;
+        case ORIGINAL_PROTOCOL:
+          switch (device) {
+            case DEVICE_HERMES_LITE2:
+              pk = 0.2300;
+              break;
+            default:
+              pk = 0.4067;
+              break;
+          }
+      }
+      SetPSHWPeak(transmitter->id, pk);
     }
-    SetPSHWPeak(transmitter->id, pk);
 #endif
 
   }
@@ -1111,6 +1113,13 @@ void start_radio() {
   adc[0].antenna=0;
   if(device==SOAPYSDR_USB_DEVICE) {
     adc[0].gain=0;
+    if(radio->info.soapy.rx_gains>0) {
+      adc[0].min_gain=radio->info.soapy.rx_range[0].minimum;
+      adc[0].max_gain=radio->info.soapy.rx_range[0].maximum;;
+    } else {
+      adc[0].min_gain=0.0;
+      adc[0].max_gain=100.0;
+    }
     adc[0].agc=FALSE;
     dac[0].antenna=1;
     dac[0].gain=0;
@@ -1129,6 +1138,14 @@ void start_radio() {
   adc[1].antenna=0;
   if(device==SOAPYSDR_USB_DEVICE) {
     adc[1].gain=0;
+    if(radio->info.soapy.rx_gains>0) {
+      adc[1].min_gain=radio->info.soapy.rx_range[0].minimum;
+      adc[1].max_gain=radio->info.soapy.rx_range[0].maximum;;
+    } else {
+      adc[1].min_gain=0.0;
+      adc[1].max_gain=100.0;
+    }
+    adc[1].max_gain=0;
     adc[1].agc=FALSE;
     dac[1].antenna=1;
     dac[1].gain=0;
@@ -1799,11 +1816,22 @@ void setSquelch(RECEIVER *rx) {
   SetRXAFMSQRun(rx->id, rx->squelch_enable);
 }
 
+void radio_set_rf_gain(RECEIVER *rx) {
+#ifdef SOAPYSDR
+  soapy_protocol_set_gain_element(rx,radio->info.soapy.rx_gain[rx->adc],(int)adc[rx->adc].gain);
+#endif
+}
+
 void set_attenuation(int value) {
     switch(protocol) {
       case NEW_PROTOCOL:
         schedule_high_priority();
         break;
+#ifdef SOAPYSDR
+      case SOAPYSDR_PROTOCOL:
+       soapy_protocol_set_gain_element(active_receiver,radio->info.soapy.rx_gain[0],(int)adc[0].gain);
+       break;
+#endif
     }
 }
 
@@ -1872,6 +1900,9 @@ g_print("radioRestoreState: %s\n",property_path);
 #endif
   } else {
 #endif
+
+    value=getProperty("radio_sample_rate");
+    if (value) radio_sample_rate=atoi(value);
     value=getProperty("diversity_enabled");
     if (value) diversity_enabled=atoi(value);
     value=getProperty("diversity_gain");
@@ -2166,6 +2197,8 @@ g_print("radioSaveState: %s\n",property_path);
 #ifdef CLIENT_SERVER
   if(!radio_is_remote) {
 #endif
+    sprintf(value,"%d",radio_sample_rate);
+    setProperty("radio_sample_rate",value);
     sprintf(value,"%d",diversity_enabled);
     setProperty("diversity_enabled",value);
     sprintf(value,"%f",div_gain);
@@ -2510,7 +2543,9 @@ int remote_start(void *data) {
   for(int i=0;i<receivers;i++) {
     receiver_restore_state(receiver[i]);
     if(receiver[i]->local_audio) {
-      audio_open_output(receiver[i]);
+      if(audio_open_output(receiver[i])) {
+        receiver[i]->local_audio=0;
+      }
     }
   }
   reconfigure_radio();
diff --git a/radio.h b/radio.h
index 4fbd580e930b9f0449cc9d11ac9127036c9bbc0f..0f02ecbd351de6078c756769ea033cc68cddad3d 100644 (file)
--- a/radio.h
+++ b/radio.h
@@ -345,6 +345,8 @@ extern void setTuneDrive(double d);
 extern void calcTuneDriveLevel();
 extern void setSquelch(RECEIVER *rx);
 
+extern void radio_set_rf_gain(RECEIVER *rx);
+
 extern void set_attenuation(int value);
 extern void set_alex_rx_antenna(int v);
 extern void set_alex_tx_antenna(int v);
index f77a6ccfa69f328347462c838136104daa257990..fbc3080409cd8a52fade7bbd05380e7dd7475477 100644 (file)
@@ -93,20 +93,18 @@ static void rf_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
 
 static void rx_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
   ADC *adc=(ADC *)data;
-  int gain;
   if(radio->device==SOAPYSDR_USB_DEVICE) {
-    gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
-    soapy_protocol_set_gain_element(receiver[0],(char *)gtk_widget_get_name(widget),gain);
-
+    adc->gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+    soapy_protocol_set_gain_element(receiver[0],(char *)gtk_widget_get_name(widget),adc->gain);
 /*
     for(int i=0;i<radio->info.soapy.rx_gains;i++) {
       if(strcmp(radio->info.soapy.rx_gain[i],(char *)gtk_widget_get_name(widget))==0) {
         adc[0].rx_gain[i]=gain;
+        soapy_protocol_set_gain_element(receiver[0],(char *)gtk_widget_get_name(widget),gain);
         break;
       }
     }
 */
-
   }
 }
 
@@ -145,7 +143,10 @@ static void tx_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
 static void agc_changed_cb(GtkWidget *widget, gpointer data) {
   ADC *adc=(ADC *)data;
   gboolean agc=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
-  soapy_protocol_set_automatic_gain(receiver[0],agc);
+  soapy_protocol_set_automatic_gain(active_receiver,agc);
+  if(!agc) {
+    soapy_protocol_set_gain(active_receiver);
+  } 
 }
 
 /*
@@ -850,7 +851,7 @@ void radio_menu(GtkWidget *parent) {
     row++;
     temp_row=row;
     col=0;
-    if(strcmp(radio->name,"sdrplay")==0) {
+    if(strcmp(radio->name,"sdrplay")==0 || strcmp(radio->name,"rtlsdr")==0) {
       for(i=0;i<radio->info.soapy.rx_gains;i++) {
         col=0;
         GtkWidget *rx_gain_label=gtk_label_new(radio->info.soapy.rx_gain[i]);
@@ -883,7 +884,8 @@ void radio_menu(GtkWidget *parent) {
         max=73.0;
       }
       GtkWidget *rf_gain_b=gtk_spin_button_new_with_range(0.0,max,1.0);
-      gtk_spin_button_set_value(GTK_SPIN_BUTTON(rf_gain_b),active_receiver->rf_gain);
+      //gtk_spin_button_set_value(GTK_SPIN_BUTTON(rf_gain_b),active_receiver->rf_gain);
+      gtk_spin_button_set_value(GTK_SPIN_BUTTON(rf_gain_b),adc[active_receiver->id].gain);
       gtk_grid_attach(GTK_GRID(grid),rf_gain_b,col,row,1,1);
       g_signal_connect(rf_gain_b,"value_changed",G_CALLBACK(rf_gain_value_changed_cb),&adc[0]);
 
index eb9ba057aa16ca8cea419c9d1598e6486a95eada..0bbaed412f4e94b237d8141a7931cb738fbd82a4 100644 (file)
@@ -69,7 +69,7 @@ static int waterfall_resample=6;
 
 void receiver_weak_notify(gpointer data,GObject  *obj) {
   RECEIVER *rx=(RECEIVER *)data;
-  fprintf(stderr,"receiver_weak_notify: id=%d obj=%p\n",rx->id, obj);
+  g_print("%s: id=%d obj=%p\n",__FUNCTION__,rx->id, obj);
 }
 
 gboolean receiver_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) {
@@ -175,7 +175,7 @@ void receiver_save_state(RECEIVER *rx) {
   char name[128];
   char value[128];
 
-  g_print("receiver_save_state: %d\n",rx->id);
+  g_print("%s: %d\n",__FUNCTION__,rx->id);
   sprintf(name,"receiver.%d.audio_channel",rx->id);
   sprintf(value,"%d",rx->audio_channel);
   setProperty(name,value);
@@ -212,7 +212,11 @@ void receiver_save_state(RECEIVER *rx) {
     // for PS_RX_RECEIVER, *only* save the ALEX antenna setting
     // and then return quickly.
     //
-    if (rx->id == PS_RX_FEEDBACK) return;
+    if (rx->id == PS_RX_FEEDBACK
+#ifdef SOAPYSDR
+        && protocol!=SOAPYSDR_PROTOCOL
+#endif
+       ) return;
 #endif
 
     sprintf(name,"receiver.%d.sample_rate",rx->id);
@@ -258,9 +262,9 @@ void receiver_save_state(RECEIVER *rx) {
     sprintf(name,"receiver.%d.volume",rx->id);
     sprintf(value,"%f",rx->volume);
     setProperty(name,value);
-    sprintf(name,"receiver.%d.rf_gain",rx->id);
-    sprintf(value,"%f",rx->rf_gain);
-    setProperty(name,value);
+    //sprintf(name,"receiver.%d.rf_gain",rx->id);
+    //sprintf(value,"%f",rx->rf_gain);
+    //setProperty(name,value);
     sprintf(name,"receiver.%d.agc",rx->id);
     sprintf(value,"%d",rx->agc);
     setProperty(name,value);
@@ -344,7 +348,7 @@ void receiver_restore_state(RECEIVER *rx) {
   char name[128];
   char *value;
 
-fprintf(stderr,"receiver_restore_state: id=%d\n",rx->id);
+g_print("%s: id=%d\n",__FUNCTION__,rx->id);
 
   sprintf(name,"receiver.%d.audio_channel",rx->id);
   value=getProperty(name);
@@ -385,7 +389,11 @@ fprintf(stderr,"receiver_restore_state: id=%d\n",rx->id);
     // for PS_RX_RECEIVER, *only* restore the ALEX antenna and setting
     // and then return quickly
     //
-    if (rx->id == PS_RX_FEEDBACK) return;
+    if (rx->id == PS_RX_FEEDBACK
+#ifdef SOAPYSDR
+        && protocol!=SOAPYSDR_PROTOCOL
+#endif
+       ) return;
 #endif
 
     sprintf(name,"receiver.%d.sample_rate",rx->id);
@@ -452,9 +460,9 @@ fprintf(stderr,"receiver_restore_state: id=%d\n",rx->id);
     sprintf(name,"receiver.%d.volume",rx->id);
     value=getProperty(name);
     if(value) rx->volume=atof(value);
-    sprintf(name,"receiver.%d.rf_gain",rx->id);
-    value=getProperty(name);
-    if(value) rx->rf_gain=atof(value);
+    //sprintf(name,"receiver.%d.rf_gain",rx->id);
+    //value=getProperty(name);
+    //if(value) rx->rf_gain=atof(value);
     sprintf(name,"receiver.%d.agc",rx->id);
     value=getProperty(name);
     if(value) rx->agc=atoi(value);
@@ -549,12 +557,11 @@ void reconfigure_receiver(RECEIVER *rx,int height) {
 
   if(rx->display_panadapter) {
     if(rx->panadapter==NULL) {
-fprintf(stderr,"reconfigure_receiver: panadapter_init: width:%d height:%d\n",rx->width,myheight);
+g_print("%s: panadapter_init: width:%d height:%d\n",__FUNCTION__,rx->width,myheight);
       rx_panadapter_init(rx, rx->width,myheight);
       gtk_fixed_put(GTK_FIXED(rx->panel),rx->panadapter,0,y);  // y=0 here always
     } else {
        // set the size
-//fprintf(stderr,"reconfigure_receiver: panadapter set_size_request: width:%d height:%d\n",rx->width,myheight);
       gtk_widget_set_size_request(rx->panadapter, rx->width, myheight);
       // move the current one
       gtk_fixed_move(GTK_FIXED(rx->panel),rx->panadapter,0,y);
@@ -570,12 +577,12 @@ fprintf(stderr,"reconfigure_receiver: panadapter_init: width:%d height:%d\n",rx-
 
   if(rx->display_waterfall) {
     if(rx->waterfall==NULL) {
-fprintf(stderr,"reconfigure_receiver: waterfall_init: width:%d height:%d\n",rx->width,myheight);
+g_print("%s: waterfall_init: width:%d height:%d\n",__FUNCTION__,rx->width,myheight);
       waterfall_init(rx,rx->width,myheight);
       gtk_fixed_put(GTK_FIXED(rx->panel),rx->waterfall,0,y);  // y=0 if ONLY waterfall is present
     } else {
       // set the size
-fprintf(stderr,"reconfigure_receiver: waterfall set_size_request: width:%d height:%d\n",rx->width,myheight);
+g_print("%s: waterfall set_size_request: width:%d height:%d\n",__FUNCTION__,rx->width,myheight);
       gtk_widget_set_size_request(rx->waterfall, rx->width, myheight);
       // move the current one
       gtk_fixed_move(GTK_FIXED(rx->panel),rx->waterfall,0,y);
@@ -596,8 +603,6 @@ static gint update_display(gpointer data) {
   RECEIVER *rx=(RECEIVER *)data;
   int rc;
 
-//g_print("update_display: rx=%d displaying=%d\n",rx->id,rx->displaying);
-
   if(rx->displaying) {
     if(rx->pixels>0) {
       g_mutex_lock(&rx->display_mutex);
@@ -716,8 +721,6 @@ void set_agc(RECEIVER *rx, int agc) {
 }
 
 void set_offset(RECEIVER *rx,long long offset) {
-//fprintf(stderr,"set_offset: id=%d ofset=%lld\n",rx->id,offset);
-//fprintf(stderr,"set_offset: frequency=%lld ctun_freqeuncy=%lld offset=%lld\n",vfo[rx->id].frequency,vfo[rx->id].ctun_frequency,vfo[rx->id].offset);
   if(offset==0) {
     SetRXAShiftFreq(rx->id, (double)offset);
     RXANBPSetShiftFrequency(rx->id, (double)offset);
@@ -752,7 +755,7 @@ static void init_analyzer(RECEIVER *rx) {
 
     overlap = (int)fmax(0.0, ceil(fft_size - (double)rx->sample_rate / (double)rx->fps));
 
-    //g_print("SetAnalyzer id=%d buffer_size=%d overlap=%d\n",rx->id,rx->buffer_size,overlap);
+    //g_print("%s: id=%d buffer_size=%d overlap=%d\n",_FUNCTION__,rx->id,rx->buffer_size,overlap);
 
 
     SetAnalyzer(rx->id,
@@ -783,7 +786,7 @@ static void create_visual(RECEIVER *rx) {
   int y=0;
 
   rx->panel=gtk_fixed_new();
-fprintf(stderr,"receiver: create_visual: id=%d width=%d height=%d %p\n",rx->id, rx->width, rx->height, rx->panel);
+g_print("%s: id=%d width=%d height=%d %p\n",__FUNCTION__,rx->id, rx->width, rx->height, rx->panel);
   g_object_weak_ref(G_OBJECT(rx->panel),receiver_weak_notify,(gpointer)rx);
   gtk_widget_set_size_request (rx->panel, rx->width, rx->height);
 
@@ -796,14 +799,14 @@ fprintf(stderr,"receiver: create_visual: id=%d width=%d height=%d %p\n",rx->id,
   }
 
   rx_panadapter_init(rx, rx->width,height);
-fprintf(stderr,"receiver: panadapter_init: height=%d y=%d %p\n",height,y,rx->panadapter);
+g_print("%s: panadapter height=%d y=%d %p\n",__FUNCTION__,height,y,rx->panadapter);
   g_object_weak_ref(G_OBJECT(rx->panadapter),receiver_weak_notify,(gpointer)rx);
   gtk_fixed_put(GTK_FIXED(rx->panel),rx->panadapter,0,y);
   y+=height;
 
   if(rx->display_waterfall) {
     waterfall_init(rx,rx->width,height);
-fprintf(stderr,"receiver: waterfall_init: height=%d y=%d %p\n",height,y,rx->waterfall);
+g_print("%ss: waterfall height=%d y=%d %p\n",__FUNCTION__,height,y,rx->waterfall);
     g_object_weak_ref(G_OBJECT(rx->waterfall),receiver_weak_notify,(gpointer)rx);
     gtk_fixed_put(GTK_FIXED(rx->panel),rx->waterfall,0,y);
   }
@@ -813,7 +816,7 @@ fprintf(stderr,"receiver: waterfall_init: height=%d y=%d %p\n",height,y,rx->wate
 
 #ifdef PURESIGNAL
 RECEIVER *create_pure_signal_receiver(int id, int buffer_size,int sample_rate,int width) {
-fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_size);
+g_print("%s: id=%d buffer_size=%d\n",__FUNCTION__,id,buffer_size);
   RECEIVER *rx=malloc(sizeof(RECEIVER));
   rx->id=id;
 
@@ -868,7 +871,7 @@ fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_s
   rx->panadapter_step=20;
 
   rx->volume=5.0;
-  rx->rf_gain=50.0;
+  //rx->rf_gain=50.0;
 
   rx->squelch_enable=0;
   rx->squelch=0;
@@ -916,7 +919,7 @@ fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_s
   int result;
   XCreateAnalyzer(rx->id, &result, 262144, 1, 1, "");
   if(result != 0) {
-    fprintf(stderr, "XCreateAnalyzer id=%d failed: %d\n", rx->id, result);
+    g_print( "%s: XCreateAnalyzer id=%d failed: %d\n",__FUNCTION__, rx->id, result);
   } else {
     init_analyzer(rx);
   }
@@ -933,7 +936,7 @@ fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_s
 #endif
 
 RECEIVER *create_receiver(int id, int buffer_size, int fft_size, int pixels, int fps, int width, int height) {
-fprintf(stderr,"create_receiver: id=%d buffer_size=%d fft_size=%d pixels=%d fps=%d\n",id,buffer_size, fft_size, pixels, fps);
+g_print("%s: id=%d buffer_size=%d fft_size=%d pixels=%d fps=%d\n",__FUNCTION__,id,buffer_size, fft_size, pixels, fps);
   RECEIVER *rx=malloc(sizeof(RECEIVER));
   rx->id=id;
   g_mutex_init(&rx->mutex);
@@ -970,12 +973,13 @@ fprintf(stderr,"create_receiver: id=%d buffer_size=%d fft_size=%d pixels=%d fps=
           break;
       }
   }
-fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc);
+g_print("%s: id=%d default adc=%d\n",__FUNCTION__,rx->id, rx->adc);
 #ifdef SOAPYSDR
   if(radio->device==SOAPYSDR_USB_DEVICE) {
     rx->sample_rate=radio->info.soapy.sample_rate;
     rx->resampler=NULL;
     rx->resample_buffer=NULL;
+g_print("%s: id=%d sample_rate=%d\n",__FUNCTION__,rx->id, rx->sample_rate);
   } else {
 #endif
     rx->sample_rate=48000;
@@ -1004,7 +1008,7 @@ fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc);
   rx->waterfall_automatic=1;
 
   rx->volume=0.1;
-  rx->rf_gain=50.0;
+  //rx->rf_gain=50.0;
 
   rx->dither=0;
   rx->random=0;
@@ -1068,21 +1072,22 @@ fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc);
   rx->pixel_samples=g_new(float,rx->pixels);
 
 
-fprintf(stderr,"create_receiver (after restore): rx=%p id=%d audio_buffer_size=%d local_audio=%d\n",rx,rx->id,rx->audio_buffer_size,rx->local_audio);
+g_print("%s (after restore): rx=%p id=%d audio_buffer_size=%d local_audio=%d\n",__FUNCTION__,rx,rx->id,rx->audio_buffer_size,rx->local_audio);
   //rx->audio_buffer=g_new(guchar,rx->audio_buffer_size);
   int scale=rx->sample_rate/48000;
   rx->output_samples=rx->buffer_size/scale;
   rx->audio_output_buffer=g_new(gdouble,2*rx->output_samples);
 
-fprintf(stderr,"create_receiver: id=%d output_samples=%d\n",rx->id,rx->output_samples);
+g_print("%s: id=%d output_samples=%d audio_output_buffer=%p\n",__FUNCTION__,rx->id,rx->output_samples,rx->audio_output_buffer);
 
   rx->hz_per_pixel=(double)rx->sample_rate/(double)rx->pixels;
 
   // setup wdsp for this receiver
 
-fprintf(stderr,"create_receiver: id=%d after restore adc=%d\n",rx->id, rx->adc);
+g_print("%s: id=%d after restore adc=%d\n",__FUNCTION__,rx->id, rx->adc);
 
-fprintf(stderr,"create_receiver: OpenChannel id=%d buffer_size=%d fft_size=%d sample_rate=%d\n",
+g_print("%s: OpenChannel id=%d buffer_size=%d fft_size=%d sample_rate=%d\n",
+        __FUNCTION__,
         rx->id,
         rx->buffer_size,
         rx->fft_size,
@@ -1100,9 +1105,7 @@ fprintf(stderr,"create_receiver: OpenChannel id=%d buffer_size=%d fft_size=%d sa
   create_anbEXT(rx->id,1,rx->buffer_size,rx->sample_rate,0.0001,0.0001,0.0001,0.05,20);
   create_nobEXT(rx->id,1,0,rx->buffer_size,rx->sample_rate,0.0001,0.0001,0.0001,0.05,20);
   
-fprintf(stderr,"RXASetNC %d\n",rx->fft_size);
   RXASetNC(rx->id, rx->fft_size);
-fprintf(stderr,"RXASetMP %d\n",rx->low_latency);
   RXASetMP(rx->id, rx->low_latency);
 
   set_agc(rx, rx->agc);
@@ -1141,7 +1144,7 @@ fprintf(stderr,"RXASetMP %d\n",rx->low_latency);
   int result;
   XCreateAnalyzer(rx->id, &result, 262144, 1, 1, "");
   if(result != 0) {
-    fprintf(stderr, "XCreateAnalyzer id=%d failed: %d\n", rx->id, result);
+    g_print( "%s: XCreateAnalyzer id=%d failed: %d\n",__FUNCTION__,rx->id, result);
   } else {
     init_analyzer(rx);
   }
@@ -1153,9 +1156,11 @@ fprintf(stderr,"RXASetMP %d\n",rx->low_latency);
 
   create_visual(rx);
 
-fprintf(stderr,"create_receiver: rx=%p id=%d local_audio=%d\n",rx,rx->id,rx->local_audio);
+g_print("%s: rx=%p id=%d local_audio=%d\n",__FUNCTION__,rx,rx->id,rx->local_audio);
   if(rx->local_audio) {
-    audio_open_output(rx);
+    if(audio_open_output(rx)<0) {
+      rx->local_audio=0;
+    }
   }
 
   return rx;
@@ -1181,7 +1186,7 @@ void receiver_change_sample_rate(RECEIVER *rx,int sample_rate) {
   rx->output_samples=rx->buffer_size/scale;
   rx->hz_per_pixel=(double)rx->sample_rate/(double)rx->width;
 
-g_print("receiver_change_sample_rate: id=%d rate=%d scale=%d buffer_size=%d output_samples=%d\n",rx->id,sample_rate,scale,rx->buffer_size,rx->output_samples);
+g_print("%s: id=%d rate=%d scale=%d buffer_size=%d output_samples=%d\n",__FUNCTION__,rx->id,sample_rate,scale,rx->buffer_size,rx->output_samples);
 #ifdef PURESIGNAL
   if(can_transmit && transmitter->puresignal) {
   if (rx->id == PS_RX_FEEDBACK) {
@@ -1195,8 +1200,8 @@ g_print("receiver_change_sample_rate: id=%d rate=%d scale=%d buffer_size=%d outp
     g_free(rx->pixel_samples);
     rx->pixel_samples=g_new(float,rx->pixels);
     init_analyzer(rx);
-    fprintf(stderr,"PS FEEDBACK change sample rate:id=%d rate=%d buffer_size=%d output_samples=%d\n",
-                   rx->id, rx->sample_rate, rx->buffer_size, rx->output_samples);
+    g_print("%s: PS FEEDBACK: id=%d rate=%d buffer_size=%d output_samples=%d\n",
+                   __FUNCTION__,rx->id, rx->sample_rate, rx->buffer_size, rx->output_samples);
     g_mutex_unlock(&rx->mutex);
     return;
   }
@@ -1223,7 +1228,7 @@ g_print("receiver_change_sample_rate: id=%d rate=%d scale=%d buffer_size=%d outp
 
   g_mutex_unlock(&rx->mutex);
 
-fprintf(stderr,"receiver_change_sample_rate: id=%d rate=%d buffer_size=%d output_samples=%d\n",rx->id, rx->sample_rate, rx->buffer_size, rx->output_samples);
+g_print("%s: id=%d rate=%d buffer_size=%d output_samples=%d\n",__FUNCTION__,rx->id, rx->sample_rate, rx->buffer_size, rx->output_samples);
 }
 
 void receiver_frequency_changed(RECEIVER *rx) {
@@ -1314,6 +1319,9 @@ static void process_rx_buffer(RECEIVER *rx) {
   gdouble left_sample,right_sample;
   short left_audio_sample,right_audio_sample;
   int i;
+
+  //g_print("%s: rx=%p id=%d output_samples=%d audio_output_buffer=%p\n",__FUNCTION__,rx,rx->id,rx->output_samples,rx->audio_output_buffer);
+
   for(i=0;i<rx->output_samples;i++) {
     if(isTransmitting() && (!duplex || mute_rx_while_transmitting)) {
       left_sample=0.0;
@@ -1401,6 +1409,7 @@ static void process_rx_buffer(RECEIVER *rx) {
 void full_rx_buffer(RECEIVER *rx) {
   int error;
 
+  //g_print("%s: rx=%p\n",__FUNCTION__,rx);
   g_mutex_lock(&rx->mutex);
 
   // noise blanker works on original IQ samples
@@ -1413,7 +1422,6 @@ void full_rx_buffer(RECEIVER *rx) {
 
   fexchange0(rx->id, rx->iq_input_buffer, rx->audio_output_buffer, &error);
   if(error!=0) {
-    //fprintf(stderr,"full_rx_buffer: id=%d fexchange0: error=%d\n",rx->id,error);
     rx->fexchange_errors++;
   }
 
@@ -1423,7 +1431,6 @@ void full_rx_buffer(RECEIVER *rx) {
     g_mutex_unlock(&rx->display_mutex);
   }
 
-//g_print("full_rx_buffer: rx=%d buffer_size=%d samples=%d\n",rx->id,rx->buffer_size,rx->samples);
   process_rx_buffer(rx);
   g_mutex_unlock(&rx->mutex);
 }
@@ -1455,7 +1462,6 @@ void add_div_iq_samples(RECEIVER *rx, double i0, double q0, double i1, double q1
 }
 
 void receiver_change_zoom(RECEIVER *rx,double zoom) {
-g_print("receiver_change_zoom: %d %f\n",rx->id,zoom);
   rx->zoom=(int)zoom;
   rx->pixels=rx->width*rx->zoom;
   rx->hz_per_pixel=(double)rx->sample_rate/(double)rx->pixels;
@@ -1482,7 +1488,6 @@ g_print("receiver_change_zoom: %d %f\n",rx->id,zoom);
 #ifdef CLIENT_SERVER
   }
 #endif
-g_print("receiver_change_zoom: pixels=%d zoom=%d pan=%d\n",rx->pixels,rx->zoom,rx->pan);
 }
 
 void receiver_change_pan(RECEIVER *rx,double pan) {
index 236d31d98617c1d6caece5b5a71d5d3684512184..5898a5225b2afb54f89cb2050b30b3a646c06d37 100644 (file)
@@ -44,7 +44,6 @@ typedef struct _receiver {
   gint adc;
 
   gdouble volume;
-  gdouble rf_gain;
 
   gint agc;
   gdouble agc_gain;
@@ -64,7 +63,6 @@ typedef struct _receiver {
   gdouble *iq_input_buffer;
   gdouble *audio_output_buffer;
   gint audio_buffer_size;
-  //guchar *audio_buffer;
   gint audio_index;
   guint32 audio_sequence;
   gfloat *pixel_samples;
index 77cb1e1c019482fe3e9d3a9420994f8a2bd1fc3d..06fae19ecce835852af4b42d78bf24c93d9b7eaf 100755 (executable)
@@ -35,11 +35,7 @@ fi
 cp pihpsdr.desktop ~/.local/share/applications
 echo "removing old versions of shared libraries"
 sudo rm -rf /usr/local/lib/libwdsp.so
-sudo rm -rf /usr/local/lib/libLimeSuite*
-sudo rm -rf /usr/local/lib/libSoapySDR*
-sudo rm -rf /usr/local/lib/SoapySDR
 echo "copying udev rules"
-sudo cp 64-limesuite.rules /etc/udev/rules.d/
 sudo cp 90-ozy.rules /etc/udev/rules.d/
 sudo udevadm control --reload-rules
 sudo udevadm trigger
@@ -47,13 +43,6 @@ echo "installing pihpsdr"
 sudo cp pihpsdr /usr/local/bin
 echo "installing shared libraries"
 sudo cp libwdsp.so /usr/local/lib
-sudo cp libLimeSuite.so.19.04.1 /usr/local/lib
-sudo cp libSoapySDR.so.0.8.0 /usr/local/lib
-sudo cp -R SoapySDR /usr/local/lib
 cd /usr/local/lib
-sudo ln -s libLimeSuite.so.19.04.1 libLimeSuite.so.19.04-1
-sudo ln -s libLimeSuite.so.19.04-1 libLimeSuite.so
-sudo ln -s libSoapySDR.so.0.8.0 libSoapySDR.so.0.8
-sudo ln -s libSoapySDR.so.0.8 libSoapySDR.so
 sudo ldconfig
 
index a020b796df1e72ca20ea9b0d290c3c292e4dfb79..307ec9755e07c21be7b5b18e37d9e0e22f472945 100755 (executable)
Binary files a/release/pihpsdr/libwdsp.so and b/release/pihpsdr/libwdsp.so differ
index cb4b68d05e83458290de78fc179f63c73fc8ae1d..e37141e5b059a997a16acf4367cba4d8be8ba567 100644 (file)
@@ -500,7 +500,8 @@ void rx_panadapter_update(RECEIVER *rx) {
   }
 #ifdef SOAPYSDR
   if(protocol==SOAPYSDR_PROTOCOL) {
-    s1-=rx->rf_gain;
+    //s1-=rx->rf_gain;
+    s1-=adc[rx->id].gain;
   }
 #endif
 
@@ -521,7 +522,8 @@ void rx_panadapter_update(RECEIVER *rx) {
     }
 #ifdef SOAPYSDR
     if(protocol==SOAPYSDR_PROTOCOL) {
-      s2-=rx->rf_gain;
+      //s2-=rx->rf_gain;
+      s2-=adc[rx->id].gain;
     }
 #endif
     s2 = floor((rx->panadapter_high - s2)
index d4f246117745e67829cf97ffa923695223afb179..549ab20afa9485b4c34a1eb8149bb32884d02ae6 100644 (file)
--- a/sliders.c
+++ b/sliders.c
@@ -123,15 +123,8 @@ int sliders_active_receiver_changed(void *data) {
     if (filter_board == CHARLY25) {
       update_att_preamp();
     } else {
-      gtk_range_set_value (GTK_RANGE(attenuation_scale),(double)adc_attenuation[active_receiver->adc]);
+      if(attenuation_scale!=NULL) gtk_range_set_value (GTK_RANGE(attenuation_scale),(double)adc_attenuation[active_receiver->adc]);
     }
-    char title[64];
-    if (have_rx_gain) {
-       sprintf(title,"RX GAIN");
-    } else {
-        sprintf(title,"ATT (dB)");
-    }
-    gtk_label_set_text(GTK_LABEL(attenuation_label),title);
     sliders_update();
   }
   return FALSE;
@@ -144,7 +137,8 @@ int scale_timeout_cb(gpointer data) {
 }
 
 static void attenuation_value_changed_cb(GtkWidget *widget, gpointer data) {
-  adc_attenuation[active_receiver->adc]=(int)gtk_range_get_value(GTK_RANGE(attenuation_scale));
+  adc[active_receiver->adc].gain=gtk_range_get_value(GTK_RANGE(attenuation_scale));
+  adc_attenuation[active_receiver->adc]=(int)adc[active_receiver->adc].gain;
 #ifdef CLIENT_SERVER
   if(radio_is_remote) {
     send_attenuation(client_socket,active_receiver->id,(int)adc_attenuation[active_receiver->adc]);
@@ -157,6 +151,7 @@ static void attenuation_value_changed_cb(GtkWidget *widget, gpointer data) {
 }
 
 void set_attenuation_value(double value) {
+  g_print("%s\n",__FUNCTION__);
   adc_attenuation[active_receiver->adc]=(int)value;
   set_attenuation(adc_attenuation[active_receiver->adc]);
   if(display_sliders) {
@@ -223,9 +218,10 @@ void update_att_preamp(void) {
 }
 
 void att_type_changed(void) {
+  g_print("%s\n",__FUNCTION__);
   if (filter_board == CHARLY25) {
-    gtk_widget_hide(attenuation_label);
-    gtk_widget_hide(attenuation_scale);
+    if(attenuation_label!=NULL) gtk_widget_hide(attenuation_label);
+    if(attenuation_scale!=NULL) gtk_widget_hide(attenuation_scale);
     gtk_widget_show(c25_att_preamp_label);
     gtk_widget_show(c25_att_combobox);
     gtk_widget_show(c25_preamp_combobox);
@@ -234,8 +230,8 @@ void att_type_changed(void) {
     gtk_widget_hide(c25_att_preamp_label);
     gtk_widget_hide(c25_att_combobox);
     gtk_widget_hide(c25_preamp_combobox);
-    gtk_widget_show(attenuation_label);
-    gtk_widget_show(attenuation_scale);
+    if(attenuation_label!=NULL) gtk_widget_show(attenuation_label);
+    if(attenuation_scale!=NULL) gtk_widget_show(attenuation_scale);
   }
 }
 
@@ -291,6 +287,7 @@ static void agcgain_value_changed_cb(GtkWidget *widget, gpointer data) {
 }
 
 void set_agc_gain(int rx,double value) {
+  g_print("%s\n",__FUNCTION__);
   receiver[rx]->agc_gain=value;
   SetRXAAGCTop(receiver[rx]->id, receiver[rx]->agc_gain);
   GetRXAAGCHangLevel(receiver[rx]->id, &receiver[rx]->agc_hang);
@@ -352,6 +349,7 @@ void update_af_gain() {
 }
 
 void set_af_gain(int rx,double value) {
+  g_print("%s\n",__FUNCTION__);
   receiver[rx]->volume=value;
   SetRXAPanelGain1 (receiver[rx]->id, receiver[rx]->volume);
   if(display_sliders) {
@@ -388,27 +386,36 @@ void set_af_gain(int rx,double value) {
 }
 
 static void rf_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
-    active_receiver->rf_gain=gtk_range_get_value(GTK_RANGE(af_gain_scale));
+    adc[active_receiver->adc].gain=gtk_range_get_value(GTK_RANGE(rf_gain_scale));
+    switch(protocol) {
 #ifdef SOAPYSDR
-    if(protocol==SOAPYSDR_PROTOCOL) {
-      soapy_protocol_set_gain(active_receiver);
-    }
+      case SOAPYSDR_PROTOCOL:
+        soapy_protocol_set_gain(active_receiver);
+       break;
 #endif
+      default:
+       //adc_attenuation[active_receiver->adc]=(int)adc[active_receiver->adc].gain;
+        //set_attenuation(adc_attenuation[active_receiver->adc]);
+       break;
+    }
 }
 
 void update_rf_gain() {
-  set_rf_gain(active_receiver->id,active_receiver->rf_gain);
+  //set_rf_gain(active_receiver->id,active_receiver->rf_gain);
+  set_rf_gain(active_receiver->id,adc[active_receiver->id].gain);
 }
 
 void set_rf_gain(int rx,double value) {
-  receiver[rx]->rf_gain=value;
+  g_print("%s\n",__FUNCTION__);
+  adc[receiver[rx]->id].gain=value;
 #ifdef SOAPYSDR
   if(protocol==SOAPYSDR_PROTOCOL) {
-    soapy_protocol_set_gain(active_receiver);
+    soapy_protocol_set_gain(receiver[rx]);
   }
 #endif
   if(display_sliders) {
-    gtk_range_set_value (GTK_RANGE(attenuation_scale),receiver[rx]->rf_gain);
+    //gtk_range_set_value (GTK_RANGE(attenuation_scale),receiver[rx]->rf_gain);
+    gtk_range_set_value (GTK_RANGE(rf_gain_scale),adc[receiver[rx]->id].gain);
   } else {
     if(scale_status!=RF_GAIN || scale_rx!=rx) {
       if(scale_status!=NO_FUNCTION) {
@@ -426,7 +433,8 @@ void set_rf_gain(int rx,double value) {
       GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
       rf_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
       gtk_widget_set_size_request (rf_gain_scale, 400, 30);
-      gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+      //gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+      gtk_range_set_value (GTK_RANGE(rf_gain_scale),adc[receiver[rx]->id].gain);
       gtk_widget_show(rf_gain_scale);
       gtk_container_add(GTK_CONTAINER(content),rf_gain_scale);
       scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
@@ -434,13 +442,15 @@ void set_rf_gain(int rx,double value) {
       gtk_dialog_run(GTK_DIALOG(scale_dialog));
     } else {
       g_source_remove(scale_timer);
-      gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+      //gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+      gtk_range_set_value (GTK_RANGE(rf_gain_scale),adc[receiver[rx]->id].gain);
       scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
     }
   }
 }
 
 void set_filter_width(int rx,int width) {
+  g_print("%s\n",__FUNCTION__);
     if(scale_status!=FILTER_WIDTH || scale_rx!=rx) {
       if(scale_status!=NO_FUNCTION) {
         g_source_remove(scale_timer);
@@ -471,6 +481,7 @@ void set_filter_width(int rx,int width) {
 }
 
 void set_filter_shift(int rx,int shift) {
+  g_print("%s\n",__FUNCTION__);
     if(scale_status!=FILTER_SHIFT || scale_rx!=rx) {
       if(scale_status!=NO_FUNCTION) {
         g_source_remove(scale_timer);
@@ -510,6 +521,7 @@ static void micgain_value_changed_cb(GtkWidget *widget, gpointer data) {
 }
 
 void set_mic_gain(double value) {
+  g_print("%s\n",__FUNCTION__);
   if(can_transmit) {
     mic_gain=value;
     SetTXAPanelGain1(transmitter->id,pow(10.0, mic_gain/20.0));
@@ -545,6 +557,7 @@ void set_mic_gain(double value) {
 }
 
 void set_linein_gain(int value) {
+  g_print("%s\n",__FUNCTION__);
   linein_gain=value;
   if(display_sliders) {
     gtk_range_set_value (GTK_RANGE(mic_gain_scale),linein_gain);
@@ -583,6 +596,7 @@ int update_linein_gain(void *data) {
 }
 
 void set_drive(double value) {
+  g_print("%s\n",__FUNCTION__);
   setDrive(value);
   if(display_sliders) {
     gtk_range_set_value (GTK_RANGE(drive_scale),value);
@@ -665,6 +679,7 @@ static void compressor_enable_cb(GtkWidget *widget, gpointer data) {
 }
 
 void set_squelch() {
+  g_print("%s\n",__FUNCTION__);
   setSquelch(active_receiver);
 #ifndef COMPRESSION_SLIDER_INSTEAD_OF_SQUELCH
   if(display_sliders) {
@@ -703,6 +718,7 @@ void set_squelch() {
 }
 
 void set_compression(TRANSMITTER* tx) {
+  g_print("%s\n",__FUNCTION__);
   // Update VFO panel to reflect changed value
   g_idle_add(ext_vfo_update, NULL);
 #ifdef COMPRESSION_SLIDER_INSTEAD_OF_SQUELCH
@@ -740,6 +756,7 @@ void set_compression(TRANSMITTER* tx) {
 }
 
 void show_diversity_gain() {
+  g_print("%s\n",__FUNCTION__);
     if(scale_status!=DIVERSITY_GAIN) {
       if(scale_status!=NO_FUNCTION) {
         g_source_remove(scale_timer);
@@ -767,6 +784,7 @@ void show_diversity_gain() {
 }
 
 void show_diversity_phase() {
+  g_print("%s\n",__FUNCTION__);
     if(scale_status!=DIVERSITY_PHASE) {
       if(scale_status!=NO_FUNCTION) {
         g_source_remove(scale_timer);
@@ -831,31 +849,37 @@ fprintf(stderr,"sliders_init: width=%d height=%d\n", width,height);
   gtk_grid_attach(GTK_GRID(sliders),agc_scale,4,0,2,1);
   g_signal_connect(G_OBJECT(agc_scale),"value_changed",G_CALLBACK(agcgain_value_changed_cb),NULL);
 
-  char title[64];
-  if (have_rx_gain) {
-       sprintf(title,"RX-GAIN:");
-  } else {
-        sprintf(title,"ATT (dB):");
-  }
-  attenuation_label=gtk_label_new(title);
-  gtk_widget_override_font(attenuation_label, pango_font_description_from_string("Sans 10"));
-  gtk_widget_show(attenuation_label);
-  gtk_grid_attach(GTK_GRID(sliders),attenuation_label,6,0,1,1);
-
-  if (have_rx_gain) {
-       attenuation_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,-12.0, 48.0, 1.0);
-       gtk_range_set_value (GTK_RANGE(attenuation_scale),adc_attenuation[active_receiver->adc]);
+
+  if(have_rx_gain) {
+    rf_gain_label=gtk_label_new("RX-GAIN:");
+    gtk_widget_override_font(rf_gain_label, pango_font_description_from_string("Sans 10"));
+    gtk_widget_show(rf_gain_label);
+    gtk_grid_attach(GTK_GRID(sliders),rf_gain_label,6,0,1,1);
+    if(protocol==SOAPYSDR_PROTOCOL) {
+      rf_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,adc[0].min_gain, adc[0].max_gain, 1.0);
+      gtk_range_set_value (GTK_RANGE(rf_gain_scale),adc[0].gain);
+    } else {
+      rf_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,-12.0, 48.0, 1.0);
+      gtk_range_set_value (GTK_RANGE(rf_gain_scale),adc_attenuation[active_receiver->adc]);
+    }
+    gtk_widget_override_font(rf_gain_scale, pango_font_description_from_string("Sans 10"));
+    gtk_range_set_increments (GTK_RANGE(rf_gain_scale),1.0,1.0);
+    gtk_widget_show(rf_gain_scale);
+    gtk_grid_attach(GTK_GRID(sliders),rf_gain_scale,7,0,2,1);
+    g_signal_connect(G_OBJECT(rf_gain_scale),"value_changed",G_CALLBACK(rf_gain_value_changed_cb),NULL);
   } else {
-       attenuation_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 31.0, 1.0);
-       gtk_range_set_value (GTK_RANGE(attenuation_scale),adc_attenuation[active_receiver->adc]);
+    attenuation_label=gtk_label_new("ATT (dB):");
+    gtk_widget_override_font(attenuation_label, pango_font_description_from_string("Sans 10"));
+    gtk_widget_show(attenuation_label);
+    gtk_grid_attach(GTK_GRID(sliders),attenuation_label,6,0,1,1);
+    attenuation_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 31.0, 1.0);
+    gtk_widget_override_font(attenuation_scale, pango_font_description_from_string("Sans 10"));
+    gtk_range_set_value (GTK_RANGE(attenuation_scale),adc_attenuation[active_receiver->adc]);
+    gtk_range_set_increments (GTK_RANGE(attenuation_scale),1.0,1.0);
+    gtk_widget_show(attenuation_scale);
+    gtk_grid_attach(GTK_GRID(sliders),attenuation_scale,7,0,2,1);
+    g_signal_connect(G_OBJECT(attenuation_scale),"value_changed",G_CALLBACK(attenuation_value_changed_cb),NULL);
   }
-  gtk_range_set_increments (GTK_RANGE(attenuation_scale),1.0,1.0);
-  gtk_widget_override_font(attenuation_scale, pango_font_description_from_string("Sans 10"));
-  
-  gtk_widget_show(attenuation_scale);
-  gtk_grid_attach(GTK_GRID(sliders),attenuation_scale,7,0,2,1);
-  g_signal_connect(G_OBJECT(attenuation_scale),"value_changed",G_CALLBACK(attenuation_value_changed_cb),NULL);
 
   c25_att_preamp_label = gtk_label_new("Att/PreAmp");
   gtk_widget_override_font(c25_att_preamp_label, pango_font_description_from_string("Sans 10"));
index ba308dc7e8cd52f6394933cd51410b061963255b..1c111ef2c627eb6214d6cda46aa16650b8bd8aa9 100644 (file)
@@ -164,15 +164,6 @@ void soapy_protocol_create_receiver(RECEIVER *rx) {
   if(max_samples>(2*rx->fft_size)) {
     max_samples=2*rx->fft_size;
   }
-  /*
-  if(max_samples>=4096) {
-    max_samples=4096;
-  } else if(max_samples>=2048) {
-    max_samples=2048;
-  } else {
-    max_samples=1024;
-  }
-  */
   rx->buffer=g_new(double,max_samples*2);
 
   if(rx->sample_rate==radio_sample_rate) {
@@ -398,10 +389,12 @@ fprintf(stderr,"soapy_protocol: receive_thread\n");
 
 fprintf(stderr,"soapy_protocol: receive_thread: SoapySDRDevice_deactivateStream\n");
   SoapySDRDevice_deactivateStream(soapy_device,rx_stream[channel],0,0LL);
+  /*
 fprintf(stderr,"soapy_protocol: receive_thread: SoapySDRDevice_closeStream\n");
   SoapySDRDevice_closeStream(soapy_device,rx_stream[channel]);
 fprintf(stderr,"soapy_protocol: receive_thread: SoapySDRDevice_unmake\n");
   SoapySDRDevice_unmake(soapy_device);
+  */
   return NULL;
 }
 
@@ -507,10 +500,10 @@ void soapy_protocol_set_gain(RECEIVER *rx) {
 
 void soapy_protocol_set_gain_element(RECEIVER *rx,char *name,int gain) {
   int rc;
-//fprintf(stderr,"soapy_protocol_set_gain: adc=%d %s=%d\n",rx->adc,name,gain);
+g_print("%s: adc=%d %s=%d\n",__FUNCTION__,rx->adc,name,gain);
   rc=SoapySDRDevice_setGainElement(soapy_device,SOAPY_SDR_RX,rx->adc,name,(double)gain);
   if(rc!=0) {
-    fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGainElement %s failed: %s\n",name,SoapySDR_errToStr(rc));
+    g_print("%s: SoapySDRDevice_setGainElement %s failed: %s\n",__FUNCTION__,name,SoapySDR_errToStr(rc));
   }
 }
 
index c72100bfc84edf3b52feceab6c66ef22acb7baec..e03908c24b8a5b3456721670a6c26addb6b724b9 100644 (file)
@@ -126,6 +126,7 @@ void switch_menu(GtkWidget *parent) {
   gchar label[64];
   GtkWidget *notebook;
   GtkWidget *grid;
+  GtkWidget *widget;
   gint function=0;
 
 
@@ -172,40 +173,98 @@ next_function_set:
       break;
   }
 
-  GtkWidget *widget=gtk_label_new(NULL);
-  gtk_label_set_markup(GTK_LABEL(widget),"<b>Switch</b>");
-  gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
-  col++;
+  int original_row=row;
 
-  widget=gtk_label_new(NULL);
-  gtk_label_set_markup(GTK_LABEL(widget),"<b>Action</b>");
-  gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
-
-  row++;
-  col=0;
-
-  for(int i=0;i<max_switches;i++) {
-    widget=gtk_label_new(NULL);
-    g_sprintf(label,"<b>%d</b>",i);
-    gtk_label_set_markup (GTK_LABEL(widget), label);
+  if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
+    row=row+5;
+    col=0;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[0].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(0));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
-
-    if((controller==NO_CONTROLLER || controller==CONTROLLER1) && (temp_switches[i].switch_function==FUNCTION)) {
-      widget=gtk_label_new(NULL);
-      g_sprintf(label,"<b>%s</b>",sw_string[temp_switches[i].switch_function]);
-      gtk_label_set_markup (GTK_LABEL(widget), label);
-    } else {
-      widget=gtk_button_new_with_label(sw_string[temp_switches[i].switch_function]);
-      g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(i));
-    }
+    widget=gtk_button_new_with_label(sw_string[temp_switches[1].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(1));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[2].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(2));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[3].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(3));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[4].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(4));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[5].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(5));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[6].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(6));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
 
+    row=original_row;
+    col=8;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[7].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(7));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     row++;
-    col=0;
-  }
+    col=7;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[8].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(8));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[9].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(9));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    row++;
+    col=7;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[10].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(10));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[11].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(11));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    row++;
+    col=7;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[12].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(12));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[13].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(13));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    row++;
+    col=7;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[14].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(14));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
+    widget=gtk_button_new_with_label(sw_string[temp_switches[15].switch_function]);
+    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(15));
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+
+    gtk_container_add(GTK_CONTAINER(content),grid);
+  } else {
+    int start_row=row;
+    for(int i=0;i<max_switches;i++) {
+      if((controller==NO_CONTROLLER || controller==CONTROLLER1) && (temp_switches[i].switch_function==FUNCTION)) {
+        widget=gtk_label_new(NULL);
+        g_sprintf(label,"<b>%s</b>",sw_string[temp_switches[i].switch_function]);
+        gtk_label_set_markup (GTK_LABEL(widget), label);
+      } else {
+        widget=gtk_button_new_with_label(sw_string[temp_switches[i].switch_function]);
+        g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(i));
+      }
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      col++;
+    }
 
-  if(controller==NO_CONTROLLER || controller==CONTROLLER1) {
     g_sprintf(label,"Function %d",function);
     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid,gtk_label_new(label));
     function++;
@@ -214,8 +273,6 @@ next_function_set:
     }
     gtk_container_add(GTK_CONTAINER(content),notebook);
     g_signal_connect (notebook, "switch-page",G_CALLBACK(switch_page_cb),NULL);
-  } else {
-    gtk_container_add(GTK_CONTAINER(content),grid);
   }
 
   sub_menu=dialog;
index 2bf600e4e2b68179b935d815f13c00a7d8ca40e9..7cdd157610b586b25e275bdbd1d591e54fe83bf3 100644 (file)
--- a/toolbar.c
+++ b/toolbar.c
@@ -82,6 +82,8 @@ static gint rit_minus_timer=-1;
 static gint xit_plus_timer=-1;
 static gint xit_minus_timer=-1;
 
+SWITCH *toolbar_switches=switches_controller1[0];
+
 static gboolean rit_timer_cb(gpointer data) {
   int i=GPOINTER_TO_INT(data);
   vfo_rit(active_receiver->id,i);
@@ -101,14 +103,14 @@ static gboolean xit_timer_cb(gpointer data) {
 }
 
 void update_toolbar_labels() {
-  gtk_button_set_label(GTK_BUTTON(sim_mox),sw_cap_string[switches[0].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_s1),sw_cap_string[switches[1].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_s2),sw_cap_string[switches[2].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_s3),sw_cap_string[switches[3].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_s4),sw_cap_string[switches[4].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_s5),sw_cap_string[switches[5].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_s6),sw_cap_string[switches[6].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_function),sw_cap_string[switches[7].switch_function]);
+  gtk_button_set_label(GTK_BUTTON(sim_mox),sw_cap_string[toolbar_switches[0].switch_function]);
+  gtk_button_set_label(GTK_BUTTON(sim_s1),sw_cap_string[toolbar_switches[1].switch_function]);
+  gtk_button_set_label(GTK_BUTTON(sim_s2),sw_cap_string[toolbar_switches[2].switch_function]);
+  gtk_button_set_label(GTK_BUTTON(sim_s3),sw_cap_string[toolbar_switches[3].switch_function]);
+  gtk_button_set_label(GTK_BUTTON(sim_s4),sw_cap_string[toolbar_switches[4].switch_function]);
+  gtk_button_set_label(GTK_BUTTON(sim_s5),sw_cap_string[toolbar_switches[5].switch_function]);
+  gtk_button_set_label(GTK_BUTTON(sim_s6),sw_cap_string[toolbar_switches[6].switch_function]);
+  gtk_button_set_label(GTK_BUTTON(sim_function),sw_cap_string[toolbar_switches[7].switch_function]);
 }
 
 static void close_cb(GtkWidget *widget, gpointer data) {
@@ -501,7 +503,7 @@ void tune_update(int state) {
 void switch_pressed_cb(GtkWidget *widget, gpointer data) {
   gint i=GPOINTER_TO_INT(data);
   SWITCH_ACTION *a=g_new(SWITCH_ACTION,1);
-  a->action=switches[i].switch_function;
+  a->action=toolbar_switches[i].switch_function;
   a->state=PRESSED;
   g_idle_add(switch_action,a);
 }
@@ -509,7 +511,7 @@ void switch_pressed_cb(GtkWidget *widget, gpointer data) {
 void switch_released_cb(GtkWidget *widget, gpointer data) {
   gint i=GPOINTER_TO_INT(data);
   SWITCH_ACTION *a=g_new(SWITCH_ACTION,1);
-  a->action=switches[i].switch_function;
+  a->action=toolbar_switches[i].switch_function;
   a->state=RELEASED;
   g_idle_add(switch_action,a);
 }
@@ -537,43 +539,43 @@ GtkWidget *toolbar_init(int my_width, int my_height, GtkWidget* parent) {
     gtk_widget_set_size_request (toolbar, width, height);
     gtk_grid_set_column_homogeneous(GTK_GRID(toolbar),TRUE);
 
-    sim_mox=gtk_button_new_with_label(sw_cap_string[switches[0].switch_function]);
+    sim_mox=gtk_button_new_with_label(sw_cap_string[toolbar_switches[0].switch_function]);
     g_signal_connect(G_OBJECT(sim_mox),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(0));
     gtk_grid_attach(GTK_GRID(toolbar),sim_mox,0,0,4,1);
 
-    sim_s1=gtk_button_new_with_label(sw_cap_string[switches[1].switch_function]);
+    sim_s1=gtk_button_new_with_label(sw_cap_string[toolbar_switches[1].switch_function]);
     gtk_widget_set_size_request (sim_s1, button_width, 0);
     g_signal_connect(G_OBJECT(sim_s1),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(1));
     g_signal_connect(G_OBJECT(sim_s1),"released",G_CALLBACK(switch_released_cb),GINT_TO_POINTER(1));
     gtk_grid_attach(GTK_GRID(toolbar),sim_s1,4,0,4,1);
 
-    sim_s2=gtk_button_new_with_label(sw_cap_string[switches[2].switch_function]);
+    sim_s2=gtk_button_new_with_label(sw_cap_string[toolbar_switches[2].switch_function]);
     gtk_widget_set_size_request (sim_s2, button_width, 0);
     g_signal_connect(G_OBJECT(sim_s2),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(2));
     g_signal_connect(G_OBJECT(sim_s2),"released",G_CALLBACK(switch_released_cb),GINT_TO_POINTER(2));
     gtk_grid_attach(GTK_GRID(toolbar),sim_s2,8,0,4,1);
 
-    sim_s3=gtk_button_new_with_label(sw_cap_string[switches[3].switch_function]);
+    sim_s3=gtk_button_new_with_label(sw_cap_string[toolbar_switches[3].switch_function]);
     g_signal_connect(G_OBJECT(sim_s3),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(3));
     g_signal_connect(G_OBJECT(sim_s3),"released",G_CALLBACK(switch_released_cb),GINT_TO_POINTER(3));
     gtk_grid_attach(GTK_GRID(toolbar),sim_s3,12,0,4,1);
 
-    sim_s4=gtk_button_new_with_label(sw_cap_string[switches[4].switch_function]);
+    sim_s4=gtk_button_new_with_label(sw_cap_string[toolbar_switches[4].switch_function]);
     g_signal_connect(G_OBJECT(sim_s4),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(4));
     g_signal_connect(G_OBJECT(sim_s4),"released",G_CALLBACK(switch_released_cb),GINT_TO_POINTER(4));
     gtk_grid_attach(GTK_GRID(toolbar),sim_s4,16,0,4,1);
 
-    sim_s5=gtk_button_new_with_label(sw_cap_string[switches[5].switch_function]);
+    sim_s5=gtk_button_new_with_label(sw_cap_string[toolbar_switches[5].switch_function]);
     g_signal_connect(G_OBJECT(sim_s5),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(5));
     g_signal_connect(G_OBJECT(sim_s5),"released",G_CALLBACK(switch_released_cb),GINT_TO_POINTER(5));
     gtk_grid_attach(GTK_GRID(toolbar),sim_s5,20,0,4,1);
 
-    sim_s6=gtk_button_new_with_label(sw_cap_string[switches[6].switch_function]);
+    sim_s6=gtk_button_new_with_label(sw_cap_string[toolbar_switches[6].switch_function]);
     g_signal_connect(G_OBJECT(sim_s6),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(6));
     g_signal_connect(G_OBJECT(sim_s6),"released",G_CALLBACK(switch_released_cb),GINT_TO_POINTER(6));
     gtk_grid_attach(GTK_GRID(toolbar),sim_s6,24,0,4,1);
 
-    sim_function=gtk_button_new_with_label(sw_cap_string[switches[7].switch_function]);
+    sim_function=gtk_button_new_with_label(sw_cap_string[toolbar_switches[7].switch_function]);
     g_signal_connect(G_OBJECT(sim_function),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(7));
     gtk_grid_attach(GTK_GRID(toolbar),sim_function,28,0,4,1);
 
index 5a1b8879783cb419a0b82ae981cf0e84af8281f6..ea9063a5b696cfac184b78060f8c7388ec774c03 100644 (file)
--- a/toolbar.h
+++ b/toolbar.h
 #ifndef _TOOLBAR_H
 #define _TOOLBAR_H
 
+#include "gpio.h"
 #define MAX_FUNCTION 5
 
 extern int function;
 
+extern SWITCH *toolbar_switches;
 
 void update_toolbar_labels();
 void ptt_update(int state);