From: John Melton g0orx/n6lyt Date: Wed, 6 Apr 2016 07:10:52 +0000 (+0000) Subject: changes for updated wdsp and some cleanup X-Git-Url: https://git.rkrishnan.org/%5B/frontends/(%5B%5E?a=commitdiff_plain;h=34eaf8a427efb53e0edcd01fbb976ea01d7b6108;p=pihpsdr.git changes for updated wdsp and some cleanup --- diff --git a/Makefile b/Makefile index c5bae3b..7b468b0 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,14 @@ UNAME_N := $(shell uname -n) CC=gcc LINK=gcc -OPTIONS=-g -D $(UNAME_N) +OPTIONS=-g -D $(UNAME_N) -O3 GTKINCLUDES=`pkg-config --cflags gtk+-3.0` GTKLIBS=`pkg-config --libs gtk+-3.0` +ifeq ($(UNAME_N),raspberrypi) LIBS=-lwiringPi -lpigpio -lrt -lm -lwdsp -lpthread $(GTKLIBS) +else +LIBS=-lwiringPi -lrt -lm -lwdsp -lpthread $(GTKLIBS) +endif INCLUDES=$(GTKINCLUDES) COMPILE=$(CC) $(OPTIONS) $(INCLUDES) @@ -15,72 +19,97 @@ PROGRAM=pihpsdr SOURCES= \ band.c \ +frequency.c \ +discovered.c \ filter.c \ main.c \ +menu.c \ meter.c \ mode.c \ +old_discovery.c \ new_discovery.c \ +old_protocol.c \ new_protocol.c \ new_protocol_programmer.c \ panadapter.c \ property.c \ radio.c \ -rotary_encoder.c \ +gpio.c \ splash.c \ toolbar.c \ +version.c \ vfo.c \ -waterfall.c +waterfall.c \ +wdsp_init.c HEADERS= \ agc.h \ alex.h \ band.h \ +frequency.h \ bandstack.h \ channel.h \ discovered.h \ filter.h \ +menu.h \ meter.h \ mode.h \ +old_discovery.h \ new_discovery.h \ +old_protocol.h \ new_protocol.h \ panadapter.h \ property.h \ radio.h \ -rotary_encoder.h \ +gpio.h \ splash.h \ toolbar.h \ +version.h \ vfo.h \ waterfall.h \ +wdsp_init.h \ xvtr.h OBJS= \ band.o \ +frequency.o \ +discovered.o \ filter.o \ +version.o \ main.o \ +menu.o \ meter.o \ mode.o \ +old_discovery.o \ new_discovery.o \ +old_protocol.o \ new_protocol.o \ new_protocol_programmer.o \ panadapter.o \ property.o \ radio.o \ -rotary_encoder.o \ +gpio.o \ splash.o \ toolbar.o \ vfo.o \ -waterfall.o +waterfall.o \ +wdsp_init.o -all: $(PROGRAM) $(HEADERS) $(SOURCES) +all: prebuild $(PROGRAM) $(HEADERS) $(SOURCES) + +prebuild: + rm -f version.o $(PROGRAM): $(OBJS) $(LINK) -o $(PROGRAM) $(OBJS) $(LIBS) .c.o: - $(COMPILE) $(OPTIONS) -c -o $@ $< + $(COMPILE) -c -o $@ $< clean: -rm -f *.o -rm -f $(PROGRAM) +install: + cp pihpsdr ../pihpsdr diff --git a/agc.h b/agc.h index c6e3aff..c64de97 100644 --- a/agc.h +++ b/agc.h @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #define AGC_OFF 0 #define AGC_LONG 1 #define AGC_SLOW 2 diff --git a/alex.h b/alex.h index 7ead806..a9178cb 100644 --- a/alex.h +++ b/alex.h @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #define ALEX_RX_ANTENNA_NONE 0x00000000 #define ALEX_RX_ANTENNA_XVTR 0x00000900 #define ALEX_RX_ANTENNA_EXT1 0x00000A00 diff --git a/band.c b/band.c index 53ec328..d023d04 100644 --- a/band.c +++ b/band.c @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include #include "bandstack.h" @@ -100,19 +119,19 @@ BANDSTACK bandstackGEN={3,1,bandstack_entriesGEN}; BANDSTACK bandstackWWV={5,1,bandstack_entriesWWV}; BAND bands[BANDS] = - {{"160",&bandstack160,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}, - {"80",&bandstack80,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}, - {"60",&bandstack60,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}, - {"40",&bandstack40,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}, - {"30",&bandstack30,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}, - {"20",&bandstack20,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}, - {"18",&bandstack18,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}, - {"15",&bandstack15,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}, - {"12",&bandstack12,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}, - {"10",&bandstack10,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}, - {"50",&bandstack50,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}, - {"GEN",&bandstackGEN,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}, - {"WWV",&bandstackWWV,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB}}; + {{"160",&bandstack160,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30}, + {"80",&bandstack80,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30}, + {"60",&bandstack60,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30}, + {"40",&bandstack40,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30}, + {"30",&bandstack30,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30}, + {"20",&bandstack20,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30}, + {"18",&bandstack18,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30}, + {"15",&bandstack15,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30}, + {"12",&bandstack12,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30}, + {"10",&bandstack10,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30}, + {"50",&bandstack50,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30}, + {"GEN",&bandstackGEN,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,0}, + {"WWV",&bandstackWWV,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,0}}; #define NUM_BAND_LIMITS 22 @@ -170,13 +189,24 @@ BANDSTACK_ENTRY *bandstack_entry_get_current() { BANDSTACK_ENTRY *bandstack_entry_next() { BANDSTACK *bandstack=bands[band].bandstack; bandstack->current_entry++; - if(bandstack->current_entry==bandstack->entries) { + if(bandstack->current_entry>=bandstack->entries) { bandstack->current_entry=0; } BANDSTACK_ENTRY *entry=&bandstack->entry[bandstack->current_entry]; return entry; } +BANDSTACK_ENTRY *bandstack_entry_previous() { + BANDSTACK *bandstack=bands[band].bandstack; + bandstack->current_entry--; + if(bandstack->current_entry<0) { + bandstack->current_entry=bandstack->entries-1; + } + BANDSTACK_ENTRY *entry=&bandstack->entry[bandstack->current_entry]; + return entry; +} + + int band_get_current() { return band; } @@ -230,6 +260,10 @@ void bandSaveState() { sprintf(name,"band.%d.alexAttenuation",b); setProperty(name,value); + sprintf(value,"%d",bands[b].pa_calibration); + sprintf(name,"band.%d.pa_calibration",b); + setProperty(name,value); + for(stack=0;stackentries;stack++) { entry=bands[b].bandstack->entry; entry+=stack; @@ -303,6 +337,11 @@ void bandRestoreState() { sprintf(name,"band.%d.alexAttenuation",b); value=getProperty(name); if(value) bands[b].alexAttenuation=atoi(value); + + sprintf(name,"band.%d.pa_calibration",b); + value=getProperty(name); + if(value) bands[b].pa_calibration=atoi(value); + for(stack=0;stackentries;stack++) { entry=bands[b].bandstack->entry; entry+=stack; @@ -341,4 +380,18 @@ void bandRestoreState() { if(value) band=atoi(value); } +BAND_LIMITS* getBandLimits(long long minDisplay,long long maxDisplay) { + BAND_LIMITS* limits; + int i; + + for(i=0;iminFrequency&&maxDisplay>=limits->minFrequency) || + (minDisplay<=limits->maxFrequency&&maxDisplay>=limits->maxFrequency)) { + return limits; + } + } + + return NULL; +} diff --git a/band.h b/band.h index 24d15c1..add9288 100644 --- a/band.h +++ b/band.h @@ -1,14 +1,6 @@ -/** -* @file band.h -* @brief Header files for the Amateur Radio band stack. -* @author John Melton, G0ORX/N6LYT, Doxygen Comments Dave Larsen, KV0S -* @version 0.1 -* @date 2009-04-11 -*/ -// band.h - /* Copyright (C) -* 2009 - John Melton, G0ORX/N6LYT, Doxygen Comments Dave Larsen, KV0S +* 2015 - John Melton, G0ORX/N6LYT +* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 @@ -43,6 +35,7 @@ #define bandWWV 12 #define BANDS 13 +#define HAM_BANDS 11 /* --------------------------------------------------------------------------*/ /** @@ -68,6 +61,7 @@ struct _BAND { unsigned long alexRxAntenna; unsigned long alexTxAntenna; unsigned long alexAttenuation; + int pa_calibration; }; typedef struct _BAND BAND; @@ -82,19 +76,12 @@ BAND *band_get_band(int b); BAND *band_set_current(int b); BANDSTACK_ENTRY *bandstack_entry_next(); +BANDSTACK_ENTRY *bandstack_entry_previous(); BANDSTACK_ENTRY *bandstack_entry_get_current(); -/* -void bandSaveState(); -void bandRestoreState(); -void forceBand(int band,int setup); -void configureXVTRButton(int setup); -GtkWidget* buildBandUI(); - -int remoteSetBand(gpointer *data); - BAND_LIMITS* getBandLimits(long long minDisplay,long long maxDisplay); -XVTR_ENTRY* getXvtrEntry(int i); +/* +XVTR_ENTRY* getXvtrEntry(int i); */ diff --git a/bandstack.h b/bandstack.h index 2fb8e9a..c40a09e 100644 --- a/bandstack.h +++ b/bandstack.h @@ -1,14 +1,7 @@ -/** -* @file bandstack.h -* @brief Bandstack definition files -* @author John Melton, G0ORX/N6LYT, Doxygen Comments Dave Larsen, KV0S -* @version 0.1 -* @date 2009-04-11 -*/ -// bandstack.h - /* Copyright (C) -* This program is free software; you can redistribute it and/or2009 - John Melton, G0ORX/N6LYT, Doxygen Comments Dave Larsen, KV0S +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. diff --git a/channel.h b/channel.h index ae1e178..877f7a0 100644 --- a/channel.h +++ b/channel.h @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #define CHANNEL_RX0 0 #define CHANNEL_RX1 1 #define CHANNEL_RX2 2 diff --git a/discovered.c b/discovered.c new file mode 100644 index 0000000..513f255 --- /dev/null +++ b/discovered.c @@ -0,0 +1,25 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#include "discovered.h" + +int selected_device=0; +int devices=0; +DISCOVERED discovered[MAX_DEVICES]; + diff --git a/discovered.h b/discovered.h index e644e69..6eea262 100644 --- a/discovered.h +++ b/discovered.h @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include #define MAX_DEVICES 16 diff --git a/filter.c b/filter.c index e6b0fe5..c6a4ff8 100644 --- a/filter.c +++ b/filter.c @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include "filter.h" FILTER filterLSB[FILTERS]={ diff --git a/filter.h b/filter.h index ad72c9f..c6e0503 100644 --- a/filter.h +++ b/filter.h @@ -1,13 +1,6 @@ -/** -* @file filter.h -* @brief Header files to define the filters. -* @author John Melton, G0ORX/N6LYT, Doxygen Comments Dave Larsen, KV0S -* @version 0.1 -* @date 2009-04-11 -*/ -// filter.h /* Copyright (C) -* 2009 - John Melton, G0ORX/N6LYT, Doxygen Comments Dave Larsen, KV0S +* 2015 - John Melton, G0ORX/N6LYT +* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 diff --git a/gpio.c b/gpio.c new file mode 100644 index 0000000..ccc35ba --- /dev/null +++ b/gpio.c @@ -0,0 +1,1147 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef raspberrypi +#include +#endif + +#include "band.h" +#include "channel.h" +#include "mode.h" +#include "filter.h" +#include "bandstack.h" +#include "toolbar.h" +#include "gpio.h" +#include "radio.h" +#include "toolbar.h" +#include "main.h" +#include "property.h" + +#define SYSFS_GPIO_DIR "/sys/class/gpio" + +int ENABLE_VFO_ENCODER=1; +int ENABLE_VFO_PULLUP=1; +#ifdef raspberrypi +int VFO_ENCODER_A=17; +int VFO_ENCODER_B=18; +#endif +#ifdef odroid +int VFO_ENCODER_A=88; +int VFO_ENCODER_B=87; +int VFO_ENCODER_A_PIN=0; +int VFO_ENCODER_B_PIN=1; +#endif +int ENABLE_AF_ENCODER=88; +int ENABLE_AF_PULLUP=87; +int AF_ENCODER_A=20; +int AF_ENCODER_B=26; +int AF_FUNCTION=25; +int ENABLE_RF_ENCODER=1; +int ENABLE_RF_PULLUP=0; +int RF_ENCODER_A=16; +int RF_ENCODER_B=19; +int RF_FUNCTION=8; +int ENABLE_AGC_ENCODER=1; +int ENABLE_AGC_PULLUP=0; +int AGC_ENCODER_A=4; +int AGC_ENCODER_B=21; +int AGC_FUNCTION=7; +int ENABLE_BAND_BUTTON=1; +int BAND_BUTTON=13; +int ENABLE_BANDSTACK_BUTTON=1; +int BANDSTACK_BUTTON=12; +int ENABLE_MODE_BUTTON=1; +int MODE_BUTTON=6; +int ENABLE_FILTER_BUTTON=1; +int FILTER_BUTTON=5; +int ENABLE_NOISE_BUTTON=1; +int NOISE_BUTTON=24; +int ENABLE_AGC_BUTTON=1; +int AGC_BUTTON=23; +int ENABLE_MOX_BUTTON=1; +int MOX_BUTTON=27; +int ENABLE_FUNCTION_BUTTON=1; +int FUNCTION_BUTTON=22; +int ENABLE_LOCK_BUTTON=1; +int LOCK_BUTTON=25; + + + +/* +#define PI_VFO_ENCODER_A 17 +#define PI_VFO_ENCODER_B 18 + +#define ODROID_VFO_ENCODER_A 88 +#define ODROID_VFO_ENCODER_B 87 +#define ODROID_VFO_ENCODER_A_PIN 0 +#define ODROID_VFO_ENCODER_B_PIN 1 + +#define AF_ENCODER_A 20 +#define AF_ENCODER_B 26 +#define AF_FUNCTION 21 + +#define RF_ENCODER_A 16 +#define RF_ENCODER_B 19 +#define RF_FUNCTION 13 + +#define FUNCTION_BUTTON 22 +#define BAND_BUTTON 13 +#define BANDSTACK_BUTTON 12 +#define MODE_BUTTON 6 +#define FILTER_BUTTON 5 +#define NOISE_BUTTON 24 +#define AGC_BUTTON 23 +#define MOX_BUTTON 27 + +static int VFO_ENCODER_A=17; +static int VFO_ENCODER_B=18; + +static int VFO_ENCODER_A_PIN=0; +static int VFO_ENCODER_B_PIN=0; +*/ + +static volatile int vfoEncoderPos; +static volatile int afEncoderPos; +static volatile int afFunction; +static volatile int rfEncoderPos; +static volatile int rfFunction; +static volatile int agcEncoderPos; +static volatile int function_state; +static volatile int band_state; +static volatile int bandstack_state; +static volatile int mode_state; +static volatile int filter_state; +static volatile int noise_state; +static volatile int agc_state; +static volatile int mox_state; +static volatile int lock_state; + +static void* rotary_encoder_thread(void *arg); +static pthread_t rotary_encoder_thread_id; +int function=0; +static int previous_function_button=0; +static int af_function=0; +static int previous_af_function=0; +static int rf_function=0; +static int previous_rf_function=0; +static int band_button=0; +static int previous_band_button=0; +static int bandstack_button=0; +static int previous_bandstack_button=0; +static int mode_button=0; +static int previous_mode_button=0; +static int filter_button=0; +static int previous_filter_button=0; +static int noise_button=0; +static int previous_noise_button=0; +static int agc_button=0; +static int previous_agc_button=0; +static int mox_button=0; +static int previous_mox_button=0; +static int lock_button=0; +static int previous_lock_button=0; + +static void afFunctionAlert(int gpio, int level, uint32_t tick) { + afFunction=(level==0); +} + +static void rfFunctionAlert(int gpio, int level, uint32_t tick) { + rfFunction=(level==0); +} + +static void functionAlert(int gpio, int level, uint32_t tick) { + function_state=(level==0); +} + +static void bandAlert(int gpio, int level, uint32_t tick) { + band_state=(level==0); +} + +static void bandstackAlert(int gpio, int level, uint32_t tick) { + bandstack_state=(level==0); +} + +static void modeAlert(int gpio, int level, uint32_t tick) { + mode_state=(level==0); +} + +static void filterAlert(int gpio, int level, uint32_t tick) { + filter_state=(level==0); +} + +static void noiseAlert(int gpio, int level, uint32_t tick) { + noise_state=(level==0); +} + +static void agcAlert(int gpio, int level, uint32_t tick) { + agc_state=(level==0); +} + +static void moxAlert(int gpio, int level, uint32_t tick) { + mox_state=(level==0); +} + +static void lockAlert(int gpio, int level, uint32_t tick) { + lock_state=(level==0); +} + +static void vfoEncoderPulse(int gpio, int level, unsigned int tick) { + static int levA=0, levB=0, lastGpio = -1; + + if (gpio == VFO_ENCODER_A) levA = level; else levB = level; + + if (gpio != lastGpio) /* debounce */ + { + lastGpio = gpio; + + if ((gpio == VFO_ENCODER_A) && (level == 0)) + { + if (!levB) ++vfoEncoderPos; + } + else if ((gpio == VFO_ENCODER_B) && (level == 1)) + { + if (levA) --vfoEncoderPos; + } + } +} + +static void afEncoderPulse(int gpio, int level, uint32_t tick) +{ + static int levA=0, levB=0, lastGpio = -1; + + if (gpio == AF_ENCODER_A) levA = level; else levB = level; + + if (gpio != lastGpio) /* debounce */ + { + lastGpio = gpio; + + if ((gpio == AF_ENCODER_A) && (level == 0)) + { + if (!levB) ++afEncoderPos; + } + else if ((gpio == AF_ENCODER_B) && (level == 1)) + { + if (levA) --afEncoderPos; + } + } +} + +static void rfEncoderPulse(int gpio, int level, uint32_t tick) +{ + static int levA=0, levB=0, lastGpio = -1; + + if (gpio == RF_ENCODER_A) levA = level; else levB = level; + + if (gpio != lastGpio) /* debounce */ + { + lastGpio = gpio; + + if ((gpio == RF_ENCODER_A) && (level == 0)) + { + if (!levB) ++rfEncoderPos; + } + else if ((gpio == RF_ENCODER_B) && (level == 1)) + { + if (levA) --rfEncoderPos; + } + } +} + +static void agcEncoderPulse(int gpio, int level, uint32_t tick) +{ + static int levA=0, levB=0, lastGpio = -1; + + if (gpio == AGC_ENCODER_A) levA = level; else levB = level; + + if (gpio != lastGpio) /* debounce */ + { + lastGpio = gpio; + + if ((gpio == AGC_ENCODER_A) && (level == 0)) + { + if (!levB) ++agcEncoderPos; + } + else if ((gpio == AGC_ENCODER_B) && (level == 1)) + { + if (levA) --agcEncoderPos; + } + } +} + +#ifdef odroid +void interruptB(void) { + vfoEncoderPulse(VFO_ENCODER_B,digitalRead(VFO_ENCODER_B_PIN),0); +} + +void interruptA(void) { + vfoEncoderPulse(VFO_ENCODER_A,digitalRead(VFO_ENCODER_A_PIN),0); +} +#endif + +void gpio_restore_state() { + char* value; + loadProperties("gpio.props"); + value=getProperty("ENABLE_VFO_ENCODER"); + if(value) ENABLE_VFO_ENCODER=atoi(value); + value=getProperty("ENABLE_VFO_PULLUP"); + if(value) ENABLE_VFO_PULLUP=atoi(value); + value=getProperty("VFO_ENCODER_A"); + if(value) VFO_ENCODER_A=atoi(value); + value=getProperty("VFO_ENCODER_B"); + if(value) VFO_ENCODER_B=atoi(value); +#ifdef odroid + value=getProperty("VFO_ENCODER_A_PIN"); + if(value) VFO_ENCODER_A_PIN=atoi(value); + value=getProperty("VFO_ENCODER_B_PIN"); + if(value) VFO_ENCODER_B_PIN=atoi(value); +#endif + value=getProperty("ENABLE_AF_ENCODER"); + if(value) ENABLE_AF_ENCODER=atoi(value); + value=getProperty("ENABLE_AF_PULLUP"); + if(value) ENABLE_AF_PULLUP=atoi(value); + value=getProperty("AF_ENCODER_A"); + if(value) AF_ENCODER_A=atoi(value); + value=getProperty("AF_ENCODER_B"); + if(value) AF_ENCODER_B=atoi(value); + value=getProperty("ENABLE_RF_ENCODER"); + if(value) ENABLE_RF_ENCODER=atoi(value); + value=getProperty("ENABLE_RF_PULLUP"); + if(value) ENABLE_RF_PULLUP=atoi(value); + value=getProperty("RF_ENCODER_A"); + if(value) RF_ENCODER_A=atoi(value); + value=getProperty("RF_ENCODER_B"); + if(value) RF_ENCODER_B=atoi(value); + value=getProperty("ENABLE_AGC_ENCODER"); + if(value) ENABLE_AGC_ENCODER=atoi(value); + value=getProperty("ENABLE_AGC_PULLUP"); + if(value) ENABLE_AGC_PULLUP=atoi(value); + value=getProperty("AGC_ENCODER_A"); + if(value) AGC_ENCODER_A=atoi(value); + value=getProperty("AGC_ENCODER_B"); + if(value) AGC_ENCODER_B=atoi(value); + value=getProperty("ENABLE_BAND_BUTTON"); + if(value) ENABLE_BAND_BUTTON=atoi(value); + value=getProperty("BAND_BUTTON"); + if(value) BAND_BUTTON=atoi(value); + value=getProperty("ENABLE_BANDSTACK_BUTTON"); + if(value) ENABLE_BANDSTACK_BUTTON=atoi(value); + value=getProperty("BANDSTACK_BUTTON"); + if(value) BANDSTACK_BUTTON=atoi(value); + value=getProperty("ENABLE_MODE_BUTTON"); + if(value) ENABLE_MODE_BUTTON=atoi(value); + value=getProperty("MODE_BUTTON"); + if(value) MODE_BUTTON=atoi(value); + value=getProperty("ENABLE_FILTER_BUTTON"); + if(value) ENABLE_FILTER_BUTTON=atoi(value); + value=getProperty("FILTER_BUTTON"); + if(value) FILTER_BUTTON=atoi(value); + value=getProperty("ENABLE_NOISE_BUTTON"); + if(value) ENABLE_NOISE_BUTTON=atoi(value); + value=getProperty("NOISE_BUTTON"); + if(value) NOISE_BUTTON=atoi(value); + value=getProperty("ENABLE_AGC_BUTTON"); + if(value) ENABLE_AGC_BUTTON=atoi(value); + value=getProperty("AGC_BUTTON"); + if(value) AGC_BUTTON=atoi(value); + value=getProperty("ENABLE_FUNCTION_BUTTON"); + if(value) ENABLE_FUNCTION_BUTTON=atoi(value); + value=getProperty("FUNCTION_BUTTON"); + if(value) FUNCTION_BUTTON=atoi(value); + value=getProperty("ENABLE_MOX_BUTTON"); + if(value) ENABLE_MOX_BUTTON=atoi(value); + value=getProperty("MOX_BUTTON"); + if(value) MOX_BUTTON=atoi(value); + value=getProperty("ENABLE_LOCK_BUTTON"); + if(value) ENABLE_LOCK_BUTTON=atoi(value); + value=getProperty("LOCK_BUTTON"); + if(value) LOCK_BUTTON=atoi(value); +} + +void gpio_save_state() { + char value[80]; + + sprintf(value,"%d",ENABLE_VFO_ENCODER); + setProperty("ENABLE_VFO_ENCODER",value); + sprintf(value,"%d",ENABLE_VFO_PULLUP); + setProperty("ENABLE_VFO_PULLUP",value); + sprintf(value,"%d",VFO_ENCODER_A); + setProperty("VFO_ENCODER_A",value); + sprintf(value,"%d",VFO_ENCODER_B); + setProperty("VFO_ENCODER_B",value); +#ifdef odroid + sprintf(value,"%d",VFO_ENCODER_A_PIN); + setProperty("VFO_ENCODER_A_PIN",value); + sprintf(value,"%d",VFO_ENCODER_B_PIN); + setProperty("VFO_ENCODER_B_PIN",value); +#endif + sprintf(value,"%d",ENABLE_AF_ENCODER); + setProperty("ENABLE_AF_ENCODER",value); + sprintf(value,"%d",ENABLE_AF_PULLUP); + setProperty("ENABLE_AF_PULLUP",value); + sprintf(value,"%d",AF_ENCODER_A); + setProperty("AF_ENCODER_A",value); + sprintf(value,"%d",AF_ENCODER_B); + setProperty("AF_ENCODER_B",value); + sprintf(value,"%d",ENABLE_RF_ENCODER); + setProperty("ENABLE_RF_ENCODER",value); + sprintf(value,"%d",ENABLE_RF_PULLUP); + setProperty("ENABLE_RF_PULLUP",value); + sprintf(value,"%d",RF_ENCODER_A); + setProperty("RF_ENCODER_A",value); + sprintf(value,"%d",RF_ENCODER_B); + setProperty("RF_ENCODER_B",value); + sprintf(value,"%d",ENABLE_AGC_ENCODER); + setProperty("ENABLE_AGC_ENCODER",value); + sprintf(value,"%d",ENABLE_AGC_PULLUP); + setProperty("ENABLE_AGC_PULLUP",value); + sprintf(value,"%d",AGC_ENCODER_A); + setProperty("AGC_ENCODER_A",value); + sprintf(value,"%d",AGC_ENCODER_B); + setProperty("AGC_ENCODER_B",value); + sprintf(value,"%d",ENABLE_BAND_BUTTON); + setProperty("ENABLE_BAND_BUTTON",value); + sprintf(value,"%d",BAND_BUTTON); + setProperty("BAND_BUTTON",value); + sprintf(value,"%d",ENABLE_BANDSTACK_BUTTON); + setProperty("ENABLE_BANDSTACK_BUTTON",value); + sprintf(value,"%d",BANDSTACK_BUTTON); + setProperty("BANDSTACK_BUTTON",value); + sprintf(value,"%d",ENABLE_MODE_BUTTON); + setProperty("ENABLE_MODE_BUTTON",value); + sprintf(value,"%d",MODE_BUTTON); + setProperty("MODE_BUTTON",value); + sprintf(value,"%d",ENABLE_FILTER_BUTTON); + setProperty("ENABLE_FILTER_BUTTON",value); + sprintf(value,"%d",FILTER_BUTTON); + setProperty("FILTER_BUTTON",value); + sprintf(value,"%d",ENABLE_NOISE_BUTTON); + setProperty("ENABLE_NOISE_BUTTON",value); + sprintf(value,"%d",NOISE_BUTTON); + setProperty("NOISE_BUTTON",value); + sprintf(value,"%d",ENABLE_AGC_BUTTON); + setProperty("ENABLE_AGC_BUTTON",value); + sprintf(value,"%d",AGC_BUTTON); + setProperty("AGC_BUTTON",value); + sprintf(value,"%d",ENABLE_FUNCTION_BUTTON); + setProperty("ENABLE_FUNCTION_BUTTON",value); + sprintf(value,"%d",FUNCTION_BUTTON); + setProperty("FUNCTION_BUTTON",value); + sprintf(value,"%d",ENABLE_MOX_BUTTON); + setProperty("ENABLE_MOX_BUTTON",value); + sprintf(value,"%d",MOX_BUTTON); + setProperty("MOX_BUTTON",value); + sprintf(value,"%d",ENABLE_LOCK_BUTTON); + setProperty("ENABLE_LOCK_BUTTON",value); + sprintf(value,"%d",LOCK_BUTTON); + setProperty("LOCK_BUTTON",value); + + saveProperties("gpio.props"); +} + + +int gpio_init() { +fprintf(stderr,"encoder_init\n"); + gpio_restore_state(); + //if(strcmp(unameData.nodename,"raspberrypi")==0) { +#ifdef raspberrypi + + fprintf(stderr,"encoder_init: VFO_ENCODER_A=%d VFO_ENCODER_B=%d\n",VFO_ENCODER_A,VFO_ENCODER_B); + + fprintf(stderr,"gpioInitialize\n"); + if(gpioInitialise()<0) { + fprintf(stderr,"Cannot initialize GPIO\n"); + return -1; + } + + if(ENABLE_FUNCTION_BUTTON) { + gpioSetMode(FUNCTION_BUTTON, PI_INPUT); + gpioSetPullUpDown(FUNCTION_BUTTON,PI_PUD_UP); + gpioSetAlertFunc(FUNCTION_BUTTON, functionAlert); + } + + if(ENABLE_VFO_ENCODER) { + gpioSetMode(VFO_ENCODER_A, PI_INPUT); + gpioSetMode(VFO_ENCODER_B, PI_INPUT); + if(ENABLE_VFO_PULLUP) { + gpioSetPullUpDown(VFO_ENCODER_A, PI_PUD_UP); + gpioSetPullUpDown(VFO_ENCODER_B, PI_PUD_UP); + } else { + gpioSetPullUpDown(VFO_ENCODER_A, PI_PUD_OFF); + gpioSetPullUpDown(VFO_ENCODER_B, PI_PUD_OFF); + } + gpioSetAlertFunc(VFO_ENCODER_A, vfoEncoderPulse); + gpioSetAlertFunc(VFO_ENCODER_B, vfoEncoderPulse); + vfoEncoderPos=0; + } + + + gpioSetMode(AF_FUNCTION, PI_INPUT); + gpioSetPullUpDown(AF_FUNCTION,PI_PUD_UP); + gpioSetAlertFunc(AF_FUNCTION, afFunctionAlert); + afFunction=0; + + if(ENABLE_AF_ENCODER) { + gpioSetMode(AF_ENCODER_A, PI_INPUT); + gpioSetMode(AF_ENCODER_B, PI_INPUT); + if(ENABLE_AF_PULLUP) { + gpioSetPullUpDown(AF_ENCODER_A, PI_PUD_UP); + gpioSetPullUpDown(AF_ENCODER_B, PI_PUD_UP); + } else { + gpioSetPullUpDown(AF_ENCODER_A, PI_PUD_OFF); + gpioSetPullUpDown(AF_ENCODER_B, PI_PUD_OFF); + } + gpioSetAlertFunc(AF_ENCODER_A, afEncoderPulse); + gpioSetAlertFunc(AF_ENCODER_B, afEncoderPulse); + afEncoderPos=0; + } + + gpioSetMode(RF_FUNCTION, PI_INPUT); + gpioSetPullUpDown(RF_FUNCTION,PI_PUD_UP); + gpioSetAlertFunc(RF_FUNCTION, rfFunctionAlert); + rfFunction=0; + + if(ENABLE_RF_ENCODER) { + gpioSetMode(RF_ENCODER_A, PI_INPUT); + gpioSetMode(RF_ENCODER_B, PI_INPUT); + if(ENABLE_AF_PULLUP) { + gpioSetPullUpDown(RF_ENCODER_A, PI_PUD_UP); + gpioSetPullUpDown(RF_ENCODER_B, PI_PUD_UP); + } else { + gpioSetPullUpDown(RF_ENCODER_A, PI_PUD_OFF); + gpioSetPullUpDown(RF_ENCODER_B, PI_PUD_OFF); + } + gpioSetAlertFunc(RF_ENCODER_A, rfEncoderPulse); + gpioSetAlertFunc(RF_ENCODER_B, rfEncoderPulse); + rfEncoderPos=0; + } + + if(ENABLE_AGC_ENCODER) { + gpioSetMode(AGC_ENCODER_A, PI_INPUT); + gpioSetMode(AGC_ENCODER_B, PI_INPUT); + if(ENABLE_AF_PULLUP) { + gpioSetPullUpDown(AGC_ENCODER_A, PI_PUD_UP); + gpioSetPullUpDown(AGC_ENCODER_B, PI_PUD_UP); + } else { + gpioSetPullUpDown(AGC_ENCODER_A, PI_PUD_OFF); + gpioSetPullUpDown(AGC_ENCODER_B, PI_PUD_OFF); + } + gpioSetAlertFunc(AGC_ENCODER_A, agcEncoderPulse); + gpioSetAlertFunc(AGC_ENCODER_B, agcEncoderPulse); + rfEncoderPos=0; + } + + + if(ENABLE_BAND_BUTTON) { + gpioSetMode(BAND_BUTTON, PI_INPUT); + gpioSetPullUpDown(BAND_BUTTON,PI_PUD_UP); + gpioSetAlertFunc(BAND_BUTTON, bandAlert); + } + + if(ENABLE_BANDSTACK_BUTTON) { + gpioSetMode(BANDSTACK_BUTTON, PI_INPUT); + gpioSetPullUpDown(BANDSTACK_BUTTON,PI_PUD_UP); + gpioSetAlertFunc(BANDSTACK_BUTTON, bandstackAlert); + } + + if(ENABLE_MODE_BUTTON) { + gpioSetMode(MODE_BUTTON, PI_INPUT); + gpioSetPullUpDown(MODE_BUTTON,PI_PUD_UP); + gpioSetAlertFunc(MODE_BUTTON, modeAlert); + } + + if(ENABLE_FILTER_BUTTON) { + gpioSetMode(FILTER_BUTTON, PI_INPUT); + gpioSetPullUpDown(FILTER_BUTTON,PI_PUD_UP); + gpioSetAlertFunc(FILTER_BUTTON, filterAlert); + } + + if(ENABLE_NOISE_BUTTON) { + gpioSetMode(NOISE_BUTTON, PI_INPUT); + gpioSetPullUpDown(NOISE_BUTTON,PI_PUD_UP); + gpioSetAlertFunc(NOISE_BUTTON, noiseAlert); + } + + if(ENABLE_AGC_BUTTON) { + gpioSetMode(AGC_BUTTON, PI_INPUT); + gpioSetPullUpDown(AGC_BUTTON,PI_PUD_UP); + gpioSetAlertFunc(AGC_BUTTON, agcAlert); + } + + if(ENABLE_MOX_BUTTON) { + gpioSetMode(MOX_BUTTON, PI_INPUT); + gpioSetPullUpDown(MOX_BUTTON,PI_PUD_UP); + gpioSetAlertFunc(MOX_BUTTON, moxAlert); + } + + if(ENABLE_LOCK_BUTTON) { + gpioSetMode(LOCK_BUTTON, PI_INPUT); + gpioSetPullUpDown(LOCK_BUTTON,PI_PUD_UP); + gpioSetAlertFunc(LOCK_BUTTON, lockAlert); + } + +#endif +// } else if(strcmp(unameData.nodename,"odroid")==0) { +#ifdef odroid + + //VFO_ENCODER_A=ODROID_VFO_ENCODER_A; + //VFO_ENCODER_B=ODROID_VFO_ENCODER_B; + //VFO_ENCODER_A_PIN=ODROID_VFO_ENCODER_A_PIN; + //VFO_ENCODER_B_PIN=ODROID_VFO_ENCODER_B_PIN; + + fprintf(stderr,"encoder_init: VFO_ENCODER_A=%d VFO_ENCODER_B=%d\n",VFO_ENCODER_A,VFO_ENCODER_B); + + fprintf(stderr,"wiringPiSetup\n"); + if (wiringPiSetup () < 0) { + printf ("Unable to setup wiringPi: %s\n", strerror (errno)); + return 1; + } + + FILE *fp; + + fp = popen("echo 88 > /sys/class/gpio/export\n", "r"); + pclose(fp); + fp = popen("echo \"in\" > /sys/class/gpio/gpio88/direction\n", "r"); + pclose(fp); + fp = popen("chmod 0666 /sys/class/gpio/gpio88/value\n", "r"); + pclose(fp); + + fp = popen("echo 87 > /sys/class/gpio/export\n", "r"); + pclose(fp); + fp = popen("echo \"in\" > /sys/class/gpio/gpio87/direction\n", "r"); + pclose(fp); + fp = popen("chmod 0666 /sys/class/gpio/gpio87/value\n", "r"); + pclose(fp); + + if ( wiringPiISR (0, INT_EDGE_BOTH, &interruptB) < 0 ) { + printf ("Unable to setup ISR: %s\n", strerror (errno)); + return 1; + } + + if ( wiringPiISR (1, INT_EDGE_BOTH, &interruptA) < 0 ) { + printf ("Unable to setup ISR: %s\n", strerror (errno)); + return 1; + } +#endif +// } else { +// fprintf(stderr,"Unknown nodename: %s. Rotary Encoder not enabled.\n",unameData.nodename); +// return 1; +// } + + int rc=pthread_create(&rotary_encoder_thread_id, NULL, rotary_encoder_thread, NULL); + if(rc<0) { + fprintf(stderr,"pthread_create for rotary_encoder_thread failed %d\n",rc); + } + + + return 0; +} + +void gpio_close() { +// if(strcmp(unameData.nodename,"raspberrypi")==0) { +#ifdef raspberrypi + gpioTerminate(); +#endif +// } +// if(strcmp(unameData.nodename,"odroid")==0) { +#ifdef odroid + FILE *fp; + fp = popen("echo 97 > /sys/class/gpio/unexport\n", "r"); + pclose(fp); + fp = popen("echo 108 > /sys/class/gpio/unexport\n", "r"); + pclose(fp); +#endif +// } +} + +int vfo_encoder_get_pos() { + int pos=vfoEncoderPos; + + if(vfo_encoder_divisor>1) { + if(pos<0 && pos>-vfo_encoder_divisor) { + pos=0; + } else if(pos>0 && posfrequencyA=entry->frequencyA+(pos*step); + setFrequency(entry->frequencyA); + vfo_update(NULL); + } + free(data); + return 0; +} + +static int af_encoder_changed(void *data) { + int pos=*(int*)data; + if(pos!=0) { + if(function) { + // mic gain + double gain=mic_gain; + gain+=(double)pos/100.0; + if(gain<0.0) { + gain=0.0; + } else if(gain>4.0) { + gain=4.0; + } + set_mic_gain(gain); + } else { + // af gain + double gain=volume; + gain+=(double)pos/100.0; + if(gain<0.0) { + gain=0.0; + } else if(gain>1.0) { + gain=1.0; + } + set_af_gain(gain); + } + } + free(data); + return 0; +} + +static int rf_encoder_changed(void *data) { + int pos=*(int*)data; + if(pos!=0) { + if(function || tune) { + // tune drive + double d=getTuneDrive(); + d+=(double)pos/100.0; + if(d<0.0) { + d=0.0; + } else if(d>1.0) { + d=1.0; + } + set_tune(d); + } else { + // drive + double d=getDrive(); + d+=(double)pos/100.0; + if(d<0.0) { + d=0.0; + } else if(d>1.0) { + d=1.0; + } + set_drive(d); + } + } + free(data); + return 0; +} + +static int agc_encoder_changed(void *data) { + int pos=*(int*)data; + if(pos!=0) { + double gain=agc_gain; + gain+=(double)pos; + if(gain<0.0) { + gain=0.0; + } else if(gain>120.0) { + gain=120.0; + } + set_agc_gain(gain); + } + return 0; +} + +static int band_pressed(void *data) { + BAND* band; + BANDSTACK_ENTRY *entry; +fprintf(stderr,"band_pressed\n"); + int b=band_get_current(); + if(function) { + b--; + if(b<0) { + b=BANDS-1; + } + } else { + b++; + if(b>=BANDS) { + b=0; + } + } + band=band_set_current(b); + entry=bandstack_entry_get_current(); + + setFrequency(entry->frequencyA); + setMode(entry->mode); + FILTER* band_filters=filters[entry->mode]; + FILTER* band_filter=&band_filters[entry->filter]; + setFilter(band_filter->low,band_filter->high); + + band=band_get_current_band(); + set_alex_rx_antenna(band->alexRxAntenna); + set_alex_tx_antenna(band->alexTxAntenna); + set_alex_attenuation(band->alexAttenuation); + vfo_update(NULL); + + return 0; +} + +static int bandstack_pressed(void *data) { + BANDSTACK_ENTRY *entry; + fprintf(stderr,"bandstack_pressed\n"); + if(function) { + entry=bandstack_entry_previous(); + } else { + entry=bandstack_entry_next(); + } + setFrequency(entry->frequencyA); + setMode(entry->mode); + FILTER* band_filters=filters[entry->mode]; + FILTER* band_filter=&band_filters[entry->filter]; + setFilter(band_filter->low,band_filter->high); + vfo_update(NULL); + return 0; +} + +static int function_pressed(void *data) { +fprintf(stderr,"function_pressed\n"); + function=function==1?0:1; + vfo_update(NULL); + return 0; +} + +static int mox_pressed(void *data) { +fprintf(stderr,"mox_pressed\n"); + if(function) { + tune_cb((GtkWidget *)NULL, (gpointer)NULL); + } else { + mox_cb((GtkWidget *)NULL, (gpointer)NULL); + } + return 0; +} + +static int lock_pressed(void *data) { +fprintf(stderr,"lock_pressed\n"); + lock_cb((GtkWidget *)NULL, (gpointer)NULL); + return 0; +} + +static int mode_pressed(void *data) { + BAND* band; + BANDSTACK_ENTRY *entry; + +fprintf(stderr,"mode_pressed\n"); + band=band_get_current_band(); + entry=bandstack_entry_get_current(); + if(function) { + entry->mode--; + if(entry->mode<0) { + entry->mode=MODES-1; + } + } else { + entry->mode++; + if(entry->mode>=MODES) { + entry->mode=0; + } + } + setMode(entry->mode); + + FILTER* band_filters=filters[entry->mode]; + FILTER* band_filter=&band_filters[entry->filter]; + setFilter(band_filter->low,band_filter->high); + + vfo_update(NULL); + + return 0; +} + +static int filter_pressed(void *data) { + BAND* band; + BANDSTACK_ENTRY *entry; + +fprintf(stderr,"filter_pressed\n"); + band=band_get_current_band(); + entry=bandstack_entry_get_current(); + // note order of filter reversed (largest first) + if(function) { + entry->filter++; + if(entry->filter>=FILTERS) { + entry->filter=0; + } + } else { + entry->filter--; + if(entry->filter<0) { + entry->filter=FILTERS-1; + } + } + + FILTER* band_filters=filters[entry->mode]; + FILTER* band_filter=&band_filters[entry->filter]; + setFilter(band_filter->low,band_filter->high); + + vfo_update(NULL); + + return 0; +} + +static int noise_pressed(void *data) { +fprintf(stderr,"noise_pressed\n"); + if(function) { + if(nr) { + nr=0; + } else if(nb) { + nr=1; + nb=0; + } else if(anf) { + nb=1; + anf=0; + } else if(snb) { + snb=0; + anf=1; + } else { + snb=1; + } + } else { + if(nr) { + nr=0; + nb=1; + } else if(nb) { + nb=0; + anf=1; + } else if(anf) { + anf=0; + snb=1; + } else if(snb) { + snb=0; + } else { + nr=1; + } + } + SetRXAANRRun(CHANNEL_RX0, nr); + SetRXAEMNRRun(CHANNEL_RX0, nb); + SetRXAANFRun(CHANNEL_RX0, anf); + SetRXASNBARun(CHANNEL_RX0, snb); + vfo_update(NULL); + return 0; +} + +static int agc_pressed(void *data) { +fprintf(stderr,"agc_pressed\n"); + if(function) { + agc--; + if(agc<0) { + agc=3; + } + } else { + agc++; + if(agc>=4) { + agc=0; + } + } + SetRXAAGCMode(CHANNEL_RX0, agc); + vfo_update(NULL); + return 0; +} + +static void* rotary_encoder_thread(void *arg) { + int pos; + while(1) { + + int function_button=function_get_state(); + if(function_button!=previous_function_button) { + previous_function_button=function_button; + if(function_button) { + g_idle_add(function_pressed,(gpointer)NULL); + } + } + + pos=vfo_encoder_get_pos(); + if(pos!=0) { + int *p=malloc(sizeof(int)); + *p=pos; + g_idle_add(vfo_encoder_changed,(gpointer)p); + } + +/* + af_function=af_function_get_state(); + if(af_function!=previous_af_function) { + previous_af_function=af_function; + } +*/ + pos=af_encoder_get_pos(); + if(pos!=0) { + int *p=malloc(sizeof(int)); + *p=pos; + g_idle_add(af_encoder_changed,(gpointer)p); + } + +/* + rf_function=rf_function_get_state(); + if(rf_function!=previous_rf_function) { + previous_rf_function=rf_function; + } +*/ + pos=rf_encoder_get_pos(); + if(pos!=0) { + int *p=malloc(sizeof(int)); + *p=pos; + g_idle_add(rf_encoder_changed,(gpointer)p); + } + + pos=agc_encoder_get_pos(); + if(pos!=0) { + int *p=malloc(sizeof(int)); + *p=pos; + g_idle_add(agc_encoder_changed,(gpointer)p); + } + + + int band_button=band_get_state(); + if(band_button!=previous_band_button) { + previous_band_button=band_button; + if(band_button) { + g_idle_add(band_pressed,(gpointer)NULL); + } + } + + int bandstack_button=bandstack_get_state(); + if(bandstack_button!=previous_bandstack_button) { + previous_bandstack_button=bandstack_button; + if(bandstack_button) { + g_idle_add(bandstack_pressed,(gpointer)NULL); + } + } + + int mode_button=mode_get_state(); + if(mode_button!=previous_mode_button) { + previous_mode_button=mode_button; + if(mode_button) { + g_idle_add(mode_pressed,(gpointer)NULL); + } + } + + int filter_button=filter_get_state(); + if(filter_button!=previous_filter_button) { + previous_filter_button=filter_button; + if(filter_button) { + g_idle_add(filter_pressed,(gpointer)NULL); + } + } + + int noise_button=noise_get_state(); + if(noise_button!=previous_noise_button) { + previous_noise_button=noise_button; + if(noise_button) { + g_idle_add(noise_pressed,(gpointer)NULL); + } + } + + int agc_button=agc_get_state(); + if(agc_button!=previous_agc_button) { + previous_agc_button=agc_button; + if(agc_button) { + g_idle_add(agc_pressed,(gpointer)NULL); + } + } + + int mox_button=mox_get_state(); + if(mox_button!=previous_mox_button) { + previous_mox_button=mox_button; + if(mox_button) { + g_idle_add(mox_pressed,(gpointer)NULL); + } + } + + int lock_button=lock_get_state(); + if(lock_button!=previous_lock_button) { + previous_lock_button=lock_button; + if(lock_button) { + g_idle_add(lock_pressed,(gpointer)NULL); + } + } + +// if(strcmp(unameData.nodename,"raspberrypi")==0) { +#ifdef raspberrypi + gpioDelay(100000); // 10 per second +#endif +// } else if(strcmp(unameData.nodename,"odroid")==0) { +#ifdef odroid + usleep(100000); +#endif +// } + } +} diff --git a/gpio.h b/gpio.h new file mode 100644 index 0000000..569b616 --- /dev/null +++ b/gpio.h @@ -0,0 +1,71 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +extern int ENABLE_VFO_ENCODER; +extern int ENABLE_VFO_PULLUP; +extern int VFO_ENCODER_A; +extern int VFO_ENCODER_B; +extern int VFO_ENCODER_A_PIN; +extern int VFO_ENCODER_B_PIN; +extern int ENABLE_AF_ENCODER; +extern int ENABLE_AF_PULLUP; +extern int AF_ENCODER_A; +extern int AF_ENCODER_B; +extern int ENABLE_RF_ENCODER; +extern int ENABLE_RF_PULLUP; +extern int RF_ENCODER_A; +extern int RF_ENCODER_B; +extern int ENABLE_AGC_ENCODER; +extern int ENABLE_AGC_PULLUP; +extern int AGC_ENCODER_A; +extern int AGC_ENCODER_B; +extern int ENABLE_BAND_BUTTON; +extern int BAND_BUTTON; +extern int ENABLE_BANDSTACK_BUTTON; +extern int BANDSTACK_BUTTON; +extern int ENABLE_MODE_BUTTON; +extern int MODE_BUTTON; +extern int ENABLE_FILTER_BUTTON; +extern int FILTER_BUTTON; +extern int ENABLE_NOISE_BUTTON; +extern int NOISE_BUTTON; +extern int ENABLE_AGC_BUTTON; +extern int AGC_BUTTON; +extern int ENABLE_MOX_BUTTON; +extern int MOX_BUTTON; +extern int ENABLE_FUNCTION_BUTTON; +extern int FUNCTION_BUTTON; + +extern int function; +void gpio_restore_state(); +void gpio_save_state(); +int gpio_init(); +void gpio_close(); +int vfo_encoder_get_pos(); +int af_encoder_get_pos(); +int af_function_get_state(); +int rf_encoder_get_pos(); +int rf_function_get_state(); +int function_get_state(); +int band_get_state(); +int mode_get_state(); +int filter_get_state(); +int noise_get_state(); +int mox_get_state(); + diff --git a/main.c b/main.c index 814e9f5..ab7183b 100644 --- a/main.c +++ b/main.c @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include #include #include @@ -11,24 +30,32 @@ #include "main.h" #include "channel.h" #include "discovered.h" +#include "gpio.h" +#include "old_discovery.h" #include "new_discovery.h" #include "new_protocol.h" #include "wdsp.h" #include "vfo.h" +#include "menu.h" #include "meter.h" #include "panadapter.h" #include "splash.h" #include "waterfall.h" #include "toolbar.h" #include "radio.h" - -#define VFO_HEIGHT (display_height/8) -#define VFO_WIDTH ((display_width/4)*3) -#define METER_HEIGHT (display_height/8) -#define METER_WIDTH (display_width/4) -#define PANADAPTER_HEIGHT (display_height/4) -#define TOOLBAR_HEIGHT (display_height/4) -#define WATERFALL_HEIGHT (display_height-(VFO_HEIGHT+PANADAPTER_HEIGHT+TOOLBAR_HEIGHT)) +#include "wdsp_init.h" +#include "version.h" + +#define VFO_HEIGHT ((display_height/32)*4) +#define VFO_WIDTH ((display_width/32)*16) +#define MENU_HEIGHT VFO_HEIGHT +#define MENU_WIDTH ((display_width/32)*3) +#define METER_HEIGHT VFO_HEIGHT +#define METER_WIDTH ((display_width/32)*13) +#define PANADAPTER_HEIGHT ((display_height/32)*8) +#define SLIDERS_HEIGHT ((display_height/32)*6) +#define TOOLBAR_HEIGHT ((display_height/32)*2) +#define WATERFALL_HEIGHT (display_height-(VFO_HEIGHT+PANADAPTER_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT)) struct utsname unameData; @@ -46,74 +73,130 @@ static int start=0; static GtkWidget *discovery_dialog; +static sem_t wisdom_sem; + +static GdkCursor *cursor_arrow; +static GdkCursor *cursor_watch; + gint update(gpointer data) { int result; - GetPixels(isTransmitting()==0?CHANNEL_RX0:CHANNEL_TX,samples,&result); + double fwd; + double rev; + double exciter; + + GetPixels(isTransmitting()==0?CHANNEL_RX0:CHANNEL_TX,0,samples,&result); if(result==1) { - panadapter_update(samples,isTransmitting()); + if(display_panadapter) { + panadapter_update(samples,isTransmitting()); + } if(!isTransmitting()) { - waterfall_update(samples); + if(display_waterfall) { + waterfall_update(samples); + } } } if(!isTransmitting()) { float m=GetRXAMeter(CHANNEL_RX0, 1/*WDSP.S_AV*/); - meter_update(SMETER,(double)m,0.0); + meter_update(SMETER,(double)m,0.0,0.0); } else { DISCOVERED *d=&discovered[selected_device]; - double constant1=5.0; - double constant2=0.108; - - switch(d->device) { - case NEW_DEVICE_ATLAS: - constant1=3.3; - constant2=0.09; - break; - case NEW_DEVICE_HERMES: - constant1=3.3; - constant2=0.09; - break; - case NEW_DEVICE_HERMES2: - constant1=3.3; - constant2=0.095; - break; - case NEW_DEVICE_ANGELIA: - constant1=3.3; - constant2=0.095; - break; - case NEW_DEVICE_ORION: - constant1=5.0; - constant2=0.108; - break; - case NEW_DEVICE_ANAN_10E: - constant1=3.3; - constant2=0.09; - break; - case NEW_DEVICE_HERMES_LITE: - constant1=3.3; - constant2=0.09; - break; - } + double constant1=3.3; + double constant2=0.09; + + if(d->protocol==ORIGINAL_PROTOCOL) { + switch(d->device) { + case DEVICE_METIS: + break; + case DEVICE_HERMES: + //constant2=0.095; HERMES 2 + break; + case DEVICE_ANGELIA: + break; + case DEVICE_ORION: + constant1=5.0; + constant2=0.108; + break; + case DEVICE_HERMES_LITE: + break; + } + + int power=alex_forward_power; + if(power==0) { + power=exciter_power; + } + double v1; + v1=((double)power/4095.0)*constant1; + fwd=(v1*v1)/constant2; + + power=exciter_power; + v1=((double)power/4095.0)*constant1; + exciter=(v1*v1)/constant2; + + rev=0.0; + if(alex_forward_power!=0) { + power=alex_reverse_power; + v1=((double)power/4095.0)*constant1; + rev=(v1*v1)/constant2; + } + + } else { + switch(d->device) { + case NEW_DEVICE_ATLAS: + constant1=3.3; + constant2=0.09; + break; + case NEW_DEVICE_HERMES: + constant1=3.3; + constant2=0.09; + break; + case NEW_DEVICE_HERMES2: + constant1=3.3; + constant2=0.095; + break; + case NEW_DEVICE_ANGELIA: + constant1=3.3; + constant2=0.095; + break; + case NEW_DEVICE_ORION: + constant1=5.0; + constant2=0.108; + break; + case NEW_DEVICE_ANAN_10E: + constant1=3.3; + constant2=0.09; + break; + case NEW_DEVICE_HERMES_LITE: + constant1=3.3; + constant2=0.09; + break; + } - int power=alex_forward_power; - if(power==0) { + int power=alex_forward_power; + if(power==0) { + power=exciter_power; + } + double v1; + v1=((double)power/4095.0)*constant1; + fwd=(v1*v1)/constant2; + power=exciter_power; - } - double v1; - double fwd; - double rev; - v1=((double)power/4095.0)*constant1; - fwd=(v1*v1)/constant2; - - rev=0.0; - if(alex_forward_power!=0) { - power=alex_reverse_power; v1=((double)power/4095.0)*constant1; - rev=(v1*v1)/constant2; + exciter=(v1*v1)/constant2; + + rev=0.0; + if(alex_forward_power!=0) { + power=alex_reverse_power; + v1=((double)power/4095.0)*constant1; + rev=(v1*v1)/constant2; + } } - meter_update(POWER,fwd,rev); + +//fprintf(stderr,"drive=%d tune_drive=%d alex_forward_power=%d alex_reverse_power=%d exciter_power=%d fwd=%f rev=%f exciter=%f\n", +// drive, tune_drive, alex_forward_power, alex_reverse_power, exciter_power, fwd, rev, exciter); + meter_update(POWER,fwd,rev,exciter); } return TRUE; @@ -121,7 +204,6 @@ gint update(gpointer data) { static gint save_cb(gpointer data) { radioSaveState(); - saveProperties(property_path); return TRUE; } @@ -132,39 +214,480 @@ fprintf(stderr,"start_cb\n"); gtk_widget_destroy(discovery_dialog); } +static void sample_rate_cb(GtkWidget *widget, gpointer data) { + sample_rate=(int)data; +} + +static void display_panadapter_cb(GtkWidget *widget, gpointer data) { + display_panadapter=display_panadapter==1?0:1; +} + +static void display_waterfall_cb(GtkWidget *widget, gpointer data) { + display_waterfall=display_waterfall==1?0:1; +} + +static void display_sliders_cb(GtkWidget *widget, gpointer data) { + display_sliders=display_sliders==1?0:1; +} + +static void display_toolbar_cb(GtkWidget *widget, gpointer data) { + display_toolbar=display_toolbar==1?0:1; +} + +static void configure_gpio() { + gpio_restore_state(); + + GtkWidget *dialog=gtk_dialog_new_with_buttons("Configure GPIO",GTK_WINDOW(splash_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + GtkWidget *grid=gtk_grid_new(); + gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); + gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); + + + GtkWidget *b_enable_vfo_encoder=gtk_check_button_new_with_label("Enable VFO"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_vfo_encoder), ENABLE_VFO_ENCODER); + gtk_widget_show(b_enable_vfo_encoder); + gtk_grid_attach(GTK_GRID(grid),b_enable_vfo_encoder,0,0,1,1); + + GtkWidget *vfo_a_label=gtk_label_new("GPIO A:"); + gtk_widget_show(vfo_a_label); + gtk_grid_attach(GTK_GRID(grid),vfo_a_label,1,0,1,1); + + GtkWidget *vfo_a=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(vfo_a),VFO_ENCODER_A); + gtk_widget_show(vfo_a); + gtk_grid_attach(GTK_GRID(grid),vfo_a,2,0,1,1); + + GtkWidget *vfo_b_label=gtk_label_new("GPIO B:"); + gtk_widget_show(vfo_b_label); + gtk_grid_attach(GTK_GRID(grid),vfo_b_label,3,0,1,1); + + GtkWidget *vfo_b=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(vfo_b),VFO_ENCODER_B); + gtk_widget_show(vfo_b); + gtk_grid_attach(GTK_GRID(grid),vfo_b,4,0,1,1); + + GtkWidget *b_enable_vfo_pullup=gtk_check_button_new_with_label("Enable Pull-up"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_vfo_pullup), ENABLE_VFO_PULLUP); + gtk_widget_show(b_enable_vfo_pullup); + gtk_grid_attach(GTK_GRID(grid),b_enable_vfo_pullup,5,0,1,1); + + + + GtkWidget *b_enable_af_encoder=gtk_check_button_new_with_label("Enable AF"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_af_encoder), ENABLE_AF_ENCODER); + gtk_widget_show(b_enable_af_encoder); + gtk_grid_attach(GTK_GRID(grid),b_enable_af_encoder,0,1,1,1); + + GtkWidget *af_a_label=gtk_label_new("GPIO A:"); + gtk_widget_show(af_a_label); + gtk_grid_attach(GTK_GRID(grid),af_a_label,1,1,1,1); + + GtkWidget *af_a=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(af_a),AF_ENCODER_A); + gtk_widget_show(af_a); + gtk_grid_attach(GTK_GRID(grid),af_a,2,1,1,1); + + GtkWidget *af_b_label=gtk_label_new("GPIO B:"); + gtk_widget_show(af_b_label); + gtk_grid_attach(GTK_GRID(grid),af_b_label,3,1,1,1); + + GtkWidget *af_b=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(af_b),AF_ENCODER_B); + gtk_widget_show(af_b); + gtk_grid_attach(GTK_GRID(grid),af_b,4,1,1,1); + + GtkWidget *b_enable_af_pullup=gtk_check_button_new_with_label("Enable Pull-up"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_af_pullup), ENABLE_AF_PULLUP); + gtk_widget_show(b_enable_af_pullup); + gtk_grid_attach(GTK_GRID(grid),b_enable_af_pullup,5,1,1,1); + + + + GtkWidget *b_enable_rf_encoder=gtk_check_button_new_with_label("Enable RF"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_rf_encoder), ENABLE_RF_ENCODER); + gtk_widget_show(b_enable_rf_encoder); + gtk_grid_attach(GTK_GRID(grid),b_enable_rf_encoder,0,2,1,1); + + GtkWidget *rf_a_label=gtk_label_new("GPIO A:"); + gtk_widget_show(rf_a_label); + gtk_grid_attach(GTK_GRID(grid),rf_a_label,1,2,1,1); + + GtkWidget *rf_a=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(rf_a),RF_ENCODER_A); + gtk_widget_show(rf_a); + gtk_grid_attach(GTK_GRID(grid),rf_a,2,2,1,1); + + GtkWidget *rf_b_label=gtk_label_new("GPIO B:"); + gtk_widget_show(rf_b_label); + gtk_grid_attach(GTK_GRID(grid),rf_b_label,3,2,1,1); + + GtkWidget *rf_b=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(rf_b),RF_ENCODER_B); + gtk_widget_show(rf_b); + gtk_grid_attach(GTK_GRID(grid),rf_b,4,2,1,1); + + GtkWidget *b_enable_rf_pullup=gtk_check_button_new_with_label("Enable Pull-up"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_rf_pullup), ENABLE_RF_PULLUP); + gtk_widget_show(b_enable_rf_pullup); + gtk_grid_attach(GTK_GRID(grid),b_enable_rf_pullup,5,2,1,1); + + + + GtkWidget *b_enable_agc_encoder=gtk_check_button_new_with_label("Enable AGC"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_agc_encoder), ENABLE_AGC_ENCODER); + gtk_widget_show(b_enable_agc_encoder); + gtk_grid_attach(GTK_GRID(grid),b_enable_agc_encoder,0,3,1,1); + + GtkWidget *agc_a_label=gtk_label_new("GPIO A:"); + gtk_widget_show(agc_a_label); + gtk_grid_attach(GTK_GRID(grid),agc_a_label,1,3,1,1); + + GtkWidget *agc_a=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(agc_a),AGC_ENCODER_A); + gtk_widget_show(agc_a); + gtk_grid_attach(GTK_GRID(grid),agc_a,2,3,1,1); + + GtkWidget *agc_b_label=gtk_label_new("GPIO B:"); + gtk_widget_show(agc_b_label); + gtk_grid_attach(GTK_GRID(grid),agc_b_label,3,3,1,1); + + GtkWidget *agc_b=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(agc_b),AGC_ENCODER_B); + gtk_widget_show(agc_b); + gtk_grid_attach(GTK_GRID(grid),agc_b,4,3,1,1); + + GtkWidget *b_enable_agc_pullup=gtk_check_button_new_with_label("Enable Pull-up"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_agc_pullup), ENABLE_AGC_PULLUP); + gtk_widget_show(b_enable_agc_pullup); + gtk_grid_attach(GTK_GRID(grid),b_enable_agc_pullup,5,3,1,1); + + + + GtkWidget *b_enable_band=gtk_check_button_new_with_label("Enable Band"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_band), ENABLE_BAND_BUTTON); + gtk_widget_show(b_enable_band); + gtk_grid_attach(GTK_GRID(grid),b_enable_band,0,4,1,1); + + GtkWidget *band_label=gtk_label_new("GPIO:"); + gtk_widget_show(band_label); + gtk_grid_attach(GTK_GRID(grid),band_label,1,4,1,1); + + GtkWidget *band=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(band),BAND_BUTTON); + gtk_widget_show(band); + gtk_grid_attach(GTK_GRID(grid),band,2,4,1,1); + + + GtkWidget *b_enable_mode=gtk_check_button_new_with_label("Enable Mode"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_mode), ENABLE_MODE_BUTTON); + gtk_widget_show(b_enable_mode); + gtk_grid_attach(GTK_GRID(grid),b_enable_mode,0,5,1,1); + + GtkWidget *mode_label=gtk_label_new("GPIO:"); + gtk_widget_show(mode_label); + gtk_grid_attach(GTK_GRID(grid),mode_label,1,5,1,1); + + GtkWidget *mode=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(mode),MODE_BUTTON); + gtk_widget_show(mode); + gtk_grid_attach(GTK_GRID(grid),mode,2,5,1,1); + + + GtkWidget *b_enable_filter=gtk_check_button_new_with_label("Enable Filter"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_filter), ENABLE_FILTER_BUTTON); + gtk_widget_show(b_enable_filter); + gtk_grid_attach(GTK_GRID(grid),b_enable_filter,0,6,1,1); + + GtkWidget *filter_label=gtk_label_new("GPIO:"); + gtk_widget_show(filter_label); + gtk_grid_attach(GTK_GRID(grid),filter_label,1,6,1,1); + + GtkWidget *filter=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(filter),FILTER_BUTTON); + gtk_widget_show(filter); + gtk_grid_attach(GTK_GRID(grid),filter,2,6,1,1); + + + GtkWidget *b_enable_noise=gtk_check_button_new_with_label("Enable Noise"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_noise), ENABLE_NOISE_BUTTON); + gtk_widget_show(b_enable_noise); + gtk_grid_attach(GTK_GRID(grid),b_enable_noise,0,7,1,1); + + GtkWidget *noise_label=gtk_label_new("GPIO:"); + gtk_widget_show(noise_label); + gtk_grid_attach(GTK_GRID(grid),noise_label,1,7,1,1); + + GtkWidget *noise=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(noise),NOISE_BUTTON); + gtk_widget_show(noise); + gtk_grid_attach(GTK_GRID(grid),noise,2,7,1,1); + + + GtkWidget *b_enable_agc=gtk_check_button_new_with_label("Enable AGC"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_agc), ENABLE_AGC_BUTTON); + gtk_widget_show(b_enable_agc); + gtk_grid_attach(GTK_GRID(grid),b_enable_agc,0,8,1,1); + + GtkWidget *agc_label=gtk_label_new("GPIO:"); + gtk_widget_show(agc_label); + gtk_grid_attach(GTK_GRID(grid),agc_label,1,8,1,1); + + GtkWidget *agc=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(agc),AGC_BUTTON); + gtk_widget_show(agc); + gtk_grid_attach(GTK_GRID(grid),agc,2,8,1,1); + + + GtkWidget *b_enable_mox=gtk_check_button_new_with_label("Enable MOX"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_mox), ENABLE_MOX_BUTTON); + gtk_widget_show(b_enable_mox); + gtk_grid_attach(GTK_GRID(grid),b_enable_mox,0,9,1,1); + + GtkWidget *mox_label=gtk_label_new("GPIO:"); + gtk_widget_show(mox_label); + gtk_grid_attach(GTK_GRID(grid),mox_label,1,9,1,1); + + GtkWidget *mox=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(mox),MOX_BUTTON); + gtk_widget_show(mox); + gtk_grid_attach(GTK_GRID(grid),mox,2,9,1,1); + + + GtkWidget *b_enable_function=gtk_check_button_new_with_label("Enable Function"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_function), ENABLE_FUNCTION_BUTTON); + gtk_widget_show(b_enable_function); + gtk_grid_attach(GTK_GRID(grid),b_enable_function,0,10,1,1); + + GtkWidget *function_label=gtk_label_new("GPIO:"); + gtk_widget_show(function_label); + gtk_grid_attach(GTK_GRID(grid),function_label,1,10,1,1); + + GtkWidget *function=gtk_spin_button_new_with_range (0.0,100.0,1.0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(function),FUNCTION_BUTTON); + gtk_widget_show(function); + gtk_grid_attach(GTK_GRID(grid),function,2,10,1,1); + + + + gtk_container_add(GTK_CONTAINER(content),grid); + + gtk_container_add(GTK_CONTAINER(content),grid); + + GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK); + //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20")); + gtk_widget_show_all(dialog); + +/* + g_signal_connect_swapped (dialog, + "response", + G_CALLBACK (gtk_widget_destroy), + dialog); +*/ + + int result=gtk_dialog_run(GTK_DIALOG(dialog)); + + ENABLE_VFO_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_vfo_encoder))?1:0; + VFO_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vfo_a)); + VFO_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vfo_b)); + ENABLE_AF_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_af_encoder))?1:0; + AF_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(af_a)); + AF_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(af_b)); + ENABLE_RF_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_rf_encoder))?1:0; + RF_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(rf_a)); + RF_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(rf_b)); + ENABLE_AGC_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_agc_encoder))?1:0; + AGC_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(agc_a)); + AGC_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(agc_b)); + ENABLE_BAND_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_band))?1:0; + BAND_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(band)); + ENABLE_MODE_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_mode))?1:0; + MODE_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(mode)); + ENABLE_FILTER_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_filter))?1:0; + FILTER_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(filter)); + ENABLE_NOISE_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_noise))?1:0; + NOISE_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(noise)); + ENABLE_AGC_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_agc))?1:0; + AGC_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(agc)); + ENABLE_MOX_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_mox))?1:0; + MOX_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(mox)); + ENABLE_FUNCTION_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_function))?1:0; + FUNCTION_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(function)); + + gtk_widget_destroy(dialog); + + gpio_save_state(); +} + static void configure_cb(GtkWidget *widget, gpointer data) { + DISCOVERED* d; + d=&discovered[(int)data]; + sprintf(property_path,"%02X-%02X-%02X-%02X-%02X-%02X.props", + d->mac_address[0], + d->mac_address[1], + d->mac_address[2], + d->mac_address[3], + d->mac_address[4], + d->mac_address[5]); + radioRestoreState(); + + GtkWidget *dialog=gtk_dialog_new_with_buttons("Configure",GTK_WINDOW(splash_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + GtkWidget *grid=gtk_grid_new(); + gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE); + gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE); + + GtkWidget *sample_rate_label=gtk_label_new("Sample Rate:"); + //gtk_widget_override_font(sample_rate_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(sample_rate_label); + gtk_grid_attach(GTK_GRID(grid),sample_rate_label,0,0,1,1); + + GtkWidget *sample_rate_48=gtk_radio_button_new_with_label(NULL,"48000"); + //gtk_widget_override_font(sample_rate_48, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_48), sample_rate==48000); + gtk_widget_show(sample_rate_48); + gtk_grid_attach(GTK_GRID(grid),sample_rate_48,0,1,1,1); + g_signal_connect(sample_rate_48,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)48000); + + GtkWidget *sample_rate_96=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_48),"96000"); + //gtk_widget_override_font(sample_rate_96, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_96), sample_rate==96000); + gtk_widget_show(sample_rate_96); + gtk_grid_attach(GTK_GRID(grid),sample_rate_96,0,2,1,1); + g_signal_connect(sample_rate_96,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)96000); + + GtkWidget *sample_rate_192=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_96),"192000"); + //gtk_widget_override_font(sample_rate_192, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_192), sample_rate==192000); + gtk_widget_show(sample_rate_192); + gtk_grid_attach(GTK_GRID(grid),sample_rate_192,0,3,1,1); + g_signal_connect(sample_rate_192,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)192000); + + GtkWidget *sample_rate_384=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_192),"384000"); + //gtk_widget_override_font(sample_rate_384, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_384), sample_rate==384000); + gtk_widget_show(sample_rate_384); + gtk_grid_attach(GTK_GRID(grid),sample_rate_384,0,4,1,1); + g_signal_connect(sample_rate_384,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)384000); + + + GtkWidget *display_label=gtk_label_new("Display:"); + //gtk_widget_override_font(display_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(display_label); + gtk_grid_attach(GTK_GRID(grid),display_label,0,5,1,1); + + GtkWidget *b_display_panadapter=gtk_check_button_new_with_label("Display Panadapter"); + //gtk_widget_override_font(b_display_panadapter, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_display_panadapter), display_panadapter); + gtk_widget_show(b_display_panadapter); + gtk_grid_attach(GTK_GRID(grid),b_display_panadapter,0,6,1,1); + g_signal_connect(b_display_panadapter,"toggled",G_CALLBACK(display_panadapter_cb),(gpointer *)NULL); + + GtkWidget *b_display_waterfall=gtk_check_button_new_with_label("Display Waterfall"); + //gtk_widget_override_font(b_display_waterfall, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_display_waterfall), display_waterfall); + gtk_widget_show(b_display_waterfall); + gtk_grid_attach(GTK_GRID(grid),b_display_waterfall,0,7,1,1); + g_signal_connect(b_display_waterfall,"toggled",G_CALLBACK(display_waterfall_cb),(gpointer *)NULL); + + GtkWidget *b_display_sliders=gtk_check_button_new_with_label("Display Sliders"); + //gtk_widget_override_font(b_display_sliders, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_display_sliders), display_sliders); + gtk_widget_show(b_display_sliders); + gtk_grid_attach(GTK_GRID(grid),b_display_sliders,0,8,1,1); + g_signal_connect(b_display_sliders,"toggled",G_CALLBACK(display_sliders_cb),(gpointer *)NULL); + + GtkWidget *b_display_toolbar=gtk_check_button_new_with_label("Display Toolbar"); + //gtk_widget_override_font(b_display_toolbar, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_display_toolbar), display_toolbar); + gtk_widget_show(b_display_toolbar); + gtk_grid_attach(GTK_GRID(grid),b_display_toolbar,0,9,1,1); + g_signal_connect(b_display_toolbar,"toggled",G_CALLBACK(display_toolbar_cb),(gpointer *)NULL); + + gtk_container_add(GTK_CONTAINER(content),grid); + + GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK); + //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20")); + gtk_widget_show_all(dialog); + + g_signal_connect_swapped (dialog, + "response", + G_CALLBACK (gtk_widget_destroy), + dialog); + + int result=gtk_dialog_run(GTK_DIALOG(dialog)); + + radioSaveState(); + } +static pthread_t wisdom_thread_id; + +static void* wisdom_thread(void *arg) { + splash_status("Creating FFTW Wisdom file ..."); + WDSPwisdom ((char *)arg); + sem_post(&wisdom_sem); +} gint init(void* arg) { GtkWidget *window; GtkWidget *grid; + GtkWidget *fixed; + gint x; + gint y; GtkWidget *vfo; + GtkWidget *menu; GtkWidget *meter; GtkWidget *panadapter; GtkWidget *waterfall; + GtkWidget *sliders; GtkWidget *toolbar; DISCOVERED* d; + char *res; char wisdom_directory[1024]; char wisdom_file[1024]; fprintf(stderr,"init\n"); + cursor_arrow=gdk_cursor_new(GDK_ARROW); + cursor_watch=gdk_cursor_new(GDK_WATCH); + + GdkWindow *gdk_splash_window = gtk_widget_get_window(splash_window); + gdk_window_set_cursor(gdk_splash_window,cursor_watch); + + init_radio(); + // check if wisdom file exists - getcwd(wisdom_directory, sizeof(wisdom_directory)); + res=getcwd(wisdom_directory, sizeof(wisdom_directory)); strcpy(&wisdom_directory[strlen(wisdom_directory)],"/"); strcpy(wisdom_file,wisdom_directory); strcpy(&wisdom_file[strlen(wisdom_file)],"wdspWisdom"); + splash_status("Checking FFTW Wisdom file ..."); if(access(wisdom_file,F_OK)<0) { - WDSPwisdom (wisdom_directory); + int rc=sem_init(&wisdom_sem, 0, 0); + rc=pthread_create(&wisdom_thread_id, NULL, wisdom_thread, (void *)wisdom_directory); + while(sem_trywait(&wisdom_sem)<0) { + splash_status(wisdom_get_status()); + while (gtk_events_pending ()) + gtk_main_iteration (); + usleep(100000); // 100ms + } } while(!start) { + gdk_window_set_cursor(gdk_splash_window,cursor_watch); + selected_device=0; + devices=0; + splash_status("Old Protocol ... Discovering Devices"); + old_discovery(); + splash_status("New Protocol ... Discovering Devices"); new_discovery(); + splash_status("Discovery"); if(devices==0) { + gdk_window_set_cursor(gdk_splash_window,cursor_arrow); fprintf(stderr,"No devices found!\n"); GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT; discovery_dialog = gtk_message_dialog_new (GTK_WINDOW(splash_window), @@ -172,27 +695,30 @@ gint init(void* arg) { GTK_MESSAGE_ERROR, GTK_BUTTONS_OK_CANCEL, "No devices found! Retry Discovery?"); + gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("Arial 18")); gint result=gtk_dialog_run (GTK_DIALOG (discovery_dialog)); + gtk_widget_destroy(discovery_dialog); if(result==GTK_RESPONSE_CANCEL) { _exit(0); } - } else if(devices==1) { - selected_device=0; - start=1; } else { fprintf(stderr,"%s: found %d devices.\n", (char *)arg, devices); + gdk_window_set_cursor(gdk_splash_window,cursor_arrow); GtkDialogFlags flags=GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT; discovery_dialog = gtk_dialog_new_with_buttons ("Discovered", GTK_WINDOW(splash_window), flags, + "Configure GPIO", + GTK_RESPONSE_YES, "Discover", GTK_RESPONSE_REJECT, + "Exit", + GTK_RESPONSE_CLOSE, NULL); + gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("Arial 18")); GtkWidget *content; -// g_signal_connect_swapped(discovery_dialog,"response",G_CALLBACK(gtk_widget_destroy),discovery_dialog); - content=gtk_dialog_get_content_area(GTK_DIALOG(discovery_dialog)); GtkWidget *grid=gtk_grid_new(); @@ -203,8 +729,11 @@ gint init(void* arg) { char text[128]; for(i=0;iname, + d->protocol==ORIGINAL_PROTOCOL?"old":"new", + d->protocol==ORIGINAL_PROTOCOL?d->software_version/10:d->software_version/100, + d->protocol==ORIGINAL_PROTOCOL?d->software_version%10:d->software_version%100, inet_ntoa(d->address.sin_addr), d->mac_address[0], d->mac_address[1], @@ -215,27 +744,46 @@ gint init(void* arg) { d->interface_name); GtkWidget *label=gtk_label_new(text); + gtk_widget_override_font(label, pango_font_description_from_string("Arial 12")); gtk_widget_show(label); - gtk_grid_attach(GTK_GRID(grid),label,0,i,3,1); + gtk_grid_attach(GTK_GRID(grid),label,0,i,4,1); GtkWidget *start_button=gtk_button_new_with_label("Start"); + gtk_widget_override_font(start_button, pango_font_description_from_string("Arial 18")); gtk_widget_show(start_button); - gtk_grid_attach(GTK_GRID(grid),start_button,3,i,1,1); + gtk_grid_attach(GTK_GRID(grid),start_button,4,i,1,1); g_signal_connect(start_button,"pressed",G_CALLBACK(start_cb),(gpointer *)i); GtkWidget *configure_button=gtk_button_new_with_label("Configure"); + gtk_widget_override_font(configure_button, pango_font_description_from_string("Arial 18")); gtk_widget_show(configure_button); - gtk_grid_attach(GTK_GRID(grid),configure_button,4,i,1,1); + gtk_grid_attach(GTK_GRID(grid),configure_button,5,i,1,1); g_signal_connect(configure_button,"pressed",G_CALLBACK(configure_cb),(gpointer *)i); } gtk_container_add (GTK_CONTAINER (content), grid); gtk_widget_show_all(discovery_dialog); gint result=gtk_dialog_run(GTK_DIALOG(discovery_dialog)); + + if(result==GTK_RESPONSE_CLOSE) { + _exit(0); + } + + if(result==GTK_RESPONSE_YES) { + gtk_widget_destroy(discovery_dialog); + configure_gpio(); + } } } + gdk_window_set_cursor(gdk_splash_window,cursor_watch); + + splash_status("Initializing wdsp ..."); + d=&discovered[selected_device]; + protocol=d->protocol; + device=d->device; + sprintf(property_path,"%02X-%02X-%02X-%02X-%02X-%02X.props", d->mac_address[0], d->mac_address[1], @@ -244,39 +792,128 @@ gint init(void* arg) { d->mac_address[4], d->mac_address[5]); - loadProperties(property_path); radioRestoreState(); samples=malloc(display_width*sizeof(float)); - //selected_device=0; - setSampleRate(48000); - new_protocol_init(0,display_width); + //splash_status("Initializing wdsp ..."); + wdsp_init(0,display_width,d->protocol); - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window), "pihpsdr"); + if(d->protocol==ORIGINAL_PROTOCOL) { + splash_status("Initializing old protocol ..."); + old_protocol_init(0,display_width); + } else { + splash_status("Initializing new protocol ..."); + new_protocol_init(0,display_width); + } - //g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL); + splash_status("Initializing GPIO ..."); + gpio_init(); + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (window), "pihpsdr"); gtk_container_set_border_width (GTK_CONTAINER (window), 0); +#ifdef GRID_LAYOUT grid = gtk_grid_new(); + gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); + gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE); gtk_container_add(GTK_CONTAINER(window), grid); +#else + fixed=gtk_fixed_new(); + gtk_container_add(GTK_CONTAINER(window), fixed); + y=0; +#endif +fprintf(stderr,"vfo_height=%d\n",VFO_HEIGHT); vfo = vfo_init(VFO_WIDTH,VFO_HEIGHT,window); - gtk_grid_attach(GTK_GRID(grid), vfo, 0, 0, 3, 1); - +#ifdef GRID_LAYOUT + gtk_grid_attach(GTK_GRID(grid), vfo, 0, y, 16, 1); +#else + gtk_fixed_put(GTK_FIXED(fixed),vfo,0,0); +#endif + + +fprintf(stderr,"menu_height=%d\n",MENU_HEIGHT); + menu = menu_init(MENU_WIDTH,MENU_HEIGHT,window); +#ifdef GRID_LAYOUT + gtk_grid_attach(GTK_GRID(grid), menu, 16, 0, 1, 1); +#else + gtk_fixed_put(GTK_FIXED(fixed),menu,VFO_WIDTH,y); +#endif + +fprintf(stderr,"meter_height=%d\n",METER_HEIGHT); meter = meter_init(METER_WIDTH,METER_HEIGHT); - gtk_grid_attach(GTK_GRID(grid), meter, 3, 0, 1, 1); +#ifdef GRID_LAYOUT + gtk_grid_attach(GTK_GRID(grid), meter, 17, 0, 15, 1); +#else + gtk_fixed_put(GTK_FIXED(fixed),meter,VFO_WIDTH+MENU_WIDTH,y); + y+=VFO_HEIGHT; +#endif + + if(display_panadapter) { + int height=PANADAPTER_HEIGHT; + if(!display_waterfall) { + height+=WATERFALL_HEIGHT; + if(!display_sliders) { + height+=SLIDERS_HEIGHT; + } + if(!display_toolbar) { + height+=TOOLBAR_HEIGHT; + } + } +fprintf(stderr,"panadapter_height=%d\n",height); + panadapter = panadapter_init(display_width,height); +#ifdef GRID_LAYOUT + gtk_grid_attach(GTK_GRID(grid), panadapter, 0, 1, 32, 1); +#else + gtk_fixed_put(GTK_FIXED(fixed),panadapter,0,VFO_HEIGHT); + y+=height; +#endif + } - panadapter = panadapter_init(display_width,PANADAPTER_HEIGHT); - gtk_grid_attach(GTK_GRID(grid), panadapter, 0, 1, 4, 1); + if(display_waterfall) { + int height=WATERFALL_HEIGHT; + if(!display_panadapter) { + height+=PANADAPTER_HEIGHT; + } + if(!display_sliders) { + height+=SLIDERS_HEIGHT; + } + if(!display_toolbar) { + height+=TOOLBAR_HEIGHT; + } +fprintf(stderr,"waterfall_height=%d\n",height); + waterfall = waterfall_init(display_width,height); +#ifdef GRID_LAYOUT + gtk_grid_attach(GTK_GRID(grid), waterfall, 0, 2, 32, 1); +#else + gtk_fixed_put(GTK_FIXED(fixed),waterfall,0,y); + y+=height; +#endif + } - waterfall = waterfall_init(display_width,WATERFALL_HEIGHT); - gtk_grid_attach(GTK_GRID(grid), waterfall, 0, 2, 4, 1); + if(display_sliders) { +fprintf(stderr,"sliders_height=%d\n",SLIDERS_HEIGHT); + sliders = sliders_init(display_width,SLIDERS_HEIGHT,window); +#ifdef GRID_LAYOUT + gtk_grid_attach(GTK_GRID(grid), sliders, 0, 3, 32, 1); +#else + gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y); + y+=SLIDERS_HEIGHT; +#endif + } - toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,window); - gtk_grid_attach(GTK_GRID(grid), toolbar, 0, 3, 4, 1); + if(display_toolbar) { +fprintf(stderr,"toolbar_height=%d\n",TOOLBAR_HEIGHT); + toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,window); +#ifdef GRID_LAYOUT + gtk_grid_attach(GTK_GRID(grid), toolbar, 0, 4, 32, 1); +#else + gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y); + y+=TOOLBAR_HEIGHT; +#endif + } splash_close(); @@ -285,19 +922,8 @@ gint init(void* arg) { gtk_window_fullscreen(GTK_WINDOW(window)); - GdkCursor *cursor=gdk_cursor_new(GDK_ARROW); GdkWindow *gdk_window = gtk_widget_get_window(window); - gdk_window_set_cursor(gdk_window,cursor); - -/* - GdkDisplay *display=gdk_display_get_default(); - if(display==NULL) { - fprintf(stderr,"no default display!\n"); - _exit(0); - } - - GdkCursor *cursor=gdk_cursor_new_for_display(display,GDK_ARROW); -*/ + gdk_window_set_cursor(gdk_window,cursor_arrow); update_timer_id=gdk_threads_add_timeout(1000/updates_per_second, update, NULL); @@ -306,6 +932,10 @@ gint init(void* arg) { vfo_update(NULL); + if(protocol==ORIGINAL_PROTOCOL) { + setFrequency(getFrequency()); + } + return 0; } @@ -316,6 +946,8 @@ main (int argc, { gtk_init (&argc, &argv); + fprintf(stderr,"Build: %s %s\n",build_date,build_time); + uname(&unameData); fprintf(stderr,"sysname: %s\n",unameData.sysname); fprintf(stderr,"nodename: %s\n",unameData.nodename); @@ -330,12 +962,12 @@ main (int argc, } - //display_width=gdk_screen_get_width(screen); - //display_height=gdk_screen_get_height(screen); - display_width=800; - display_height=480; + display_width=gdk_screen_get_width(screen); + display_height=gdk_screen_get_height(screen); + + fprintf(stderr,"display_width=%d display_height=%d\n", display_width, display_height); - splash_show("splash.png", 0, display_width, display_height); + splash_show("hpsdr.png", 0, display_width, display_height); g_idle_add(init,(void *)argv[0]); diff --git a/main.h b/main.h index 1e1d955..dff0089 100644 --- a/main.h +++ b/main.h @@ -1,2 +1,21 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include extern struct utsname unameData; diff --git a/menu.c b/menu.c new file mode 100644 index 0000000..317d867 --- /dev/null +++ b/menu.c @@ -0,0 +1,532 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#include +#include +#include + +#include "band.h" +#include "discovered.h" +#include "new_protocol.h" +#include "radio.h" +#include "version.h" + +static GtkWidget *parent_window; + +static GtkWidget *box; +static GtkWidget *menu; + +static void cw_keyer_internal_cb(GtkWidget *widget, gpointer data) { + cw_keyer_internal=cw_keyer_internal==1?0:1; + cw_changed(); +} + +static void cw_keyer_speed_value_changed_cb(GtkWidget *widget, gpointer data) { + cw_keyer_speed=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + cw_changed(); +} + +static void cw_breakin_cb(GtkWidget *widget, gpointer data) { + cw_breakin=cw_breakin==1?0:1; + cw_changed(); +} + +static void cw_keyer_hang_time_value_changed_cb(GtkWidget *widget, gpointer data) { + cw_keyer_hang_time=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + cw_changed(); +} + +static void cw_keys_reversed_cb(GtkWidget *widget, gpointer data) { + cw_keys_reversed=cw_keys_reversed==1?0:1; + cw_changed(); +} + +static void cw_keyer_mode_cb(GtkWidget *widget, gpointer data) { + cw_keyer_mode=(int)data; + cw_changed(); +} + +static void vfo_divisor_value_changed_cb(GtkWidget *widget, gpointer data) { + vfo_encoder_divisor=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static void panadapter_high_value_changed_cb(GtkWidget *widget, gpointer data) { + panadapter_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static void panadapter_low_value_changed_cb(GtkWidget *widget, gpointer data) { + panadapter_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static void waterfall_high_value_changed_cb(GtkWidget *widget, gpointer data) { + waterfall_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static void waterfall_low_value_changed_cb(GtkWidget *widget, gpointer data) { + waterfall_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static void waterfall_automatic_cb(GtkWidget *widget, gpointer data) { + waterfall_automatic=waterfall_automatic==1?0:1; +} + +static void linein_cb(GtkWidget *widget, gpointer data) { + mic_linein=mic_linein==1?0:1; +} + +static void micboost_cb(GtkWidget *widget, gpointer data) { + mic_boost=mic_boost==1?0:1; +} + +static void ptt_cb(GtkWidget *widget, gpointer data) { + mic_ptt_enabled=mic_ptt_enabled==1?0:1; +} + +static void ptt_ring_cb(GtkWidget *widget, gpointer data) { + mic_ptt_tip_bias_ring=0; +} + +static void ptt_tip_cb(GtkWidget *widget, gpointer data) { + mic_ptt_tip_bias_ring=1; +} + +static void bias_cb(GtkWidget *widget, gpointer data) { + mic_bias_enabled=mic_bias_enabled==1?0:1; +} + +static void apollo_cb(GtkWidget *widget, gpointer data); + +static void alex_cb(GtkWidget *widget, gpointer data) { + if(filter_board==ALEX) { + filter_board=NONE; + } else if(filter_board==NONE) { + filter_board=ALEX; + } else if(filter_board==APOLLO) { + GtkWidget *w=(GtkWidget *)data; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), FALSE); + filter_board=ALEX; + } + + if(protocol==NEW_PROTOCOL) { + filter_board_changed(); + } +} + +static void apollo_cb(GtkWidget *widget, gpointer data) { + if(filter_board==APOLLO) { + filter_board=NONE; + } else if(filter_board==NONE) { + filter_board=APOLLO; + } else if(filter_board==ALEX) { + GtkWidget *w=(GtkWidget *)data; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), FALSE); + filter_board=APOLLO; + } + if(protocol==NEW_PROTOCOL) { + filter_board_changed(); + } +} + +static void apollo_tuner_cb(GtkWidget *widget, gpointer data) { + apollo_tuner=apollo_tuner==1?0:1; + if(protocol==NEW_PROTOCOL) { + tuner_changed(); + } +} + +static void pa_cb(GtkWidget *widget, gpointer data) { + pa=pa==1?0:1; + if(protocol==NEW_PROTOCOL) { + pa_changed(); + } +} + + +static void tx_out_of_band_cb(GtkWidget *widget, gpointer data) { + tx_out_of_band=tx_out_of_band==1?0:1; +} + +static void pa_value_changed_cb(GtkWidget *widget, gpointer data) { + BAND *band=(BAND *)data; + band->pa_calibration=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static gboolean exit_pressed_event_cb (GtkWidget *widget, + GdkEventButton *event, + gpointer data) +{ + gpio_close(); + if(protocol==ORIGINAL_PROTOCOL) { + old_protocol_stop(); + } else { + new_protocol_stop(); + } + _exit(0); +} + +static gboolean menu_pressed_event_cb (GtkWidget *widget, + GdkEventButton *event, + gpointer data) +{ + int i; + int id; + + GtkWidget *dialog=gtk_dialog_new_with_buttons("Menu",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + + + + GtkWidget *notebook=gtk_notebook_new(); + + + GtkWidget *display_label=gtk_label_new("Display"); + GtkWidget *display_grid=gtk_grid_new(); + gtk_grid_set_row_homogeneous(GTK_GRID(display_grid),TRUE); + + GtkWidget *panadapter_high_label=gtk_label_new("Panadapter High: "); + //gtk_widget_override_font(panadapter_high_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(panadapter_high_label); + gtk_grid_attach(GTK_GRID(display_grid),panadapter_high_label,0,1,1,1); + + GtkWidget *panadapter_high_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); + //gtk_widget_override_font(panadapter_high_r, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_high_r),(double)panadapter_high); + gtk_widget_show(panadapter_high_r); + gtk_grid_attach(GTK_GRID(display_grid),panadapter_high_r,1,1,1,1); + g_signal_connect(panadapter_high_r,"value_changed",G_CALLBACK(panadapter_high_value_changed_cb),NULL); + + GtkWidget *panadapter_low_label=gtk_label_new("Panadapter Low: "); + //gtk_widget_override_font(panadapter_low_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(panadapter_low_label); + gtk_grid_attach(GTK_GRID(display_grid),panadapter_low_label,0,2,1,1); + + GtkWidget *panadapter_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); + //gtk_widget_override_font(panadapter_low_r, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_low_r),(double)panadapter_low); + gtk_widget_show(panadapter_low_r); + gtk_grid_attach(GTK_GRID(display_grid),panadapter_low_r,1,2,1,1); + g_signal_connect(panadapter_low_r,"value_changed",G_CALLBACK(panadapter_low_value_changed_cb),NULL); + + GtkWidget *waterfall_automatic_label=gtk_label_new("Waterfall Automatic: "); + //gtk_widget_override_font(waterfall_automatic_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(waterfall_automatic_label); + gtk_grid_attach(GTK_GRID(display_grid),waterfall_automatic_label,0,3,1,1); + + GtkWidget *waterfall_automatic_b=gtk_check_button_new(); + //gtk_widget_override_font(waterfall_automatic_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (waterfall_automatic_b), waterfall_automatic); + gtk_widget_show(waterfall_automatic_b); + gtk_grid_attach(GTK_GRID(display_grid),waterfall_automatic_b,1,3,1,1); + g_signal_connect(waterfall_automatic_b,"toggled",G_CALLBACK(waterfall_automatic_cb),NULL); + + GtkWidget *waterfall_high_label=gtk_label_new("Waterfall High: "); + //gtk_widget_override_font(waterfall_high_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(waterfall_high_label); + gtk_grid_attach(GTK_GRID(display_grid),waterfall_high_label,0,4,1,1); + + GtkWidget *waterfall_high_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); + //gtk_widget_override_font(waterfall_high_r, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(waterfall_high_r),(double)waterfall_high); + gtk_widget_show(waterfall_high_r); + gtk_grid_attach(GTK_GRID(display_grid),waterfall_high_r,1,4,1,1); + g_signal_connect(waterfall_high_r,"value_changed",G_CALLBACK(waterfall_high_value_changed_cb),NULL); + + GtkWidget *waterfall_low_label=gtk_label_new("Waterfall Low: "); + //gtk_widget_override_font(waterfall_low_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(waterfall_low_label); + gtk_grid_attach(GTK_GRID(display_grid),waterfall_low_label,0,5,1,1); + + GtkWidget *waterfall_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); + //gtk_widget_override_font(waterfall_low_r, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(waterfall_low_r),(double)waterfall_low); + gtk_widget_show(waterfall_low_r); + gtk_grid_attach(GTK_GRID(display_grid),waterfall_low_r,1,5,1,1); + g_signal_connect(waterfall_low_r,"value_changed",G_CALLBACK(waterfall_low_value_changed_cb),NULL); + + id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),display_grid,display_label); + + + + GtkWidget *tx_label=gtk_label_new("TX"); + GtkWidget *tx_grid=gtk_grid_new(); + gtk_grid_set_row_homogeneous(GTK_GRID(tx_grid),TRUE); + gtk_grid_set_column_spacing (GTK_GRID(tx_grid),10); + + for(i=0;ititle); + //gtk_widget_override_font(band_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(band_label); + gtk_grid_attach(GTK_GRID(tx_grid),band_label,(i/6)*2,i%6,1,1); + + GtkWidget *pa_r=gtk_spin_button_new_with_range(0.0,100.0,1.0); + //gtk_widget_override_font(pa_r, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(pa_r),(double)band->pa_calibration); + gtk_widget_show(pa_r); + gtk_grid_attach(GTK_GRID(tx_grid),pa_r,((i/6)*2)+1,i%6,1,1); + g_signal_connect(pa_r,"value_changed",G_CALLBACK(pa_value_changed_cb),band); + } + + GtkWidget *tx_out_of_band_b=gtk_check_button_new_with_label("Transmit out of band"); + //gtk_widget_override_font(tx_out_of_band_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tx_out_of_band_b), tx_out_of_band); + gtk_widget_show(tx_out_of_band_b); + gtk_grid_attach(GTK_GRID(tx_grid),tx_out_of_band_b,0,7,4,1); + g_signal_connect(tx_out_of_band_b,"toggled",G_CALLBACK(tx_out_of_band_cb),NULL); + + id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),tx_grid,tx_label); + + GtkWidget *cw_label=gtk_label_new("CW"); + GtkWidget *cw_grid=gtk_grid_new(); + gtk_grid_set_row_homogeneous(GTK_GRID(cw_grid),TRUE); + + GtkWidget *cw_keyer_internal_b=gtk_check_button_new_with_label("CW Internal - Speed (WPM)"); + gtk_widget_override_font(cw_keyer_internal_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_internal_b), cw_keyer_internal); + gtk_widget_show(cw_keyer_internal_b); + gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_internal_b,0,0,1,1); + g_signal_connect(cw_keyer_internal_b,"toggled",G_CALLBACK(cw_keyer_internal_cb),NULL); + + GtkWidget *cw_keyer_speed_b=gtk_spin_button_new_with_range(1.0,60.0,1.0); + gtk_widget_override_font(cw_keyer_speed_b, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_speed_b),(double)cw_keyer_speed); + gtk_widget_show(cw_keyer_speed_b); + gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_speed_b,1,0,1,1); + g_signal_connect(cw_keyer_speed_b,"value_changed",G_CALLBACK(cw_keyer_speed_value_changed_cb),NULL); + + GtkWidget *cw_breakin_b=gtk_check_button_new_with_label("CW Break In - Delay (ms)"); + gtk_widget_override_font(cw_breakin_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_breakin_b), cw_breakin); + gtk_widget_show(cw_breakin_b); + gtk_grid_attach(GTK_GRID(cw_grid),cw_breakin_b,0,1,1,1); + g_signal_connect(cw_breakin_b,"toggled",G_CALLBACK(cw_breakin_cb),NULL); + + GtkWidget *cw_keyer_hang_time_b=gtk_spin_button_new_with_range(0.0,1000.0,1.0); + gtk_widget_override_font(cw_keyer_hang_time_b, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_hang_time_b),(double)cw_keyer_hang_time); + gtk_widget_show(cw_keyer_hang_time_b); + gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_hang_time_b,1,1,1,1); + g_signal_connect(cw_keyer_hang_time_b,"value_changed",G_CALLBACK(cw_keyer_hang_time_value_changed_cb),NULL); + + GtkWidget *cw_keyer_straight=gtk_radio_button_new_with_label(NULL,"CW KEYER STRAIGHT"); + gtk_widget_override_font(cw_keyer_straight, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_straight), cw_keyer_mode==KEYER_STRAIGHT); + gtk_widget_show(cw_keyer_straight); + gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_straight,0,2,1,1); + g_signal_connect(cw_keyer_straight,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_STRAIGHT); + + GtkWidget *cw_keyer_mode_a=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(cw_keyer_straight),"CW KEYER MODE A"); + gtk_widget_override_font(cw_keyer_mode_a, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_mode_a), cw_keyer_mode==KEYER_MODE_A); + gtk_widget_show(cw_keyer_mode_a); + gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_mode_a,0,3,1,1); + g_signal_connect(cw_keyer_mode_a,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_MODE_A); + + GtkWidget *cw_keyer_mode_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(cw_keyer_mode_a),"CW KEYER MODE B"); + gtk_widget_override_font(cw_keyer_mode_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_mode_b), cw_keyer_mode==KEYER_MODE_B); + gtk_widget_show(cw_keyer_mode_b); + gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_mode_b,0,4,1,1); + g_signal_connect(cw_keyer_mode_b,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_MODE_B); + + id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),cw_grid,cw_label); + + + GtkWidget *encoder_label=gtk_label_new("VFO Encoder"); + GtkWidget *encoder_grid=gtk_grid_new(); + gtk_grid_set_row_homogeneous(GTK_GRID(encoder_grid),TRUE); + + GtkWidget *vfo_divisor_label=gtk_label_new("Divisor: "); + gtk_widget_override_font(vfo_divisor_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(vfo_divisor_label); + gtk_grid_attach(GTK_GRID(encoder_grid),vfo_divisor_label,0,0,1,1); + + GtkWidget *vfo_divisor=gtk_spin_button_new_with_range(1.0,60.0,1.0); + gtk_widget_override_font(vfo_divisor, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(vfo_divisor),(double)vfo_encoder_divisor); + gtk_widget_show(vfo_divisor); + gtk_grid_attach(GTK_GRID(encoder_grid),vfo_divisor,1,0,1,1); + g_signal_connect(vfo_divisor,"value_changed",G_CALLBACK(vfo_divisor_value_changed_cb),NULL); + + id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),encoder_grid,encoder_label); + + GtkWidget *microphone_label=gtk_label_new("Microphone"); + GtkWidget *microphone_grid=gtk_grid_new(); + gtk_grid_set_row_homogeneous(GTK_GRID(microphone_grid),TRUE); + + GtkWidget *linein_b=gtk_check_button_new_with_label("Line In"); + //gtk_widget_override_font(linein_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linein_b), mic_linein); + gtk_widget_show(linein_b); + gtk_grid_attach(GTK_GRID(microphone_grid),linein_b,1,1,1,1); + g_signal_connect(linein_b,"toggled",G_CALLBACK(linein_cb),NULL); + + GtkWidget *micboost_b=gtk_check_button_new_with_label("Boost"); + //gtk_widget_override_font(micboost_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (micboost_b), mic_boost); + gtk_widget_show(micboost_b); + gtk_grid_attach(GTK_GRID(microphone_grid),micboost_b,1,2,1,1); + g_signal_connect(micboost_b,"toggled",G_CALLBACK(micboost_cb),NULL); + + + if((protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION) || (protocol==ORIGINAL_PROTOCOL && device==DEVICE_ORION)) { + + GtkWidget *ptt_ring_b=gtk_radio_button_new_with_label(NULL,"PTT On Ring, Mic and Bias on Tip"); + //gtk_widget_override_font(ptt_ring_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_ring_b), mic_ptt_tip_bias_ring==0); + gtk_widget_show(ptt_ring_b); + gtk_grid_attach(GTK_GRID(microphone_grid),ptt_ring_b,1,3,1,1); + g_signal_connect(ptt_ring_b,"pressed",G_CALLBACK(ptt_ring_cb),NULL); + + GtkWidget *ptt_tip_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ptt_ring_b),"PTT On Tip, Mic and Bias on Ring"); + //gtk_widget_override_font(ptt_tip_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_tip_b), mic_ptt_tip_bias_ring==1); + gtk_widget_show(ptt_tip_b); + gtk_grid_attach(GTK_GRID(microphone_grid),ptt_tip_b,1,4,1,1); + g_signal_connect(ptt_tip_b,"pressed",G_CALLBACK(ptt_tip_cb),NULL); + + GtkWidget *ptt_b=gtk_check_button_new_with_label("PTT Enabled"); + //gtk_widget_override_font(ptt_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_b), mic_ptt_enabled); + gtk_widget_show(ptt_b); + gtk_grid_attach(GTK_GRID(microphone_grid),ptt_b,1,5,1,1); + g_signal_connect(ptt_b,"toggled",G_CALLBACK(ptt_cb),NULL); + + GtkWidget *bias_b=gtk_check_button_new_with_label("BIAS Enabled"); + //gtk_widget_override_font(bias_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bias_b), mic_bias_enabled); + gtk_widget_show(bias_b); + gtk_grid_attach(GTK_GRID(microphone_grid),bias_b,1,6,1,1); + g_signal_connect(bias_b,"toggled",G_CALLBACK(bias_cb),NULL); + } + + id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),microphone_grid,microphone_label); + + GtkWidget *filters_label=gtk_label_new("Filters/PA"); + GtkWidget *filters_grid=gtk_grid_new(); + gtk_grid_set_row_homogeneous(GTK_GRID(filters_grid),TRUE); + + GtkWidget *alex_b=gtk_check_button_new_with_label("ALEX"); + //gtk_widget_override_font(alex_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (alex_b), filter_board==ALEX); + gtk_widget_show(alex_b); + gtk_grid_attach(GTK_GRID(filters_grid),alex_b,2,1,1,1); + + GtkWidget *apollo_b=gtk_check_button_new_with_label("APOLLO"); + //gtk_widget_override_font(apollo_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apollo_b), filter_board==APOLLO); + gtk_widget_show(apollo_b); + gtk_grid_attach(GTK_GRID(filters_grid),apollo_b,2,2,1,1); + + g_signal_connect(alex_b,"toggled",G_CALLBACK(alex_cb),apollo_b); + g_signal_connect(apollo_b,"toggled",G_CALLBACK(apollo_cb),alex_b); + + GtkWidget *apollo_tuner_b=gtk_check_button_new_with_label("Auto Tuner"); + //gtk_widget_override_font(apollo_tuner_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apollo_tuner_b), apollo_tuner); + gtk_widget_show(apollo_tuner_b); + gtk_grid_attach(GTK_GRID(filters_grid),apollo_tuner_b,2,3,1,1); + g_signal_connect(apollo_tuner_b,"toggled",G_CALLBACK(apollo_tuner_cb),NULL); + + GtkWidget *pa_b=gtk_check_button_new_with_label("PA"); + //gtk_widget_override_font(pa_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pa_b), pa); + gtk_widget_show(pa_b); + gtk_grid_attach(GTK_GRID(filters_grid),pa_b,2,4,1,1); + g_signal_connect(pa_b,"toggled",G_CALLBACK(pa_cb),NULL); + + id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),filters_grid,filters_label); + + + GtkWidget *exit_label=gtk_label_new("Exit"); + GtkWidget *exit_grid=gtk_grid_new(); + //gtk_grid_set_row_homogeneous(GTK_GRID(exit_grid),TRUE); + + GtkWidget *exit_button=gtk_button_new_with_label("Exit PiHPSDR"); + g_signal_connect (exit_button, "pressed", G_CALLBACK(exit_pressed_event_cb), NULL); + gtk_grid_attach(GTK_GRID(exit_grid),exit_button,0,0,1,1); + + id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),exit_grid,exit_label); + + + +/* + GtkWidget *about_label=gtk_label_new("About"); + GtkWidget *about_grid=gtk_grid_new(); + gtk_grid_set_column_homogeneous(GTK_GRID(about_grid),TRUE); + + char build[64]; + + sprintf(build,"build: %s %s",build_date, build_time); + GtkWidget *pi_label=gtk_label_new("pihpsdr by John Melton g0orx/n6lyt"); + gtk_widget_show(pi_label); + gtk_grid_attach(GTK_GRID(about_grid),pi_label,0,0,1,1); + GtkWidget *filler_label=gtk_label_new(""); + gtk_widget_show(filler_label); + gtk_grid_attach(GTK_GRID(about_grid),filler_label,0,1,1,1); + GtkWidget *build_date_label=gtk_label_new(build); + gtk_widget_show(build_date_label); + gtk_grid_attach(GTK_GRID(about_grid),build_date_label,0,2,1,1); + + id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),about_grid,about_label); +*/ + gtk_container_add(GTK_CONTAINER(content),notebook); + + GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close Dialog",GTK_RESPONSE_OK); + // gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18")); + + gtk_widget_show_all(dialog); + + int result=gtk_dialog_run(GTK_DIALOG(dialog)); + + radioSaveState(); + + gtk_widget_destroy (dialog); + + return TRUE; + +} + +GtkWidget* menu_init(int width,int height,GtkWidget *parent) { + + GdkRGBA black; + black.red=0.0; + black.green=0.0; + black.blue=0.0; + black.alpha=0.0; + + fprintf(stderr,"menu_init: width=%d height=%d\n",width,height); + + parent_window=parent; + + box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0); + gtk_widget_set_size_request (box, width, height); + gtk_widget_override_background_color(box, GTK_STATE_NORMAL, &black); + + menu=gtk_button_new_with_label("Menu"); + // gtk_widget_set_size_request (menu, width, height); + g_signal_connect (menu, "pressed", G_CALLBACK(menu_pressed_event_cb), NULL); + gtk_box_pack_start (GTK_BOX(box),menu,TRUE,TRUE,0); + + gtk_widget_show_all(box); + + return box; +} diff --git a/menu.h b/menu.h new file mode 100644 index 0000000..90f6b2d --- /dev/null +++ b/menu.h @@ -0,0 +1,21 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + + +GtkWidget* menu_init(int width,int height,GtkWidget *parent); diff --git a/meter.c b/meter.c index 2d77107..5c774bd 100644 --- a/meter.c +++ b/meter.c @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include #include #include @@ -11,6 +30,9 @@ static cairo_surface_t *meter_surface = NULL; static int meter_width; static int meter_height; +static int last_meter_type=SMETER; +static int max_level=-200; +static int max_count=0; static void meter_clear_surface (void) @@ -28,6 +50,9 @@ meter_configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, gpointer data) { +fprintf(stderr,"meter_configure_event_cb: width=%d height=%d\n", + gtk_widget_get_allocated_width (widget), + gtk_widget_get_allocated_height (widget)); if (meter_surface) cairo_surface_destroy (meter_surface); @@ -56,6 +81,7 @@ meter_draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data) { GtkWidget* meter_init(int width,int height) { +fprintf(stderr,"meter_init: width=%d height=%d\n",width,height); meter_width=width; meter_height=height; @@ -73,10 +99,11 @@ GtkWidget* meter_init(int width,int height) { } -void meter_update(int meter_type,double value,double reverse) { +void meter_update(int meter_type,double value,double reverse,double exciter) { char sf[32]; int text_location; + double offset; cairo_t *cr; cr = cairo_create (meter_surface); @@ -84,62 +111,90 @@ void meter_update(int meter_type,double value,double reverse) { cairo_set_source_rgb (cr, 0, 0, 0); cairo_paint (cr); + if(last_meter_type!=meter_type) { + last_meter_type=meter_type; + max_count=0; + if(meter_type==SMETER) { + max_level=-200; + } else { + max_level=0; + } + } + cairo_set_source_rgb(cr, 1, 1, 1); switch(meter_type) { case SMETER: // value is dBm text_location=10; + offset=5.0; cairo_select_font_face(cr, "Arial", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); double level=value+(double)get_attenuation(); if(meter_width>=114) { int db=meter_width/114; // S9+60 (9*6)+60 + if(db>2) db=2; int i; cairo_set_line_width(cr, 1.0); cairo_set_source_rgb(cr, 1, 1, 1); for(i=0;i<54;i++) { - cairo_move_to(cr,(double)(i*db),(double)meter_height-20); + cairo_move_to(cr,offset+(double)(i*db),(double)meter_height-20); if(i%18==0) { - cairo_line_to(cr,(double)(i*db),(double)(meter_height-30)); + cairo_line_to(cr,offset+(double)(i*db),(double)(meter_height-30)); } else if(i%6==0) { - cairo_line_to(cr,(double)(i*db),(double)(meter_height-25)); + cairo_line_to(cr,offset+(double)(i*db),(double)(meter_height-25)); } } cairo_stroke(cr); cairo_set_font_size(cr, 12); - cairo_move_to(cr, (double)(18*db)-3.0, (double)meter_height); + cairo_move_to(cr, offset+(double)(18*db)-3.0, (double)meter_height); cairo_show_text(cr, "3"); - cairo_move_to(cr, (double)(36*db)-3.0, (double)meter_height); + cairo_move_to(cr, offset+(double)(36*db)-3.0, (double)meter_height); cairo_show_text(cr, "6"); cairo_set_source_rgb(cr, 1, 0, 0); - cairo_move_to(cr,(double)(54*db),(double)meter_height-20); - cairo_line_to(cr,(double)(54*db),(double)(meter_height-30)); - cairo_move_to(cr,(double)(74*db),(double)meter_height-20); - cairo_line_to(cr,(double)(74*db),(double)(meter_height-30)); - cairo_move_to(cr,(double)(94*db),(double)meter_height-20); - cairo_line_to(cr,(double)(94*db),(double)(meter_height-30)); - cairo_move_to(cr,(double)(114*db),(double)meter_height-20); - cairo_line_to(cr,(double)(114*db),(double)(meter_height-30)); + cairo_move_to(cr,offset+(double)(54*db),(double)meter_height-20); + cairo_line_to(cr,offset+(double)(54*db),(double)(meter_height-30)); + cairo_move_to(cr,offset+(double)(74*db),(double)meter_height-20); + cairo_line_to(cr,offset+(double)(74*db),(double)(meter_height-30)); + cairo_move_to(cr,offset+(double)(94*db),(double)meter_height-20); + cairo_line_to(cr,offset+(double)(94*db),(double)(meter_height-30)); + cairo_move_to(cr,offset+(double)(114*db),(double)meter_height-20); + cairo_line_to(cr,offset+(double)(114*db),(double)(meter_height-30)); cairo_stroke(cr); - cairo_move_to(cr, (double)(54*db)-3.0, (double)meter_height); + cairo_move_to(cr, offset+(double)(54*db)-3.0, (double)meter_height); cairo_show_text(cr, "9"); - cairo_move_to(cr, (double)(74*db)-12.0, (double)meter_height); + cairo_move_to(cr, offset+(double)(74*db)-12.0, (double)meter_height); cairo_show_text(cr, "+20"); - cairo_move_to(cr, (double)(94*db)-9.0, (double)meter_height); + cairo_move_to(cr, offset+(double)(94*db)-9.0, (double)meter_height); cairo_show_text(cr, "+40"); - cairo_move_to(cr, (double)(114*db)-6.0, (double)meter_height); + cairo_move_to(cr, offset+(double)(114*db)-6.0, (double)meter_height); cairo_show_text(cr, "+60"); cairo_set_source_rgb(cr, 0, 1, 0); - cairo_move_to(cr,(double)((level+127.0)*db),(double)meter_height-30); - cairo_line_to(cr,(double)((level+127.0)*db),(double)(meter_height-50)); + cairo_rectangle(cr, offset+0.0, (double)(meter_height-50), (double)((level+127.0)*db), 20.0); + cairo_fill(cr); + + if(level>max_level || max_count==10) { + max_level=level; + max_count=0; + } + + if(max_level!=0) { + cairo_set_source_rgb(cr, 1, 1, 0); + cairo_move_to(cr,offset+(double)((max_level+127.0)*db),(double)meter_height-30); + cairo_line_to(cr,offset+(double)((max_level+127.0)*db),(double)(meter_height-50)); + } + + cairo_stroke(cr); - text_location=(db*114)+5; + max_count++; + + + text_location=offset+(db*114)+5; } cairo_set_font_size(cr, 16); @@ -154,18 +209,23 @@ void meter_update(int meter_type,double value,double reverse) { CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 18); - sprintf(sf,"FWD: %3.2f W",value); + if((int)value>max_level || max_count==10) { + max_level=(int)value; + max_count=0; + } + max_count++; + + sprintf(sf,"FWD: %d W",(int)max_level); cairo_move_to(cr, 10, 25); cairo_show_text(cr, sf); - // value is Watts double swr=(value+reverse)/(value-reverse); cairo_select_font_face(cr, "Arial", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 18); - sprintf(sf,"SWR: %1.2f:1",swr); + sprintf(sf,"SWR: %1.1f:1",swr); cairo_move_to(cr, 10, 45); cairo_show_text(cr, sf); diff --git a/meter.h b/meter.h index ad197d3..eb6c57b 100644 --- a/meter.h +++ b/meter.h @@ -1,6 +1,25 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #define SMETER 0 #define POWER 1 GtkWidget* meter_init(int width,int height); -void meter_update(int meter_type,double value,double reverse); +void meter_update(int meter_type,double value,double reverse,double exciter); diff --git a/mode.c b/mode.c index 98fdfa5..9b6048f 100644 --- a/mode.c +++ b/mode.c @@ -1,2 +1,21 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + char *mode_string[]={"LSB","USB","DSB","CWL","CWU","FMN","AM","DIGU","SPEC","DIGL","SAM","DRM"}; diff --git a/mode.h b/mode.h index a4766a0..154bab6 100644 --- a/mode.h +++ b/mode.h @@ -1,14 +1,6 @@ -/** -* @file mode.h -* @brief Header files for the mode functions -* @author John Melton, G0ORX/N6LYT, Doxygen Comments Dave Larsen, KV0S -* @version 0.1 -* @date 2009-04-12 -*/ -// mode.h - /* Copyright (C) -* 2009 - John Melton, G0ORX/N6LYT, Doxygen Comments Dave Larsen, KV0S +* 2015 - John Melton, G0ORX/N6LYT +* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 diff --git a/new_discovery.c b/new_discovery.c index fe4a05a..c69a10a 100644 --- a/new_discovery.c +++ b/new_discovery.c @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include #include #include @@ -17,9 +36,6 @@ #include "discovered.h" //#include "discovery.h" -int selected_device=0; -int devices=0; -DISCOVERED discovered[MAX_DEVICES]; static char interface_name[64]; static struct sockaddr_in interface_addr={0}; @@ -51,12 +67,11 @@ void print_device(int i) { } void new_discovery() { - devices=0; - selected_device=0; struct ifaddrs *addrs,*ifa; getifaddrs(&addrs); ifa = addrs; while (ifa) { + g_main_context_iteration(NULL, 0); if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) { if((ifa->ifa_flags&IFF_UP)==IFF_UP && (ifa->ifa_flags&IFF_RUNNING)==IFF_RUNNING @@ -165,7 +180,7 @@ void* new_discover_receive_thread(void* arg) { struct timeval tv; int i; - tv.tv_sec = 1; + tv.tv_sec = 2; tv.tv_usec = 0; setsockopt(discovery_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); diff --git a/new_discovery.h b/new_discovery.h index fefa81a..84b98dc 100644 --- a/new_discovery.h +++ b/new_discovery.h @@ -1,2 +1,21 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + void new_discovery(void); diff --git a/new_protocol.c b/new_protocol.c index a3b9687..dab0506 100644 --- a/new_protocol.c +++ b/new_protocol.c @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + //#define ECHO_MIC @@ -25,17 +44,20 @@ #include "channel.h" #include "discovered.h" #include "wdsp.h" +#include "mode.h" +#include "filter.h" #include "radio.h" #include "vfo.h" #include "toolbar.h" +#include "wdsp_init.h" #define PI 3.1415926535897932F -static int receiver; -static int running=0; - int data_socket; +static int receiver; +static int running; + static struct sockaddr_in base_addr; static int base_addr_length; @@ -69,21 +91,8 @@ static long general_sequence = 0; static long rx_specific_sequence = 0; static long tx_specific_sequence = 0; -static int lt2208Dither = 0; -static int lt2208Random = 0; -static int attenuation = 20; // 20dB - -static long long ddsAFrequency = 14250000; -static int filterLow=150; -static int filterHigh=2550; -static int mode=modeUSB; -static unsigned long alex_rx_antenna=0; -static unsigned long alex_tx_antenna=0; -static unsigned long alex_attenuation=0; - static int buffer_size=BUFFER_SIZE; static int fft_size=4096; -static int sampleRate=48000; static int dspRate=48000; static int outputRate=48000; @@ -94,165 +103,46 @@ static int micOutputRate=192000; static int spectrumWIDTH=800; static int SPECTRUM_UPDATES_PER_SECOND=10; -static int mox=0; -static int tune=0; static float phase = 0.0F; -static int ptt; -static int dot; -static int dash; -static int pll_locked; -static int adc_overload; -unsigned int exciter_power; -unsigned int alex_forward_power; -unsigned int alex_reverse_power; -static int supply_volts; - long response_sequence; int response; +sem_t send_high_priority_sem; int send_high_priority=0; +sem_t send_general_sem; int send_general=0; -static void initAnalyzer(int channel,int buffer_size); static void* new_protocol_thread(void* arg); static void* new_protocol_timer_thread(void* arg); -void filter_board_changed() { - send_general=1; -} - -void pa_changed() { - send_general=1; -} - -void tuner_changed() { - send_general=1; -} - -void cw_changed() { -} - -void set_attenuation(int value) { - attenuation=value; -} - -int get_attenuation() { - return attenuation; -} - -void set_alex_rx_antenna(unsigned long v) { - alex_rx_antenna=v; - send_high_priority=1; -} - -void set_alex_tx_antenna(unsigned long v) { - alex_tx_antenna=v; - send_high_priority=1; -} - -void set_alex_attenuation(unsigned long v) { - alex_attenuation=v; +void schedule_high_priority(int source) { +fprintf(stderr,"new_protocol: schedule_high_priority: source=%d\n",source); + sem_wait(&send_high_priority_sem); send_high_priority=1; + sem_post(&send_high_priority_sem); } -void setSampleRate(int rate) { - sampleRate=rate; -} - -int getSampleRate() { - return sampleRate; -} - -void setFrequency(long long f) { - ddsAFrequency=f; - send_high_priority=1; -} - -long long getFrequency() { - return ddsAFrequency; -} - -void setMode(int m) { - mode=m; - SetRXAMode(receiver, mode); - SetTXAMode(CHANNEL_TX, mode); -} - -int getMode() { - return mode; -} - -void setFilter(int low,int high) { - if(mode==modeCWL) { - filterLow=-cwPitch-low; - filterHigh=-cwPitch+high; - } else if(mode==modeCWU) { - filterLow=cwPitch-low; - filterHigh=cwPitch+high; - } else { - filterLow=low; - filterHigh=high; - } - - RXANBPSetFreqs(receiver,(double)filterLow,(double)filterHigh); - SetRXABandpassFreqs(receiver, (double)filterLow, (double)filterHigh); - SetRXASNBAOutputBandwidth(receiver, (double)filterLow, (double)filterHigh); - - SetTXABandpassFreqs(CHANNEL_TX, (double)filterLow, (double)filterHigh); -} - -int getFilterLow() { - return filterLow; -} - -int getFilterHigh() { - return filterHigh; -} - -void setMox(int state) { - if(mox!=state) { - mox=state; - send_high_priority=1; - } -} - -int getMox() { - return mox; -} - -void setTune(int state) { - if(tune!=state) { - tune=state; - send_high_priority=1; - send_general=1; - } -} - -int getTune() { - return tune; -} - -int isTransmitting() { - return ptt!=0 || mox!=0 || tune!=0; +void schedule_general() { +fprintf(stderr,"new_protocol: schedule_general\n"); + sem_wait(&send_general_sem); + send_general=1; + sem_post(&send_general_sem); } -double getDrive() { - return (double)drive/255.0; +void filter_board_changed() { + schedule_general(); } -void setDrive(double value) { - drive=(int)(value*255.0); - send_high_priority=1; +void pa_changed() { + schedule_general(); } -double getTuneDrive() { - return (double)tune_drive/255.0; +void tuner_changed() { + schedule_general(); } -void setTuneDrive(double value) { - tune_drive=(int)(value*255.0); - send_high_priority=1; +void cw_changed() { } void new_protocol_init(int rx,int pixels) { @@ -263,56 +153,8 @@ void new_protocol_init(int rx,int pixels) { fprintf(stderr,"new_protocol_init: %d\n",rx); rc=sem_init(&response_sem, 0, 0); - - fprintf(stderr,"OpenChannel %d buffer_size=%d fft_size=%d sampleRate=%d dspRate=%d outputRate=%d\n", - rx, - buffer_size, - fft_size, - sampleRate, - dspRate, - outputRate); - - OpenChannel(rx, - buffer_size, - fft_size, - sampleRate, - dspRate, - outputRate, - 0, // receive - 1, // run - 0.010, 0.025, 0.0, 0.010, 0); - - fprintf(stderr,"OpenChannel %d buffer_size=%d fft_size=%d sampleRate=%d dspRate=%d outputRate=%d\n", - CHANNEL_TX, - buffer_size, - fft_size, - micSampleRate, - micDspRate, - micOutputRate); - - OpenChannel(CHANNEL_TX, - buffer_size, - fft_size, - micSampleRate, - micDspRate, - micOutputRate, - 1, // transmit - 1, // run - 0.010, 0.025, 0.0, 0.010, 0); - - fprintf(stderr,"XCreateAnalyzer %d\n",rx); - int success; - XCreateAnalyzer(rx, &success, 262144, 1, 1, ""); - if (success != 0) { - fprintf(stderr, "XCreateAnalyzer %d failed: %d\n" ,rx,success); - } - initAnalyzer(rx,buffer_size); - - XCreateAnalyzer(CHANNEL_TX, &success, 262144, 1, 1, ""); - if (success != 0) { - fprintf(stderr, "XCreateAnalyzer CHANNEL_TX failed: %d\n" ,success); - } - initAnalyzer(CHANNEL_TX,BUFFER_SIZE); + rc=sem_init(&send_high_priority_sem, 0, 1); + rc=sem_init(&send_general_sem, 0, 1); rc=pthread_create(&new_protocol_thread_id,NULL,new_protocol_thread,NULL); if(rc != 0) { @@ -320,88 +162,8 @@ void new_protocol_init(int rx,int pixels) { exit(-1); } - SetRXAMode(rx, mode); - SetRXABandpassFreqs(rx, (double)filterLow, (double)filterHigh); - SetRXAAGCMode(rx, agc); - SetRXAAGCTop(rx,agc_gain); - - SetRXAAMDSBMode(CHANNEL_RX0, 0); - SetRXAShiftRun(CHANNEL_RX0, 0); - SetRXAEMNRgainMethod(CHANNEL_RX0, 1); - SetRXAEMNRnpeMethod(CHANNEL_RX0, 0); - SetRXAEMNRaeRun(CHANNEL_RX0, 1); - SetRXAEMNRPosition(CHANNEL_RX0, 0); - SetRXAEMNRRun(CHANNEL_RX0, 0); - SetRXAANRRun(CHANNEL_RX0, 0); - SetRXAANFRun(CHANNEL_RX0, 0); - - SetTXAMode(CHANNEL_TX, mode); - SetTXABandpassFreqs(CHANNEL_TX, (double)filterLow, (double)filterHigh); - SetTXABandpassWindow(CHANNEL_TX, 1); - SetTXABandpassRun(CHANNEL_TX, 1); - - SetTXACFIRRun(CHANNEL_TX, 1); - SetTXAEQRun(CHANNEL_TX, 0); - SetTXACTCSSRun(CHANNEL_TX, 0); - SetTXAAMSQRun(CHANNEL_TX, 0); - SetTXACompressorRun(CHANNEL_TX, 0); - SetTXAosctrlRun(CHANNEL_TX, 0); - SetTXAPreGenRun(CHANNEL_TX, 0); - SetTXAPostGenRun(CHANNEL_TX, 0); - } -static void initAnalyzer(int channel,int buffer_size) { - int flp[] = {0}; - double KEEP_TIME = 0.1; - int spur_elimination_ffts = 1; - int data_type = 1; - int fft_size = 8192; - int window_type = 4; - double kaiser_pi = 14.0; - int overlap = 2048; - int clip = 0; - int span_clip_l = 0; - int span_clip_h = 0; - int pixels=spectrumWIDTH; - int stitches = 1; - int avm = 0; - double tau = 0.001 * 120.0; - int MAX_AV_FRAMES = 60; - int display_average = MAX(2, (int) MIN((double) MAX_AV_FRAMES, (double) SPECTRUM_UPDATES_PER_SECOND * tau)); - double avb = exp(-1.0 / (SPECTRUM_UPDATES_PER_SECOND * tau)); - int calibration_data_set = 0; - double span_min_freq = 0.0; - double span_max_freq = 0.0; - - int max_w = fft_size + (int) MIN(KEEP_TIME * (double) SPECTRUM_UPDATES_PER_SECOND, KEEP_TIME * (double) fft_size * (double) SPECTRUM_UPDATES_PER_SECOND); - - fprintf(stderr,"SetAnalyzer channel=%d\n",channel); - SetAnalyzer(channel, - spur_elimination_ffts, //number of LO frequencies = number of ffts used in elimination - data_type, //0 for real input data (I only); 1 for complex input data (I & Q) - flp, //vector with one elt for each LO frequency, 1 if high-side LO, 0 otherwise - fft_size, //size of the fft, i.e., number of input samples - buffer_size, //number of samples transferred for each OpenBuffer()/CloseBuffer() - window_type, //integer specifying which window function to use - kaiser_pi, //PiAlpha parameter for Kaiser window - overlap, //number of samples each fft (other than the first) is to re-use from the previous - clip, //number of fft output bins to be clipped from EACH side of each sub-span - span_clip_l, //number of bins to clip from low end of entire span - span_clip_h, //number of bins to clip from high end of entire span - pixels, //number of pixel values to return. may be either <= or > number of bins - stitches, //number of sub-spans to concatenate to form a complete span - avm, //averaging mode - display_average, //number of spans to (moving) average for pixel result - avb, //back multiplier for weighted averaging - calibration_data_set, //identifier of which set of calibration data to use - span_min_freq, //frequency at first pixel value8192 - span_max_freq, //frequency at last pixel value - max_w //max samples to hold in input ring buffers - ); -} - - static void new_protocol_general() { unsigned char buffer[60]; @@ -446,9 +208,7 @@ static void new_protocol_high_priority(int run,int tx,int drive) { buffer[4]=run|(tx<<1); - extern long long ddsAFrequency; - - long phase=(long)((4294967296.0*(double)ddsAFrequency)/122880000.0); + long phase=(long)((4294967296.0*(double)ddsFrequency)/122880000.0); // rx buffer[9]=phase>>24; @@ -456,7 +216,7 @@ static void new_protocol_high_priority(int run,int tx,int drive) { buffer[11]=phase>>8; buffer[12]=phase; -// tx +// tx (no split yet) buffer[329]=phase>>24; buffer[330]=phase>>16; buffer[331]=phase>>8; @@ -477,15 +237,15 @@ else HPF <= 6'b000010; // 20MHz long filters=0x00000000; // set HPF - if(ddsAFrequency<1800000L) { + if(ddsFrequency<1800000L) { filters|=ALEX_BYPASS_HPF; - } else if(ddsAFrequency<6500000L) { + } else if(ddsFrequency<6500000L) { filters|=ALEX_1_5MHZ_HPF; - } else if(ddsAFrequency<9500000L) { + } else if(ddsFrequency<9500000L) { filters|=ALEX_6_5MHZ_HPF; - } else if(ddsAFrequency<13000000L) { + } else if(ddsFrequency<13000000L) { filters|=ALEX_9_5MHZ_HPF; - } else if(ddsAFrequency<20000000L) { + } else if(ddsFrequency<20000000L) { filters|=ALEX_13MHZ_HPF; } else { filters|=ALEX_20MHZ_HPF; @@ -501,17 +261,17 @@ else if (frequency > 2400000) LPF <= 7'b0000100; // > 160m so use 80m LPF else LPF <= 7'b0001000; // < 2.4MHz so use 160m LPF^M */ - if(ddsAFrequency>32000000) { + if(ddsFrequency>32000000) { filters|=ALEX_6_BYPASS_LPF; - } else if(ddsAFrequency>22000000) { + } else if(ddsFrequency>22000000) { filters|=ALEX_12_10_LPF; - } else if(ddsAFrequency>15000000) { + } else if(ddsFrequency>15000000) { filters|=ALEX_17_15_LPF; - } else if(ddsAFrequency>8000000) { + } else if(ddsFrequency>8000000) { filters|=ALEX_30_20_LPF; - } else if(ddsAFrequency>4500000) { + } else if(ddsFrequency>4500000) { filters|=ALEX_60_40_LPF; - } else if(ddsAFrequency>2400000) { + } else if(ddsFrequency>2400000) { filters|=ALEX_80_LPF; } else { filters|=ALEX_160_LPF; @@ -588,7 +348,22 @@ static void new_protocol_transmit_specific() { buffer[10]=cw_keyer_weight; // cw weight buffer[11]=cw_keyer_hang_time>>8; buffer[12]=cw_keyer_hang_time; // cw hang delay buffer[13]=0; // rf delay - buffer[50]=orion_mic; + buffer[50]=0; + if(mic_linein) { + buffer[50]|=0x01; + } + if(mic_boost) { + buffer[50]|=0x02; + } + if(mic_ptt_enabled==0) { + buffer[50]|=0x04; + } + if(mic_bias_enabled) { + buffer[50]|=0x10; + } + if(mic_ptt_tip_bias_ring) { + buffer[50]|=0x08; + } buffer[51]=0x7F; // Line in gain if(sendto(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&transmitter_addr,transmitter_addr_length)<0) { @@ -629,12 +404,12 @@ static void new_protocol_receive_specific() { buffer[17+(i*6)]=adc[i]; } - buffer[18]=((sampleRate/1000)>>8)&0xFF; - buffer[19]=(sampleRate/1000)&0xFF; + buffer[18]=((sample_rate/1000)>>8)&0xFF; + buffer[19]=(sample_rate/1000)&0xFF; buffer[22]=24; - buffer[24]=((sampleRate/1000)>>8)&0xFF; - buffer[25]=(sampleRate/1000)&0xFF; + buffer[24]=((sample_rate/1000)>>8)&0xFF; + buffer[25]=(sample_rate/1000)&0xFF; buffer[28]=24; if(sendto(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&receiver_addr,receiver_addr_length)<0) { @@ -761,7 +536,7 @@ fprintf(stderr,"new_protocol_thread: receiver=%d\n", receiver); micsamples=0; iqindex=4; - switch(sampleRate) { + switch(sample_rate) { case 48000: outputsamples=BUFFER_SIZE; break; @@ -851,7 +626,7 @@ fprintf(stderr,"outputsamples=%d\n", outputsamples); //fprintf(stderr,"samples per frame %d\n",samplesperframe); - //if(!isTransmitting()) { + if(!isTransmitting()) { b=16; for(i=0;i #include #include diff --git a/old_discovery.c b/old_discovery.c new file mode 100644 index 0000000..5b9835b --- /dev/null +++ b/old_discovery.c @@ -0,0 +1,251 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "discovered.h" +#include "old_discovery.h" + +static char interface_name[64]; +static struct sockaddr_in interface_addr={0}; +static int interface_length; + +#define DISCOVERY_PORT 1024 +static int discovery_socket; +static struct sockaddr_in discovery_addr; + +static pthread_t discover_thread_id; +static void* discover_receive_thread(void* arg); + +static void discover(struct ifaddrs* iface) { + int rc; + struct sockaddr_in *sa; + //char *addr; + + strcpy(interface_name,iface->ifa_name); + fprintf(stderr,"discover: looking for HPSDR devices on %s\n",interface_name); + + // send a broadcast to locate hpsdr boards on the network + discovery_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); + if(discovery_socket<0) { + perror("discover: create socket failed for discovery_socket\n"); + exit(-1); + } + + int optval = 1; + setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + + sa = (struct sockaddr_in *) iface->ifa_addr; + //addr = inet_ntoa(sa->sin_addr); + + // bind to this interface and the discovery port + interface_addr.sin_family = AF_INET; + interface_addr.sin_addr.s_addr = sa->sin_addr.s_addr; + interface_addr.sin_port = htons(DISCOVERY_PORT*2); + if(bind(discovery_socket,(struct sockaddr*)&interface_addr,sizeof(interface_addr))<0) { + perror("discover: bind socket failed for discovery_socket\n"); + exit(-1); + } + + fprintf(stderr,"discover: bound to %s\n",interface_name); + + // allow broadcast on the socket + int on=1; + rc=setsockopt(discovery_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); + if(rc != 0) { + fprintf(stderr,"discover: cannot set SO_BROADCAST: rc=%d\n", rc); + exit(-1); + } + + // setup to address + struct sockaddr_in to_addr={0}; + to_addr.sin_family=AF_INET; + to_addr.sin_port=htons(DISCOVERY_PORT); + to_addr.sin_addr.s_addr=htonl(INADDR_BROADCAST); + + // start a receive thread to collect discovery response packets + rc=pthread_create(&discover_thread_id,NULL,discover_receive_thread,NULL); + if(rc != 0) { + fprintf(stderr,"pthread_create failed on discover_receive_thread: rc=%d\n", rc); + exit(-1); + } + + + // send discovery packet + unsigned char buffer[63]; + buffer[0]=0xEF; + buffer[1]=0xFE; + buffer[2]=0x02; + int i; + for(i=3;i<63;i++) { + buffer[i]=0x00; + } + + if(sendto(discovery_socket,buffer,63,0,(struct sockaddr*)&to_addr,sizeof(to_addr))<0) { + perror("discover: sendto socket failed for discovery_socket\n"); + exit(-1); + } + + // wait for receive thread to complete + void* status; + pthread_join(discover_thread_id,&status); + + close(discovery_socket); + + fprintf(stderr,"discover: exiting discover for %s\n",iface->ifa_name); + +} + +static void* discover_receive_thread(void* arg) { + struct sockaddr_in addr; + int len; + unsigned char buffer[2048]; + int bytes_read; + struct timeval tv; + int i; + +fprintf(stderr,"discover_receive_thread\n"); + + tv.tv_sec = 2; + tv.tv_usec = 0; + + setsockopt(discovery_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); + + len=sizeof(addr); + while(1) { + bytes_read=recvfrom(discovery_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&addr,&len); + if(bytes_read<0) { + fprintf(stderr,"discovery: bytes read %d\n", bytes_read); + perror("discovery: recvfrom socket failed for discover_receive_thread"); + break; + } + fprintf(stderr,"discovered: received %d bytes\n",bytes_read); + if ((buffer[0] & 0xFF) == 0xEF && (buffer[1] & 0xFF) == 0xFE) { + int status = buffer[2] & 0xFF; + if (status == 2 || status == 3) { + if(devicesifa_addr && ifa->ifa_addr->sa_family == AF_INET) { + if((ifa->ifa_flags&IFF_UP)==IFF_UP + && (ifa->ifa_flags&IFF_RUNNING)==IFF_RUNNING + && (ifa->ifa_flags&IFF_LOOPBACK)!=IFF_LOOPBACK) { + discover(ifa); + } + } + ifa = ifa->ifa_next; + } + freeifaddrs(addrs); + + fprintf(stderr, "discovery found %d devices\n",devices); + + int i; + for(i=0;i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "band.h" +#include "channel.h" +#include "discovered.h" +#include "mode.h" +#include "filter.h" +#include "old_protocol.h" +#include "radio.h" +#include "toolbar.h" + +#define PI 3.1415926535897932F + +#define DATA_PORT 1024 + +#define SYNC 0x7F +#define OZY_BUFFER_SIZE 512 +#define OUTPUT_BUFFER_SIZE 1024 + +// ozy command and control +#define MOX_DISABLED 0x00 +#define MOX_ENABLED 0x01 + +#define MIC_SOURCE_JANUS 0x00 +#define MIC_SOURCE_PENELOPE 0x80 +#define CONFIG_NONE 0x00 +#define CONFIG_PENELOPE 0x20 +#define CONFIG_MERCURY 0x40 +#define CONFIG_BOTH 0x60 +#define PENELOPE_122_88MHZ_SOURCE 0x00 +#define MERCURY_122_88MHZ_SOURCE 0x10 +#define ATLAS_10MHZ_SOURCE 0x00 +#define PENELOPE_10MHZ_SOURCE 0x04 +#define MERCURY_10MHZ_SOURCE 0x08 +#define SPEED_48K 0x00 +#define SPEED_96K 0x01 +#define SPEED_192K 0x02 +#define SPEED_384K 0x03 +#define MODE_CLASS_E 0x01 +#define MODE_OTHERS 0x00 +#define ALEX_ATTENUATION_0DB 0x00 +#define ALEX_ATTENUATION_10DB 0x01 +#define ALEX_ATTENUATION_20DB 0x02 +#define ALEX_ATTENUATION_30DB 0x03 +#define LT2208_GAIN_OFF 0x00 +#define LT2208_GAIN_ON 0x04 +#define LT2208_DITHER_OFF 0x00 +#define LT2208_DITHER_ON 0x08 +#define LT2208_RANDOM_OFF 0x00 +#define LT2208_RANDOM_ON 0x10 + +static int buffer_size=BUFFER_SIZE; + +static int receiver; +static int display_width; + +static int speed; + +static int dsp_rate=48000; +static int output_rate=48000; + +static int data_socket; +static struct sockaddr_in data_addr; +static int data_addr_length; + +static int output_buffer_size; + +static unsigned char control_in[5]={0x00,0x00,0x00,0x00,0x00}; +static unsigned char control_out[5]={0x00,0x00,0x00,0x00,0x00}; + +static double tuning_phase; +static float phase=0.0f; + +static int running; +static long ep4_sequence; + +static int samples=0; + +//static float left_input_buffer[BUFFER_SIZE]; +//static float right_input_buffer[BUFFER_SIZE]; +static double iqinputbuffer[BUFFER_SIZE*2]; + +//static float mic_left_buffer[BUFFER_SIZE]; +//static float mic_right_buffer[BUFFER_SIZE]; +static double micinputbuffer[BUFFER_SIZE*2]; + +//static float left_output_buffer[OUTPUT_BUFFER_SIZE]; +//static float right_output_buffer[OUTPUT_BUFFER_SIZE]; +static double audiooutputbuffer[BUFFER_SIZE*2]; + +//static float left_subrx_output_buffer[OUTPUT_BUFFER_SIZE]; +//static float right_subrx_output_buffer[OUTPUT_BUFFER_SIZE]; + +//static float left_tx_buffer[OUTPUT_BUFFER_SIZE]; +//static float right_tx_buffer[OUTPUT_BUFFER_SIZE]; +static double micoutputbuffer[BUFFER_SIZE*2]; + +static short left_rx_sample; +static short right_rx_sample; +static short left_tx_sample; +static short right_tx_sample; + +static unsigned char output_buffer[OZY_BUFFER_SIZE]; +static int output_buffer_index=0; + +static int command=0; + +static pthread_t receive_thread_id; +static void start_receive_thread(); +static void *receive_thread(void* arg); +static void process_ozy_input_buffer(char *buffer); +static void process_bandscope_buffer(char *buffer); +void ozy_send_buffer(); + +static unsigned char metis_buffer[1032]; +static long send_sequence=-1; +static int metis_offset=8; + +static int frequencyChanged=0; +static sem_t frequency_changed_sem; + +static int metis_write(unsigned char ep,char* buffer,int length); +static void metis_start_stop(int command); +static void metis_send_buffer(char* buffer,int length); + +void schedule_frequency_changed() { +//fprintf(stderr,"old_protocol: schedule_frequency_changed\n"); + //sem_wait(&frequency_changed_sem); + frequencyChanged=1; + //sem_post(&frequency_changed_sem); +} + +static float sineWave(double* buf, int samples, float phase, float freq) { + float phase_step = 2 * PI * freq / 192000.0F; + int i; + for (i = 0; i < samples; i++) { + buf[i*2] = (double) sin(phase); + phase += phase_step; + } + return phase; +} + +static void setSpeed(int s) { + int speed=SPEED_48K; + output_buffer_size=OUTPUT_BUFFER_SIZE; + switch(s) { + case 48000: + speed=SPEED_48K; + output_buffer_size=OUTPUT_BUFFER_SIZE; + break; + case 96000: + speed=SPEED_96K; + output_buffer_size=OUTPUT_BUFFER_SIZE/2; + break; + case 192000: + speed=SPEED_192K; + output_buffer_size=OUTPUT_BUFFER_SIZE/4; + break; + case 384000: + speed=SPEED_384K; + output_buffer_size=OUTPUT_BUFFER_SIZE/8; + break; + default: + fprintf(stderr,"Invalid sample rate: %d. Defaulting to 48K.\n",s); + break; + } + + //fprintf(stderr,"setSpeed sample_rate=%d speed=%d\n",s,speed); + + control_out[1]=control_out[1]&0xFC; + control_out[1]=control_out[1]|speed; + +} + + +void old_protocol_stop() { + metis_start_stop(0); + running=FALSE; +} + +void old_protocol_init(int rx,int pixels) { + int i; + + fprintf(stderr,"old_protocol_init\n"); + + //int result=sem_init(&frequency_changed_sem, 0, 1); + + receiver=rx; + display_width=pixels; + + // setup defaults + control_out[0] = MOX_DISABLED; + control_out[1] = CONFIG_BOTH + | MERCURY_122_88MHZ_SOURCE + | MERCURY_10MHZ_SOURCE + | speed + | MIC_SOURCE_PENELOPE; + control_out[2] = MODE_OTHERS; + control_out[3] = ALEX_ATTENUATION_0DB + | LT2208_GAIN_OFF + | LT2208_DITHER_ON + | LT2208_RANDOM_ON; + control_out[4] = 0; + + setSpeed(sample_rate); + + start_receive_thread(); + + fprintf(stderr,"old_protocol_init: prime radio\n"); + for(i=8;iinterface_address,d->interface_length)<0) { + perror("old_protocol: bind socket failed for data_socket\n"); + exit(-1); + } + + memcpy(&data_addr,&d->address,d->address_length); + data_addr_length=d->address_length; + data_addr.sin_port=htons(DATA_PORT); + + rc=pthread_create(&receive_thread_id,NULL,receive_thread,NULL); + if(rc != 0) { + fprintf(stderr,"old_protocol: pthread_create failed on receive_thread: rc=%d\n", rc); + exit(-1); + } + +} + +static void *receive_thread(void* arg) { + struct sockaddr_in addr; + int length; + unsigned char buffer[2048]; + int bytes_read; + int ep; + long sequence; + + fprintf(stderr, "old_protocol: receive_thread\n"); + running=1; + + length=sizeof(addr); + while(running) { + bytes_read=recvfrom(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&addr,&length); + if(bytes_read<0) { + perror("recvfrom socket failed for old_protocol: receive_thread"); + exit(1); + } + + if(buffer[0]==0xEF && buffer[1]==0xFE) { + switch(buffer[2]) { + case 1: + // get the end point + ep=buffer[3]&0xFF; + + // get the sequence number + sequence=((buffer[4]&0xFF)<<24)+((buffer[5]&0xFF)<<16)+((buffer[6]&0xFF)<<8)+(buffer[7]&0xFF); + + switch(ep) { + case 6: // EP6 + // process the data + process_ozy_input_buffer(&buffer[8]); + process_ozy_input_buffer(&buffer[520]); + break; + case 4: // EP4 +/* + ep4_sequence++; + if(sequence!=ep4_sequence) { + ep4_sequence=sequence; + } else { + int seq=(int)(sequence%32L); + if((sequence%32L)==0L) { + reset_bandscope_buffer_index(); + } + process_bandscope_buffer(&buffer[8]); + process_bandscope_buffer(&buffer[520]); + } +*/ + break; + default: + fprintf(stderr,"unexpected EP %d length=%d\n",ep,bytes_read); + break; + } + break; + case 2: // response to a discovery packet + fprintf(stderr,"unexepected discovery response when not in discovery mode\n"); + break; + default: + fprintf(stderr,"unexpected packet type: 0x%02X\n",buffer[2]); + break; + } + } else { + fprintf(stderr,"received bad header bytes on data port %02X,%02X\n",buffer[0],buffer[1]); + } + } +} + +static void process_ozy_input_buffer(char *buffer) { + int i,j; + int b=0; + unsigned char ozy_samples[8*8]; + int bytes; + int last_ptt; + int last_dot; + int last_dash; + double gain; + int left_sample; + int right_sample; + int mic_sample; + float left_sample_float; + float right_sample_float; + float mic_sample_float; + + if(buffer[b++]==SYNC && buffer[b++]==SYNC && buffer[b++]==SYNC) { + // extract control bytes + control_in[0]=buffer[b++]; + control_in[1]=buffer[b++]; + control_in[2]=buffer[b++]; + control_in[3]=buffer[b++]; + control_in[4]=buffer[b++]; + + last_ptt=ptt; + last_dot=dot; + last_dash=dash; + ptt=(control_in[0]&0x01)==0x01; + dash=(control_in[0]&0x02)==0x02; + dot=(control_in[0]&0x04)==0x04; + + if(last_ptt!=ptt) { + g_idle_add(ptt_update,(gpointer)ptt); + } + + switch((control_in[0]>>3)&0x1F) { + case 0: + adc_overload=control_in[1]&0x01; + IO1=(control_in[1]&0x02)?0:1; + IO2=(control_in[1]&0x04)?0:1; + IO3=(control_in[1]&0x08)?0:1; + if(mercury_software_version!=control_in[2]) { + mercury_software_version=control_in[2]; + fprintf(stderr," Mercury Software version: %d (0x%0X)\n",mercury_software_version,mercury_software_version); + } + if(penelope_software_version!=control_in[3]) { + penelope_software_version=control_in[3]; + fprintf(stderr," Penelope Software version: %d (0x%0X)\n",penelope_software_version,penelope_software_version); + } + if(ozy_software_version!=control_in[4]) { + ozy_software_version=control_in[4]; + fprintf(stderr,"FPGA firmware version: %d.%d\n",ozy_software_version/10,ozy_software_version%10); + } + break; + case 1: + exciter_power=((control_in[1]&0xFF)<<8)|(control_in[2]&0xFF); // from Penelope or Hermes + alex_forward_power=((control_in[3]&0xFF)<<8)|(control_in[4]&0xFF); // from Alex or Apollo + break; + case 2: + alex_reverse_power=((control_in[1]&0xFF)<<8)|(control_in[2]&0xFF); // from Alex or Apollo + AIN3=(control_in[3]<<8)+control_in[4]; // from Pennelope or Hermes + break; + case 3: + AIN4=(control_in[1]<<8)+control_in[2]; // from Pennelope or Hermes + AIN6=(control_in[3]<<8)+control_in[4]; // from Pennelope or Hermes + break; + } + + + // extract the 63 samples + for(i=0;i<63;i++) { + + left_sample = (int)((signed char) buffer[b++]) << 16; + left_sample += (int)((unsigned char)buffer[b++]) << 8; + left_sample += (int)((unsigned char)buffer[b++]); + right_sample = (int)((signed char) buffer[b++]) << 16; + right_sample += (int)((unsigned char)buffer[b++]) << 8; + right_sample += (int)((unsigned char)buffer[b++]); + mic_sample = (int)((signed char) buffer[b++]) << 8; + mic_sample += (int)((unsigned char)buffer[b++]); +/* + left_sample = ((int)buffer[b++]) << 16; + left_sample = (((unsigned char)buffer[b++]) << 8) | left_sample; + left_sample = ((unsigned char)buffer[b++]) | left_sample; + right_sample = ((int)buffer[b++]) << 16; + right_sample = (((unsigned char)buffer[b++]) << 8) | right_sample; + right_sample = ((unsigned char)buffer[b++]) | right_sample; + mic_sample = ((int)buffer[b++]) << 8; + mic_sample = ((unsigned char)buffer[b++]) | mic_sample; +*/ + left_sample_float=(float)left_sample/8388607.0; // 24 bit sample 2^23-1 + right_sample_float=(float)right_sample/8388607.0; // 24 bit sample 2^23-1 + mic_sample_float=(float)mic_sample/32767.0f; // 16 bit sample 2^16-1 + + // add to buffer + if(isTransmitting()) { + micinputbuffer[samples*2]=(double)mic_sample_float*mic_gain; + micinputbuffer[(samples*2)+1]=(double)mic_sample_float*mic_gain; + samples++; + } else { + iqinputbuffer[samples*2]=(double)left_sample_float; + iqinputbuffer[(samples*2)+1]=(double)right_sample_float; + samples++; + } + + // when we have enough samples give them to WDSP and get the results + if(samples==buffer_size) { + int error; + if(isTransmitting()) { + if(tune) { + double tunefrequency = (double)((filterHigh - filterLow) / 2); + phase=sineWave(micinputbuffer, BUFFER_SIZE, phase, (float)tunefrequency); + } else if(mode==modeCWU || mode==modeCWL) { + } + // process the output + fexchange0(CHANNEL_TX, micinputbuffer, micoutputbuffer, &error); + if(error!=0) { + fprintf(stderr,"fexchange0 (CHANNEL_TX) returned error: %d\n", error); + } + Spectrum0(1, CHANNEL_TX, 0, 0, micoutputbuffer); + if(penelope) { + if(tune) { + gain=65535.0*255.0/(double)tune_drive; + } else { + gain=65535.0*255.0/(double)drive; + } + } else { + gain=65535.0; + } + for(j=0;j>8; + output_buffer[output_buffer_index++]=left_rx_sample; + output_buffer[output_buffer_index++]=right_rx_sample>>8; + output_buffer[output_buffer_index++]=right_rx_sample; + output_buffer[output_buffer_index++]=left_tx_sample>>8; + output_buffer[output_buffer_index++]=left_tx_sample; + output_buffer[output_buffer_index++]=right_tx_sample>>8; + output_buffer[output_buffer_index++]=right_tx_sample; + if(output_buffer_index>=OZY_BUFFER_SIZE) { + ozy_send_buffer(); + output_buffer_index=8; + } + } + } else { + // process the input + fexchange0(CHANNEL_RX0, iqinputbuffer, audiooutputbuffer, &error); + if(error!=0) { + fprintf(stderr,"fexchange2 (CHANNEL_RX0) returned error: %d\n", error); + } + Spectrum0(1, CHANNEL_RX0, 0, 0, iqinputbuffer); + for(j=0;j>8; + output_buffer[output_buffer_index++]=left_rx_sample; + output_buffer[output_buffer_index++]=right_rx_sample>>8; + output_buffer[output_buffer_index++]=right_rx_sample; + output_buffer[output_buffer_index++]=left_tx_sample>>8; + output_buffer[output_buffer_index++]=left_tx_sample; + output_buffer[output_buffer_index++]=right_tx_sample>>8; + output_buffer[output_buffer_index++]=right_tx_sample; + if(output_buffer_index>=OZY_BUFFER_SIZE) { + ozy_send_buffer(); + output_buffer_index=8; + } + } + } + samples=0; + } + } + } else { + time_t t; + struct tm* gmt; + time(&t); + gmt=gmtime(&t); + + fprintf(stderr,"%s: process_ozy_input_buffer: did not find sync\n", + asctime(gmt)); + exit(1); + } +} + +/* +static void process_bandscope_buffer(char *buffer) { +} +*/ + + +void ozy_send_buffer() { + output_buffer[0]=SYNC; + output_buffer[1]=SYNC; + output_buffer[2]=SYNC; + + switch(command) { +#ifdef EXCLUDE + case 0: + //sem_wait(&frequency_changed_sem); + if(frequencyChanged) { + // send rx frequency + output_buffer[3]=control_out[0]|0x04; + output_buffer[4]=ddsFrequency>>24; + output_buffer[5]=ddsFrequency>>16; + output_buffer[6]=ddsFrequency>>8; + output_buffer[7]=ddsFrequency; + //freqcommand++; + } else { + output_buffer[3]=control_out[0]; + output_buffer[4]=control_out[1]; + output_buffer[5]=control_out[2]; + output_buffer[6]=control_out[3]; + output_buffer[7]=control_out[4]; + } + //sem_post(&frequency_changed_sem); + break; + case 1: + // send tx frequency + output_buffer[3]=control_out[0]|0x02; +/* + if(bSplit) { + if(frequencyBChanged) { + output_buffer[3]=control_out[0]|0x02; // Penelope + output_buffer[4]=ddsBFrequency>>24; + output_buffer[5]=ddsBFrequency>>16; + output_buffer[6]=ddsBFrequency>>8; + output_buffer[7]=ddsBFrequency; + } else { + output_buffer[3]=control_out[0]; + output_buffer[4]=control_out[1]; + output_buffer[5]=control_out[2]; + output_buffer[6]=control_out[3]; + output_buffer[7]=control_out[4]; + } + } else { +*/ + //sem_wait(&frequency_changed_sem); + if(frequencyChanged) { + output_buffer[4]=ddsFrequency>>24; + output_buffer[5]=ddsFrequency>>16; + output_buffer[6]=ddsFrequency>>8; + output_buffer[7]=ddsFrequency; + } else { + output_buffer[3]=control_out[0]; + output_buffer[4]=control_out[1]; + output_buffer[5]=control_out[2]; + output_buffer[6]=control_out[3]; + output_buffer[7]=control_out[4]; + } + frequencyChanged=0; + //sem_post(&frequency_changed_sem); +/* + } +*/ +/* + frequencyBChanged=0; +*/ + break; + case 2: + output_buffer[3]=control_out[0]; + output_buffer[4]=control_out[1]; + output_buffer[5]=control_out[2]; + output_buffer[6]=control_out[3]; + output_buffer[7]=control_out[4]; + break; +#endif + + case 0: + output_buffer[3]=control_out[0]; + output_buffer[4]=control_out[1]; + output_buffer[5]=control_out[2]; + output_buffer[6]=control_out[3]; + output_buffer[7]=control_out[4]; + break; + case 1: + output_buffer[3]=control_out[0]|0x04; + output_buffer[4]=ddsFrequency>>24; + output_buffer[5]=ddsFrequency>>16; + output_buffer[6]=ddsFrequency>>8; + output_buffer[7]=ddsFrequency; + break; + case 2: + output_buffer[3]=control_out[0]|0x02; + output_buffer[4]=ddsFrequency>>24; + output_buffer[5]=ddsFrequency>>16; + output_buffer[6]=ddsFrequency>>8; + output_buffer[7]=ddsFrequency; + break; + case 3: + { + float d=(float)drive; + if(tune) { + d=(float)tune_drive; + } + BAND *band=band_get_current_band(); + d=(d/100.0F)*(float)band->pa_calibration; + + output_buffer[3]=0x12; + output_buffer[4]=(int)d; + output_buffer[5]=control_out[2]; + if(mic_boost) { + output_buffer[5]|=0x01; + } + if(mic_linein) { + output_buffer[5]|=0x02; + } + if(filter_board==APOLLO) { + output_buffer[5]|=0x2C; // board, filter ,tuner + } + if((filter_board==APOLLO) && tune && apollo_tuner) { + output_buffer[5]|=0x10; + } + output_buffer[6]=control_out[3]; + output_buffer[7]=control_out[4]; + } + break; + case 4: + // need to add orion tip/ring and bias configuration + output_buffer[3]=0x14; + output_buffer[4]=0x00; + if(mic_ptt_enabled==0) { + output_buffer[4]|=0x40; + } + if(mic_bias_enabled) { + output_buffer[4]|=0x20; + } + if(mic_ptt_tip_bias_ring) { + output_buffer[4]|=0x10; + } + output_buffer[5]=0x00; + output_buffer[6]=0x00; + output_buffer[7]=0x00; + break; + case 5: + // need to add rx attenuation and cw configuration + output_buffer[3]=0x16; + output_buffer[4]=0x00; + output_buffer[5]=0x00; + if(cw_keys_reversed!=0) { + output_buffer[5]|=0x40; + } + output_buffer[6]=cw_keyer_speed | (cw_keyer_mode<<6); + output_buffer[7]=cw_keyer_weight | (cw_keyer_spacing<<7); + break; + case 6: + // need to add tx attenuation and rx ADC selection + output_buffer[3]=0x1C; + output_buffer[4]=0x00; + output_buffer[5]=0x00; + output_buffer[6]=0x00; + output_buffer[7]=0x00; + break; + case 7: + // need to add cw configuration + output_buffer[3]=0x1E; + if(cw_keyer_internal==1) { + if(isTransmitting() || (mode!=modeCWU && mode!=modeCWL)) { + output_buffer[4]=0x00; + } else { + output_buffer[4]=0x01; + } + } else { + output_buffer[4]=0x00; + } + output_buffer[5]=cw_keyer_sidetone_volume; + output_buffer[6]=cw_keyer_ptt_delay; + output_buffer[7]=0x00; + break; + case 8: + // need to add cw configuration + output_buffer[3]=0x20; + output_buffer[4]=cw_keyer_hang_time; + output_buffer[5]=cw_keyer_hang_time>>8; + output_buffer[6]=cw_keyer_sidetone_frequency; + output_buffer[7]=cw_keyer_sidetone_frequency>>8; + break; + } + command++; + //if(command>=14) { + if(command>=8) { + command=0; + } + // set mox + output_buffer[3]|=isTransmitting(); + + metis_write(0x02,output_buffer,OZY_BUFFER_SIZE); +} + +static int metis_write(unsigned char ep,char* buffer,int length) { + int i; + + // copy the buffer over + for(i=0;i<512;i++) { + metis_buffer[i+metis_offset]=buffer[i]; + } + + if(metis_offset==8) { + metis_offset=520; + } else { + send_sequence++; + metis_buffer[0]=0xEF; + metis_buffer[1]=0xFE; + metis_buffer[2]=0x01; + metis_buffer[3]=ep; + metis_buffer[4]=(send_sequence>>24)&0xFF; + metis_buffer[5]=(send_sequence>>16)&0xFF; + metis_buffer[6]=(send_sequence>>8)&0xFF; + metis_buffer[7]=(send_sequence)&0xFF; + + // send the buffer + metis_send_buffer(&metis_buffer[0],1032); + metis_offset=8; + + } + + return length; +} + +static void metis_start_stop(int command) { + int i; + unsigned char buffer[64]; + + buffer[0]=0xEF; + buffer[1]=0xFE; + buffer[2]=0x04; // start/stop command + buffer[3]=command; // send EP6 and EP4 data (0x00=stop) + + for(i=0;i<60;i++) { + buffer[i+4]=0x00; + } + + metis_send_buffer(buffer,sizeof(buffer)); +} + +static void metis_send_buffer(char* buffer,int length) { + if(sendto(data_socket,buffer,length,0,(struct sockaddr*)&data_addr,data_addr_length)!=length) { + perror("sendto socket failed for metis_send_data\n"); + } +} + + diff --git a/old_protocol.h b/old_protocol.h new file mode 100644 index 0000000..633006b --- /dev/null +++ b/old_protocol.h @@ -0,0 +1,23 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#define BUFFER_SIZE 1024 +void old_protocol_stop(); +void old_protocol_init(int rx,int pixels); +void schedule_frequency_changed(); diff --git a/panadapter.c b/panadapter.c index 96284ef..4d50c37 100644 --- a/panadapter.c +++ b/panadapter.c @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include #include #include @@ -5,7 +24,9 @@ #include #include #include -#include "new_protocol.h" +#include "band.h" +#include "discovered.h" +#include "radio.h" #include "panadapter.h" #include "vfo.h" @@ -18,8 +39,8 @@ static gint last_x; static gboolean has_moved=FALSE; static gboolean pressed=FALSE; -static float panadapter_max=-60.0; -static float panadapter_min=-160.0; +//static float panadapter_max=-60.0; +//static float panadapter_min=-160.0; static gfloat hz_per_pixel; static gfloat filter_left; @@ -155,13 +176,17 @@ void panadapter_update(float *data,int tx) { if(panadapter_surface) { if(tx) { - saved_max=panadapter_max; - saved_min=panadapter_min; + saved_max=panadapter_high; + saved_min=panadapter_low; saved_hz_per_pixel=hz_per_pixel; - panadapter_max=30; - panadapter_min=-100; - hz_per_pixel=192000.0/(double)display_width; + panadapter_high=20; + panadapter_low=-100; + if(protocol==ORIGINAL_PROTOCOL) { + hz_per_pixel=48000.0/(double)display_width; + } else { + hz_per_pixel=192000.0/(double)display_width; + } } //clear_panadater_surface(); @@ -178,11 +203,11 @@ void panadapter_update(float *data,int tx) { cairo_fill(cr); // plot the levels - int V = (int)(panadapter_max - panadapter_min); + int V = (int)(panadapter_high - panadapter_low); int numSteps = V / 20; for (i = 1; i < numSteps; i++) { - int num = panadapter_max - i * 20; - int y = (int)floor((panadapter_max - num) * panadapter_height / V); + int num = panadapter_high - i * 20; + int y = (int)floor((panadapter_high - num) * panadapter_height / V); cairo_set_source_rgb (cr, 0, 1, 1); cairo_set_line_width(cr, 1.0); @@ -203,8 +228,9 @@ void panadapter_update(float *data,int tx) { // plot frequency markers long f; + long half=(long)getSampleRate()/2L; for(i=0;i 0) { if ((f % 20000) < (long) hz_per_pixel) { cairo_set_source_rgb (cr, 0, 1, 1); @@ -226,6 +252,25 @@ void panadapter_update(float *data,int tx) { } cairo_stroke(cr); + // band edges + long min_display=getFrequency()-half; + long max_display=getFrequency()+half; + BAND_LIMITS* bandLimits=getBandLimits(min_display,max_display); + if(bandLimits!=NULL) { + cairo_set_source_rgb (cr, 1, 0, 0); + cairo_set_line_width(cr, 2.0); + if((min_displayminFrequency)&&(max_display>bandLimits->minFrequency)) { + i=(bandLimits->minFrequency-min_display)/(long long)hz_per_pixel; + cairo_move_to(cr,(double)i,0.0); + cairo_line_to(cr,(double)i,(double)panadapter_height); + } + if((min_displaymaxFrequency)&&(max_display>bandLimits->maxFrequency)) { + i=(bandLimits->maxFrequency-min_display)/(long long)hz_per_pixel; + cairo_move_to(cr,(double)i,0.0); + cairo_line_to(cr,(double)i,(double)panadapter_height); + } + } + // cursor cairo_set_source_rgb (cr, 1, 0, 0); cairo_set_line_width(cr, 1.0); @@ -238,17 +283,17 @@ void panadapter_update(float *data,int tx) { cairo_set_line_width(cr, 1.0); double s1,s2; - samples[0]=panadapter_min-20; - samples[display_width-1]=panadapter_min-20; + samples[0]=panadapter_low-20; + samples[display_width-1]=panadapter_low-20; for(i=1;i #include #include diff --git a/property.h b/property.h index 55cd608..5056c6e 100644 --- a/property.h +++ b/property.h @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + typedef struct _PROPERTY PROPERTY; /* --------------------------------------------------------------------------*/ diff --git a/radio.c b/radio.c index 1188605..3dcff68 100644 --- a/radio.c +++ b/radio.c @@ -1,31 +1,66 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include #include #include +#include #include "radio.h" #include "agc.h" #include "band.h" #include "discovered.h" #include "property.h" +#include "new_protocol.h" char property_path[128]; +sem_t property_sem; + + +int penelope=0; +int tx_out_of_band=0; int sample_rate=48000; int filter_board=ALEX; int pa=PA_ENABLED; int apollo_tuner=0; -int panadapter_high=-80; -int panadapter_low=-160; +int display_panadapter=1; +int panadapter_high=-60; +int panadapter_low=-140; +int display_waterfall=1; int waterfall_high=-100; int waterfall_low=-150; int waterfall_automatic=1; +int display_sliders=1; +int display_toolbar=1; + double volume=0.2; double mic_gain=1.5; -int orion_mic=MIC_BOOST|ORION_MIC_PTT_ENABLED|ORION_MIC_PTT_TIP_BIAS_RING|ORION_MIC_BIAS_ENABLED; +int mic_linein=0; +int mic_boost=0; +int mic_bias_enabled=0; +int mic_ptt_enabled=0; +int mic_ptt_tip_bias_ring=0; int agc=AGC_MEDIUM; double agc_gain=60.0; @@ -49,6 +84,13 @@ int step=100; int byte_swap=0; +int lt2208Dither = 0; +int lt2208Random = 0; +int attenuation = 20; // 20dB +unsigned long alex_rx_antenna=0; +unsigned long alex_tx_antenna=0; +unsigned long alex_attenuation=0; + int cw_keys_reversed=0; // 0=disabled 1=enabled int cw_keyer_speed=12; // 1-60 WPM int cw_keyer_mode=KEYER_STRAIGHT; @@ -61,8 +103,161 @@ int cw_keyer_hang_time=300; // ms int cw_keyer_sidetone_frequency=400; // Hz int cw_breakin=1; // 0=disabled 1=enabled +int vfo_encoder_divisor=25; + +int protocol; +int device; +int ozy_software_version; +int mercury_software_version; +int penelope_software_version; +int ptt; +int dot; +int dash; +int adc_overload; +int pll_locked; +unsigned int exciter_power; +unsigned int alex_forward_power; +unsigned int alex_reverse_power; +unsigned int AIN3; +unsigned int AIN4; +unsigned int AIN6; +unsigned int IO1; +unsigned int IO2; +unsigned int IO3; +int supply_volts; +int mox; +int tune; + +long long ddsFrequency=14250000; + +void init_radio() { + int rc; + rc=sem_init(&property_sem, 0, 0); + if(rc!=0) { + fprintf(stderr,"init_radio: sem_init failed for property_sem: %d\n", rc); + exit(-1); + } + sem_post(&property_sem); +} + +void setSampleRate(int rate) { + sample_rate=rate; +} + +int getSampleRate() { + return sample_rate; +} + +void setMox(int state) { +fprintf(stderr,"setMox: protocol=%d\n", protocol); + if(mox!=state) { + mox=state; + if(protocol==NEW_PROTOCOL) { + schedule_high_priority(3); + } + } +} + +int getMox() { + return mox; +} + +void setTune(int state) { +fprintf(stderr,"setTune: protocol=%d\n", protocol); + if(tune!=state) { + tune=state; + if(protocol==NEW_PROTOCOL) { + schedule_high_priority(4); + schedule_general(); + } + } +} + +int getTune() { + return tune; +} + +int isTransmitting() { + return ptt!=0 || mox!=0 || tune!=0; +} + +void setFrequency(long long f) { +//fprintf(stderr,"setFrequency: protocol=%d f=%lld\n", protocol, f); + ddsFrequency=f; + if(protocol==NEW_PROTOCOL) { + schedule_high_priority(5); + } else { + schedule_frequency_changed(); + } +} + +long long getFrequency() { + return ddsFrequency; +} + +double getDrive() { + return (double)drive/255.0; +} + +void setDrive(double value) { +//fprintf(stderr,"setDrive: protocol=%d\n", protocol); + drive=(int)(value*255.0); + if(protocol==NEW_PROTOCOL) { + schedule_high_priority(6); + } +} + +double getTuneDrive() { + return (double)tune_drive/255.0; +} + +void setTuneDrive(double value) { +fprintf(stderr,"setTuneDrive: protocol=%d\n", protocol); + tune_drive=(int)(value*255.0); + if(protocol==NEW_PROTOCOL) { + schedule_high_priority(7); + } +} + +void set_attenuation(int value) { + attenuation=value; +} + +int get_attenuation() { + return attenuation; +} + +void set_alex_rx_antenna(unsigned long v) { + alex_rx_antenna=v; + if(protocol==NEW_PROTOCOL) { + schedule_high_priority(1); + } +} + +void set_alex_tx_antenna(unsigned long v) { + alex_tx_antenna=v; + if(protocol==NEW_PROTOCOL) { + schedule_high_priority(2); + } +} + +void set_alex_attenuation(unsigned long v) { + alex_attenuation=v; + if(protocol==NEW_PROTOCOL) { + schedule_high_priority(0); + } +} + void radioRestoreState() { char *value; + + sem_wait(&property_sem); + loadProperties(property_path); + + value=getProperty("penelope"); + if(value) penelope=atoi(value); + value=getProperty("tx_out_of_band"); + if(value) tx_out_of_band=atoi(value); value=getProperty("sample_rate"); if(value) sample_rate=atoi(value); value=getProperty("filter_board"); @@ -71,10 +266,18 @@ void radioRestoreState() { if(value) apollo_tuner=atoi(value); value=getProperty("pa"); if(value) pa=atoi(value); + value=getProperty("display_panadapter"); + if(value) display_panadapter=atoi(value); value=getProperty("panadapter_high"); if(value) panadapter_high=atoi(value); value=getProperty("panadapter_low"); if(value) panadapter_low=atoi(value); + value=getProperty("display_waterfall"); + if(value) display_waterfall=atoi(value); + value=getProperty("display_sliders"); + if(value) display_sliders=atoi(value); + value=getProperty("display_toolbar"); + if(value) display_toolbar=atoi(value); value=getProperty("waterfall_high"); if(value) waterfall_high=atoi(value); value=getProperty("waterfall_low"); @@ -83,10 +286,22 @@ void radioRestoreState() { if(value) waterfall_automatic=atoi(value); value=getProperty("volume"); if(value) volume=atof(value); + value=getProperty("drive"); + if(value) drive=atoi(value); + value=getProperty("tune_drive"); + if(value) tune_drive=atoi(value); value=getProperty("mic_gain"); if(value) mic_gain=atof(value); - value=getProperty("orion_mic"); - if(value) orion_mic=atof(value); + value=getProperty("mic_boost"); + if(value) mic_boost=atof(value); + value=getProperty("mic_linein"); + if(value) mic_linein=atof(value); + value=getProperty("mic_ptt_enabled"); + if(value) mic_ptt_enabled=atof(value); + value=getProperty("mic_bias_enabled"); + if(value) mic_bias_enabled=atof(value); + value=getProperty("mic_ptt_tip_bias_ring"); + if(value) mic_ptt_tip_bias_ring=atof(value); value=getProperty("nr"); if(value) nr=atoi(value); value=getProperty("nb"); @@ -125,13 +340,17 @@ void radioRestoreState() { if(value) cw_keyer_sidetone_frequency=atoi(value); value=getProperty("cw_breakin"); if(value) cw_breakin=atoi(value); - + value=getProperty("vfo_encoder_divisor"); + if(value) vfo_encoder_divisor=atoi(value); bandRestoreState(); + sem_post(&property_sem); } void radioSaveState() { char value[80]; + + sem_wait(&property_sem); sprintf(value,"%d",sample_rate); setProperty("sample_rate",value); sprintf(value,"%d",filter_board); @@ -140,10 +359,18 @@ void radioSaveState() { setProperty("apollo_tuner",value); sprintf(value,"%d",pa); setProperty("pa",value); + sprintf(value,"%d",display_panadapter); + setProperty("display_panadapter",value); sprintf(value,"%d",panadapter_high); setProperty("panadapter_high",value); sprintf(value,"%d",panadapter_low); setProperty("panadapter_low",value); + sprintf(value,"%d",display_waterfall); + setProperty("display_waterfall",value); + sprintf(value,"%d",display_sliders); + setProperty("display_sliders",value); + sprintf(value,"%d",display_toolbar); + setProperty("display_toolbar",value); sprintf(value,"%d",waterfall_high); setProperty("waterfall_high",value); sprintf(value,"%d",waterfall_low); @@ -154,8 +381,20 @@ void radioSaveState() { setProperty("volume",value); sprintf(value,"%f",mic_gain); setProperty("mic_gain",value); - sprintf(value,"%d",orion_mic); - setProperty("orion_mic",value); + sprintf(value,"%d",drive); + setProperty("drive",value); + sprintf(value,"%d",tune_drive); + setProperty("tune_drive",value); + sprintf(value,"%d",mic_boost); + setProperty("mic_boost",value); + sprintf(value,"%d",mic_linein); + setProperty("mic_linein",value); + sprintf(value,"%d",mic_ptt_enabled); + setProperty("mic_ptt_enabled",value); + sprintf(value,"%d",mic_bias_enabled); + setProperty("mic_bias_enabled",value); + sprintf(value,"%d",mic_ptt_tip_bias_ring); + setProperty("mic_ptt_tip_bias_ring",value); sprintf(value,"%d",nr); setProperty("nr",value); sprintf(value,"%d",nb); @@ -194,6 +433,11 @@ void radioSaveState() { setProperty("cw_keyer_sidetone_frequency",value); sprintf(value,"%d",cw_breakin); setProperty("cw_breakin",value); + sprintf(value,"%d",vfo_encoder_divisor); + setProperty("vfo_encoder_divisor",value); bandSaveState(); + + saveProperties(property_path); + sem_post(&property_sem); } diff --git a/radio.h b/radio.h index 28ef822..87d1b69 100644 --- a/radio.h +++ b/radio.h @@ -1,13 +1,43 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + + +#define NEW_MIC_IN 0x00 +#define NEW_LINE_IN 0x01 +#define NEW_MIC_BOOST 0x02 +#define NEW_ORION_MIC_PTT_ENABLED 0x00 +#define NEW_ORION_MIC_PTT_DISABLED 0x04 +#define NEW_ORION_MIC_PTT_RING_BIAS_TIP 0x00 +#define NEW_ORION_MIC_PTT_TIP_BIAS_RING 0x08 +#define NEW_ORION_MIC_BIAS_DISABLED 0x00 +#define NEW_ORION_MIC_BIAS_ENABLED 0x10 + +#define OLD_MIC_IN 0x00 +#define OLD_LINE_IN 0x02 +#define OLD_MIC_BOOST 0x01 +#define OLD_ORION_MIC_PTT_ENABLED 0x40 +#define OLD_ORION_MIC_PTT_DISABLED 0x00 +#define OLD_ORION_MIC_PTT_RING_BIAS_TIP 0x00 +#define OLD_ORION_MIC_PTT_TIP_BIAS_RING 0x08 +#define OLD_ORION_MIC_BIAS_DISABLED 0x00 +#define OLD_ORION_MIC_BIAS_ENABLED 0x20 -#define MIC_IN 0x00 -#define LINE_IN 0x01 -#define MIC_BOOST 0x02 -#define ORION_MIC_PTT_ENABLED 0x00 -#define ORION_MIC_PTT_DISABLED 0x04 -#define ORION_MIC_PTT_RING_BIAS_TIP 0x00 -#define ORION_MIC_PTT_TIP_BIAS_RING 0x08 -#define ORION_MIC_BIAS_DISABLED 0x00 -#define ORION_MIC_BIAS_ENABLED 0x10 extern char property_path[]; @@ -25,18 +55,26 @@ extern char property_path[]; #define KEYER_MODE_A 1 #define KEYER_MODE_B 2 +extern int penelope; +extern int tx_out_of_band; + extern int sample_rate; extern int filter_board; extern int pa; extern int apollo_tuner; +extern int display_panadapter; extern int panadapter_high; extern int panadapter_low; +extern int display_waterfall; extern int waterfall_high; extern int waterfall_low; extern int waterfall_automatic; +extern int display_sliders; +extern int display_toolbar; + extern double volume; extern double mic_gain; extern int agc; @@ -49,7 +87,11 @@ extern int snb; extern int cwPitch; -extern int orion_mic; +extern int mic_linein; +extern int mic_boost; +extern int mic_bias_enabled; +extern int mic_ptt_enabled; +extern int mic_ptt_tip_bias_ring; extern int tune_drive; extern int drive; @@ -63,6 +105,13 @@ extern int step; extern int byte_swap; +extern int lt2208Dither; +extern int lt2208Random; +extern int attenuation; +extern unsigned long alex_rx_antenna; +extern unsigned long alex_tx_antenna; +extern unsigned long alex_attenuation; + extern int cw_keys_reversed; extern int cw_keyer_speed; extern int cw_keyer_mode; @@ -75,6 +124,56 @@ extern int cw_keyer_hang_time; extern int cw_keyer_sidetone_frequency; extern int cw_breakin; +extern int vfo_encoder_divisor; + +extern int protocol; +extern int device; +extern int ozy_software_version; +extern int mercury_software_version; +extern int penelope_software_version; +extern int mox; +extern int tune; +extern int ptt; +extern int dot; +extern int dash; +extern int adc_overload; +extern int pll_locked; +extern unsigned int exciter_power; +extern unsigned int alex_forward_power; +extern unsigned int alex_reverse_power; +extern unsigned int IO1; +extern unsigned int IO2; +extern unsigned int IO3; +extern unsigned int AIN3; +extern unsigned int AIN4; +extern unsigned int AIN6; +extern int supply_volts; + +extern long long ddsFrequency; + +extern void init_radio(); +extern void setSampleRate(int rate); +extern int getSampleRate(); +extern void setMox(int state); +extern int getMox(); +extern void setTune(int state); +extern int getTune(); +double getDrive(); +void setDrive(double d); +double getTuneDrive(); +void setTuneDrive(double d); + +void set_attenuation(int value); +int get_attenuation(); +void set_alex_rx_antenna(unsigned long v); +void set_alex_tx_antenna(unsigned long v); +void set_alex_attenuation(unsigned long v); + +extern int isTransmitting(); + +extern void setFrequency(long long f); +extern long long getFrequency(); + extern void radioRestoreState(); extern void radioSaveState(); diff --git a/rotary_encoder.c b/rotary_encoder.c deleted file mode 100644 index 9e70db4..0000000 --- a/rotary_encoder.c +++ /dev/null @@ -1,298 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rotary_encoder.h" -#include "main.h" - -#define SYSFS_GPIO_DIR "/sys/class/gpio" - -#define RASPBERRYPI_VFO_ENCODER_A 14 -#define RASPBERRYPI_VFO_ENCODER_B 15 - -#define ODROID_VFO_ENCODER_A 108 -#define ODROID_VFO_ENCODER_B 97 -#define ODROID_VFO_ENCODER_A_PIN 23 -#define ODROID_VFO_ENCODER_B_PIN 24 - -#define AF_ENCODER_A 20 -#define AF_ENCODER_B 26 -#define AF_FUNCTION 21 - -#define RF_ENCODER_A 16 -#define RF_ENCODER_B 19 -#define RF_FUNCTION 13 - -#define FUNCTION 12 -#define BAND 6 - -static int VFO_ENCODER_A=14; -static int VFO_ENCODER_B=15; - -static int VFO_ENCODER_A_PIN=0; -static int VFO_ENCODER_B_PIN=0; - -static volatile int vfoEncoderPos; -static volatile int afEncoderPos; -static volatile int afFunction; -static volatile int rfEncoderPos; -static volatile int rfFunction; -static volatile int function; -static volatile int band; - -static void afFunctionAlert(int gpio, int level, uint32_t tick) { - afFunction=(level==0); -} - -static void rfFunctionAlert(int gpio, int level, uint32_t tick) { - rfFunction=(level==0); -} - -static void functionAlert(int gpio, int level, uint32_t tick) { - function=(level==0); -} - -static void bandAlert(int gpio, int level, uint32_t tick) { - band=(level==0); -} - -static void vfoEncoderPulse(int gpio, int level, unsigned int tick) { - static int levA=0, levB=0, lastGpio = -1; - -//fprintf(stderr,"vfoEncoderPulse:%d=%d\n",gpio,level); - if (gpio == VFO_ENCODER_A) levA = level; else levB = level; - - if (gpio != lastGpio) /* debounce */ - { - lastGpio = gpio; - - if ((gpio == VFO_ENCODER_A) && (level == 0)) - { - if (!levB) ++vfoEncoderPos; - } - else if ((gpio == VFO_ENCODER_B) && (level == 1)) - { - if (levA) --vfoEncoderPos; - } - } -} - -static void afEncoderPulse(int gpio, int level, uint32_t tick) -{ - static int levA=0, levB=0, lastGpio = -1; - - if (gpio == AF_ENCODER_A) levA = level; else levB = level; - - if (gpio != lastGpio) /* debounce */ - { - lastGpio = gpio; - - if ((gpio == AF_ENCODER_A) && (level == 0)) - { - if (!levB) ++afEncoderPos; - } - else if ((gpio == AF_ENCODER_B) && (level == 1)) - { - if (levA) --afEncoderPos; - } - } -} - -static void rfEncoderPulse(int gpio, int level, uint32_t tick) -{ - static int levA=0, levB=0, lastGpio = -1; - - if (gpio == RF_ENCODER_A) levA = level; else levB = level; - - if (gpio != lastGpio) /* debounce */ - { - lastGpio = gpio; - - if ((gpio == RF_ENCODER_A) && (level == 0)) - { - if (!levB) ++rfEncoderPos; - } - else if ((gpio == RF_ENCODER_B) && (level == 1)) - { - if (levA) --rfEncoderPos; - } - } -} - -void interruptB(void) { - vfoEncoderPulse(VFO_ENCODER_B,digitalRead(VFO_ENCODER_B_PIN),0); -} - -void interruptA(void) { - vfoEncoderPulse(VFO_ENCODER_A,digitalRead(VFO_ENCODER_A_PIN),0); -} - -int encoder_init() { - - if(strcmp(unameData.nodename,"raspberrypi")==0) { - - VFO_ENCODER_A=RASPBERRYPI_VFO_ENCODER_A; - VFO_ENCODER_B=RASPBERRYPI_VFO_ENCODER_B; - VFO_ENCODER_A_PIN=0; - VFO_ENCODER_B_PIN=0; - - fprintf(stderr,"encoder_init: VFO_ENCODER_A=%d VFO_ENCODER_B=%d\n",VFO_ENCODER_A,VFO_ENCODER_B); - - if(gpioInitialise()<0) { - fprintf(stderr,"Cannot initialize GPIO\n"); - return -1; - } - - gpioSetMode(VFO_ENCODER_A, PI_INPUT); - gpioSetMode(VFO_ENCODER_B, PI_INPUT); - gpioSetPullUpDown(VFO_ENCODER_A, PI_PUD_UP); - gpioSetPullUpDown(VFO_ENCODER_B, PI_PUD_UP); - gpioSetAlertFunc(VFO_ENCODER_A, vfoEncoderPulse); - gpioSetAlertFunc(VFO_ENCODER_B, vfoEncoderPulse); - vfoEncoderPos=0; - - - gpioSetMode(AF_FUNCTION, PI_INPUT); - gpioSetPullUpDown(AF_FUNCTION,PI_PUD_UP); - gpioSetAlertFunc(AF_FUNCTION, afFunctionAlert); - afFunction=0; - - gpioSetMode(AF_ENCODER_A, PI_INPUT); - gpioSetMode(AF_ENCODER_B, PI_INPUT); - gpioSetPullUpDown(AF_ENCODER_A, PI_PUD_OFF); - gpioSetPullUpDown(AF_ENCODER_B, PI_PUD_OFF); - gpioSetAlertFunc(AF_ENCODER_A, afEncoderPulse); - gpioSetAlertFunc(AF_ENCODER_B, afEncoderPulse); - afEncoderPos=0; - - gpioSetMode(RF_FUNCTION, PI_INPUT); - gpioSetPullUpDown(RF_FUNCTION,PI_PUD_UP); - gpioSetAlertFunc(RF_FUNCTION, rfFunctionAlert); - rfFunction=0; - - gpioSetMode(RF_ENCODER_A, PI_INPUT); - gpioSetMode(RF_ENCODER_B, PI_INPUT); - gpioSetPullUpDown(RF_ENCODER_A, PI_PUD_OFF); - gpioSetPullUpDown(RF_ENCODER_B, PI_PUD_OFF); - gpioSetAlertFunc(RF_ENCODER_A, rfEncoderPulse); - gpioSetAlertFunc(RF_ENCODER_B, rfEncoderPulse); - rfEncoderPos=0; - - gpioSetMode(FUNCTION, PI_INPUT); - gpioSetPullUpDown(FUNCTION,PI_PUD_UP); - gpioSetAlertFunc(FUNCTION, functionAlert); - - gpioSetMode(BAND, PI_INPUT); - gpioSetPullUpDown(BAND,PI_PUD_UP); - gpioSetAlertFunc(BAND, bandAlert); - - } else if(strcmp(unameData.nodename,"odroid")==0) { - - VFO_ENCODER_A=ODROID_VFO_ENCODER_A; - VFO_ENCODER_B=ODROID_VFO_ENCODER_B; - VFO_ENCODER_A_PIN=ODROID_VFO_ENCODER_A_PIN; - VFO_ENCODER_B_PIN=ODROID_VFO_ENCODER_B_PIN; - - fprintf(stderr,"encoder_init: VFO_ENCODER_A=%d VFO_ENCODER_B=%d\n",VFO_ENCODER_A,VFO_ENCODER_B); - - if (wiringPiSetup () < 0) { - printf ("Unable to setup wiringPi: %s\n", strerror (errno)); - return 1; - } - - FILE *fp; - - fp = popen("echo 97 > /sys/class/gpio/export\n", "r"); - pclose(fp); - fp = popen("echo \"in\" > /sys/class/gpio/gpio97/direction\n", "r"); - pclose(fp); - fp = popen("chmod 0666 /sys/class/gpio/gpio97/value\n", "r"); - pclose(fp); - - fp = popen("echo 108 > /sys/class/gpio/export\n", "r"); - pclose(fp); - fp = popen("echo \"in\" > /sys/class/gpio/gpio108/direction\n", "r"); - pclose(fp); - fp = popen("chmod 0666 /sys/class/gpio/gpio108/value\n", "r"); - pclose(fp); - - if ( wiringPiISR (24, INT_EDGE_BOTH, &interruptB) < 0 ) { - printf ("Unable to setup ISR: %s\n", strerror (errno)); - return 1; - } - - if ( wiringPiISR (23, INT_EDGE_BOTH, &interruptA) < 0 ) { - printf ("Unable to setup ISR: %s\n", strerror (errno)); - return 1; - } - } else { - fprintf(stderr,"Unknown nodename: %s. Rotary Encoder not enabled.\n",unameData.nodename); - return 1; - } - - - return 0; -} - -void encoder_close() { - if(strcmp(unameData.nodename,"odroid")==0) { - FILE *fp; - fp = popen("echo 97 > /sys/class/gpio/unexport\n", "r"); - pclose(fp); - fp = popen("echo 108 > /sys/class/gpio/unexport\n", "r"); - pclose(fp); - } -} - -int vfo_encoder_get_pos() { - int pos=vfoEncoderPos; - - if(strcmp(unameData.nodename,"raspberrypi")==0) { - if(pos<0 && pos>-12) { - pos=0; - } else if(pos>0 && pos<12) { - pos=0; - } - pos=pos/12; - vfoEncoderPos=vfoEncoderPos-(pos*12); - } else if(strcmp(unameData.nodename,"odroid")==0) { - vfoEncoderPos=0; - } - return pos; -} - -int af_encoder_get_pos() { - int pos=afEncoderPos; - afEncoderPos=0; - return pos; -} - -int af_function_get_state() { - return afFunction; -} - -int rf_encoder_get_pos() { - int pos=rfEncoderPos; - rfEncoderPos=0; - return pos; -} - -int rf_function_get_state() { - return rfFunction; -} - -int function_get_state() { - return function; -} - -int band_get_state() { - return band; -} diff --git a/rotary_encoder.h b/rotary_encoder.h deleted file mode 100644 index 604feb1..0000000 --- a/rotary_encoder.h +++ /dev/null @@ -1,6 +0,0 @@ -int encoder_init(); -void encoder_close(); -int vfo_encoder_get_pos(); -int af_encoder_get_pos(); -int af_function_get_state(); - diff --git a/splash.c b/splash.c index 53c7909..a231547 100644 --- a/splash.c +++ b/splash.c @@ -1,6 +1,28 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include +#include "version.h" GtkWidget *splash_window; +GtkWidget *status; +static cairo_surface_t *splash_surface = NULL; /* Close the splash screen */ void splash_close() @@ -8,16 +30,70 @@ void splash_close() gtk_widget_destroy(splash_window); } +static gboolean splash_configure_event_cb (GtkWidget *widget, + GdkEventConfigure *event, + gpointer data) +{ + if (splash_surface) + cairo_surface_destroy (splash_surface); + + splash_surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget), + CAIRO_CONTENT_COLOR, + gtk_widget_get_allocated_width (widget), + gtk_widget_get_allocated_height (widget)); + + return TRUE; +} + void splash_show(char* image_name,int time,int width,int height) { GtkWidget *image; splash_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_fullscreen(GTK_WINDOW(splash_window)); gtk_widget_set_size_request(splash_window, width, height); gtk_window_set_decorated(GTK_WINDOW(splash_window), FALSE); gtk_window_set_position(GTK_WINDOW(splash_window),GTK_WIN_POS_CENTER_ALWAYS); gtk_window_set_resizable(GTK_WINDOW(splash_window), FALSE); + + + GtkWidget *grid = gtk_grid_new(); + gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE); + gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE); + image=gtk_image_new_from_file(image_name); - gtk_container_add(GTK_CONTAINER(splash_window), image); + //gtk_container_add(GTK_CONTAINER(splash_window), image); + gtk_grid_attach(GTK_GRID(grid), image, 0, 0, 1, 4); + g_signal_connect (splash_window,"configure-event", + G_CALLBACK (splash_configure_event_cb), NULL); + + char build[64]; + sprintf(build,"build: %s %s",build_date, build_time); + + GtkWidget *pi_label=gtk_label_new("pihpsdr by John Melton g0orx/n6lyt"); + gtk_label_set_justify(GTK_LABEL(pi_label),GTK_JUSTIFY_LEFT); + gtk_widget_show(pi_label); + gtk_grid_attach(GTK_GRID(grid),pi_label,1,0,1,1); + GtkWidget *build_date_label=gtk_label_new(build); + gtk_label_set_justify(GTK_LABEL(build_date_label),GTK_JUSTIFY_LEFT); + gtk_widget_show(build_date_label); + gtk_grid_attach(GTK_GRID(grid),build_date_label,1,1,1,1); + + status=gtk_label_new(""); + gtk_label_set_justify(GTK_LABEL(status),GTK_JUSTIFY_LEFT); + gtk_widget_override_font(status, pango_font_description_from_string("Arial 18")); + gtk_widget_show(status); + //gtk_container_add(GTK_CONTAINER(splash_window), status); + gtk_grid_attach(GTK_GRID(grid), status, 1, 3, 1, 1); + + gtk_container_add(GTK_CONTAINER(splash_window), grid); gtk_widget_show_all (splash_window); } + +void splash_status(char *text) { + fprintf(stderr,"splash_status: %s\n",text); + gtk_label_set_text(GTK_LABEL(status),text); + usleep(50000); + while (gtk_events_pending ()) + gtk_main_iteration (); +} diff --git a/splash.h b/splash.h index 5adb9ef..b366305 100644 --- a/splash.h +++ b/splash.h @@ -1,5 +1,25 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + extern GtkWidget* splash_window; void splash_close(void); -void splash_show(char* image_name,int time,int width,int height); +void splash_show(char *image_name,int time,int width,int height); +void splash_status(char *text); diff --git a/splash.png b/splash.png deleted file mode 100644 index 4b249eb..0000000 Binary files a/splash.png and /dev/null differ diff --git a/toolbar.c b/toolbar.c index 048ad04..95688c3 100644 --- a/toolbar.c +++ b/toolbar.c @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include #include #include @@ -5,11 +24,11 @@ #include "toolbar.h" #include "mode.h" #include "filter.h" +#include "frequency.h" #include "bandstack.h" #include "band.h" #include "discovered.h" #include "new_protocol.h" -#include "rotary_encoder.h" #include "vfo.h" #include "alex.h" #include "agc.h" @@ -21,25 +40,37 @@ static int width; static int height; -static int column=0; - static GtkWidget *parent_window; +static GtkWidget *sliders; static GtkWidget *toolbar; -static GtkWidget *toolbar_bottom; -static GtkWidget *toolbar_top; static GtkWidget *last_band; static GtkWidget *last_mode; static GtkWidget *last_filter; +#define NONE 0 +#define AF_GAIN 1 +#define MIC_GAIN 2 +#define AGC_GAIN 3 +#define DRIVE 4 +#define TUNE_DRIVE 5 + +#define MIC_GAIN_FUDGE 25.0 + +static gint scale_timer; +static int scale_status=NONE; +static GtkWidget *scale_dialog; static GtkWidget *af_gain_label; -static GtkWidget *audio_scale; +static GtkWidget *af_gain_scale; static GtkWidget *agc_gain_label; static GtkWidget *agc_scale; static GtkWidget *mic_gain_label; -static GtkWidget *mic_scale; +static GtkWidget *mic_gain_scale; +static GtkWidget *drive_label; static GtkWidget *drive_scale; +static GtkWidget *tune_label; static GtkWidget *tune_scale; +static GtkWidget *dummy_label; static GdkRGBA white; static GdkRGBA gray; @@ -57,17 +88,20 @@ static void band_select_cb(GtkWidget *widget, gpointer data) { last_band=widget; gtk_widget_override_background_color(last_band, GTK_STATE_NORMAL, &gray); } - setFrequency(entry->frequencyA); setMode(entry->mode); FILTER* band_filters=filters[entry->mode]; FILTER* band_filter=&band_filters[entry->filter]; setFilter(band_filter->low,band_filter->high); + setFrequency(entry->frequencyA); BAND *band=band_get_current_band(); set_alex_rx_antenna(band->alexRxAntenna); set_alex_tx_antenna(band->alexTxAntenna); set_alex_attenuation(band->alexAttenuation); + vfo_update(NULL); + + setFrequency(entry->frequencyA); } static void band_cb(GtkWidget *widget, gpointer data) { @@ -82,7 +116,7 @@ static void band_cb(GtkWidget *widget, gpointer data) { BAND* band=band_get_band(i); GtkWidget *b=gtk_button_new_with_label(band->title); gtk_widget_override_background_color(b, GTK_STATE_NORMAL, &white); - gtk_widget_override_font(b, pango_font_description_from_string("Arial 20")); + //gtk_widget_override_font(b, pango_font_description_from_string("Arial 20")); if(i==band_get_current()) { gtk_widget_override_background_color(b, GTK_STATE_NORMAL, &gray); last_band=b; @@ -95,7 +129,7 @@ static void band_cb(GtkWidget *widget, gpointer data) { gtk_container_add(GTK_CONTAINER(content),grid); GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK); - gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20")); + //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20")); gtk_widget_show_all(dialog); g_signal_connect_swapped (dialog, @@ -140,14 +174,14 @@ static void mode_cb(GtkWidget *widget, gpointer data) { } else { gtk_widget_override_background_color(b, GTK_STATE_NORMAL, &white); } - gtk_widget_override_font(b, pango_font_description_from_string("Arial 20")); + //gtk_widget_override_font(b, pango_font_description_from_string("Arial 20")); gtk_widget_show(b); gtk_grid_attach(GTK_GRID(grid),b,i%5,i/5,1,1); g_signal_connect(b,"pressed",G_CALLBACK(mode_select_cb),(gpointer *)i); } gtk_container_add(GTK_CONTAINER(content),grid); GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK); - gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20")); + //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20")); gtk_widget_show_all(dialog); g_signal_connect_swapped (dialog, @@ -187,7 +221,7 @@ static void filter_cb(GtkWidget *widget, gpointer data) { for(i=0;ifilter) { gtk_widget_override_background_color(b, GTK_STATE_NORMAL, &gray); last_filter=b; @@ -200,7 +234,7 @@ static void filter_cb(GtkWidget *widget, gpointer data) { } gtk_container_add(GTK_CONTAINER(content),grid); GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK); - gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20")); + //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20")); gtk_widget_show_all(dialog); g_signal_connect_swapped (dialog, @@ -212,33 +246,129 @@ static void filter_cb(GtkWidget *widget, gpointer data) { } +int scale_timeout_cb(gpointer data) { +fprintf(stderr,"scale_timeout_cb\n"); + gtk_widget_destroy(scale_dialog); + scale_status=NONE; + return FALSE; +} + static void agc_select_cb(GtkWidget *widget, gpointer data) { agc=(int)data; SetRXAAGCMode(CHANNEL_RX0, agc); } static void agcgain_value_changed_cb(GtkWidget *widget, gpointer data) { - agc_gain=gtk_range_get_value(GTK_RANGE(widget)); + agc_gain=gtk_range_get_value(GTK_RANGE(agc_scale)); SetRXAAGCTop(CHANNEL_RX0, agc_gain); } void set_agc_gain(double value) { - agc_gain=value; + agc_gain=value; + SetRXAAGCTop(CHANNEL_RX0, agc_gain); + if(display_sliders) { gtk_range_set_value (GTK_RANGE(agc_scale),agc_gain); - SetRXAAGCTop(CHANNEL_RX0, agc_gain); + } else { + if(scale_status!=AGC_GAIN) { + if(scale_status!=NONE) { + g_source_remove(scale_timer); + gtk_widget_destroy(scale_dialog); + scale_status=NONE; + } + } + if(scale_status==NONE) { + scale_status=AGC_GAIN; + scale_dialog=gtk_dialog_new_with_buttons("AGC Gain",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog)); + agc_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 120.0, 1.00); + gtk_widget_set_size_request (agc_scale, 400, 30); + gtk_range_set_value (GTK_RANGE(agc_scale),agc_gain); + gtk_widget_show(agc_scale); + gtk_container_add(GTK_CONTAINER(content),agc_scale); + scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); + //gtk_widget_show_all(scale_dialog); + int result=gtk_dialog_run(GTK_DIALOG(scale_dialog)); + } else { + g_source_remove(scale_timer); + gtk_range_set_value (GTK_RANGE(agc_scale),agc_gain); + scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); + } + } } static void afgain_value_changed_cb(GtkWidget *widget, gpointer data) { - volume=gtk_range_get_value(GTK_RANGE(widget)); + volume=gtk_range_get_value(GTK_RANGE(af_gain_scale))/100.0; } void set_af_gain(double value) { - volume=value; - gtk_range_set_value (GTK_RANGE(audio_scale),volume); + volume=value; + if(display_sliders) { + gtk_range_set_value (GTK_RANGE(af_gain_scale),volume*100.0); + } else { + if(scale_status!=AF_GAIN) { + if(scale_status!=NONE) { + g_source_remove(scale_timer); + gtk_widget_destroy(scale_dialog); + scale_status=NONE; + } + } + if(scale_status==NONE) { + scale_status=AF_GAIN; + scale_dialog=gtk_dialog_new_with_buttons("AF Gain",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog)); + af_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00); + gtk_widget_set_size_request (af_gain_scale, 400, 30); + gtk_range_set_value (GTK_RANGE(af_gain_scale),volume*100.0); + gtk_widget_show(af_gain_scale); + gtk_container_add(GTK_CONTAINER(content),af_gain_scale); + scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); + //gtk_widget_show_all(scale_dialog); + int result=gtk_dialog_run(GTK_DIALOG(scale_dialog)); + } else { + g_source_remove(scale_timer); + gtk_range_set_value (GTK_RANGE(af_gain_scale),volume*100.0); + scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); + } + } } static void micgain_value_changed_cb(GtkWidget *widget, gpointer data) { - mic_gain=gtk_range_get_value(GTK_RANGE(widget)); + mic_gain=gtk_range_get_value(GTK_RANGE(widget))/MIC_GAIN_FUDGE; +fprintf(stderr,"micgain_value_changed: %f\n",mic_gain); +} + +void set_mic_gain(double value) { + mic_gain=value; +fprintf(stderr,"set_mic_gain: %f\n",mic_gain); + if(display_sliders) { + gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain*MIC_GAIN_FUDGE); + } else { + if(scale_status!=MIC_GAIN) { + if(scale_status!=NONE) { + g_source_remove(scale_timer); + gtk_widget_destroy(scale_dialog); + scale_status=NONE; + } + } + if(scale_status==NONE) { + scale_status=MIC_GAIN; + scale_dialog=gtk_dialog_new_with_buttons("Mic Gain",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog)); + mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00); + gtk_widget_set_size_request (mic_gain_scale, 400, 30); + gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain*MIC_GAIN_FUDGE); + gtk_widget_show(mic_gain_scale); + gtk_container_add(GTK_CONTAINER(content),mic_gain_scale); + scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); + //gtk_widget_show_all(scale_dialog); + int result=gtk_dialog_run(GTK_DIALOG(scale_dialog)); + } else { + g_source_remove(scale_timer); + gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain*MIC_GAIN_FUDGE); + scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); + } + + } } static void nr_cb(GtkWidget *widget, gpointer data) { @@ -261,50 +391,6 @@ static void snb_cb(GtkWidget *widget, gpointer data) { SetRXASNBARun(CHANNEL_RX0, snb); } -static void linein_cb(GtkWidget *widget, gpointer data) { - if((orion_mic&0x01)==LINE_IN) { - orion_mic=orion_mic&0xFE; - } else { - orion_mic=orion_mic|LINE_IN; - } -} - -static void micboost_cb(GtkWidget *widget, gpointer data) { - if((orion_mic&0x02)==MIC_BOOST) { - orion_mic=orion_mic&0xFD; - } else { - orion_mic=orion_mic|MIC_BOOST; - } -} - -static void byteswap_cb(GtkWidget *widget, gpointer data) { - byte_swap=byte_swap?0:1; -} - -static void ptt_cb(GtkWidget *widget, gpointer data) { - if((orion_mic&0x04)==ORION_MIC_PTT_ENABLED) { - orion_mic=orion_mic|ORION_MIC_PTT_DISABLED; - } else { - orion_mic=orion_mic&0xFB; - } -} - -static void ptt_ring_cb(GtkWidget *widget, gpointer data) { - if((orion_mic&0x08)==ORION_MIC_PTT_RING_BIAS_TIP) { - orion_mic=orion_mic|ORION_MIC_PTT_TIP_BIAS_RING; - } else { - orion_mic=orion_mic&0xF7; - } -} - -static void bias_cb(GtkWidget *widget, gpointer data) { - if((orion_mic&0x10)==ORION_MIC_BIAS_DISABLED) { - orion_mic=orion_mic|ORION_MIC_BIAS_ENABLED; - } else { - orion_mic=orion_mic&0xEF; - } -} - static void audio_cb(GtkWidget *widget, gpointer data) { GtkWidget *dialog=gtk_dialog_new_with_buttons("Audio",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); @@ -315,35 +401,35 @@ static void audio_cb(GtkWidget *widget, gpointer data) { gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); GtkWidget *b_off=gtk_radio_button_new_with_label(NULL,"Off"); - gtk_widget_override_font(b_off, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(b_off, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_off), agc==AGC_OFF); gtk_widget_show(b_off); gtk_grid_attach(GTK_GRID(grid),b_off,0,0,2,1); g_signal_connect(b_off,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_OFF); GtkWidget *b_long=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_off),"Long"); - gtk_widget_override_font(b_long, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(b_long, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_long), agc==AGC_LONG); gtk_widget_show(b_long); gtk_grid_attach(GTK_GRID(grid),b_long,0,1,2,1); g_signal_connect(b_long,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_LONG); GtkWidget *b_slow=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_long),"Slow"); - gtk_widget_override_font(b_slow, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(b_slow, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_slow), agc==AGC_SLOW); gtk_widget_show(b_slow); gtk_grid_attach(GTK_GRID(grid),b_slow,0,2,2,1); g_signal_connect(b_slow,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_SLOW); GtkWidget *b_medium=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_slow),"Medium"); - gtk_widget_override_font(b_medium, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(b_medium, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_medium), agc==AGC_MEDIUM); gtk_widget_show(b_medium); gtk_grid_attach(GTK_GRID(grid),b_medium,0,3,2,1); g_signal_connect(b_medium,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_MEDIUM); GtkWidget *b_fast=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_medium),"Fast"); - gtk_widget_override_font(b_fast, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(b_fast, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_fast), agc==AGC_FAST); gtk_widget_show(b_fast); gtk_grid_attach(GTK_GRID(grid),b_fast,0,4,2,1); @@ -351,28 +437,28 @@ static void audio_cb(GtkWidget *widget, gpointer data) { GtkWidget *b_nr=gtk_check_button_new_with_label("NR"); - gtk_widget_override_font(b_nr, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(b_nr, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr), nr==1); gtk_widget_show(b_nr); gtk_grid_attach(GTK_GRID(grid),b_nr,2,0,2,1); g_signal_connect(b_nr,"toggled",G_CALLBACK(nr_cb),NULL); GtkWidget *b_nb=gtk_check_button_new_with_label("NB"); - gtk_widget_override_font(b_nb, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(b_nb, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nb), nb==1); gtk_widget_show(b_nb); gtk_grid_attach(GTK_GRID(grid),b_nb,2,1,2,1); g_signal_connect(b_nb,"toggled",G_CALLBACK(nb_cb),NULL); GtkWidget *b_anf=gtk_check_button_new_with_label("ANF"); - gtk_widget_override_font(b_anf, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(b_anf, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_anf), anf==1); gtk_widget_show(b_anf); gtk_grid_attach(GTK_GRID(grid),b_anf,2,2,2,1); g_signal_connect(b_anf,"toggled",G_CALLBACK(anf_cb),NULL); - GtkWidget *b_snb=gtk_check_button_new_with_label("SNB"); - gtk_widget_override_font(b_snb, pango_font_description_from_string("Arial 18")); + GtkWidget *b_snb=gtk_check_button_new_with_label("NR2"); + //gtk_widget_override_font(b_snb, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_snb), snb==1); gtk_widget_show(b_snb); gtk_grid_attach(GTK_GRID(grid),b_snb,2,3,2,1); @@ -380,7 +466,7 @@ static void audio_cb(GtkWidget *widget, gpointer data) { gtk_container_add(GTK_CONTAINER(content),grid); GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK); - gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 16")); gtk_widget_show_all(dialog); g_signal_connect_swapped (dialog, @@ -394,29 +480,92 @@ static void audio_cb(GtkWidget *widget, gpointer data) { void set_drive(double value) { setDrive(value); - gtk_range_set_value (GTK_RANGE(drive_scale),value); + if(display_sliders) { + gtk_range_set_value (GTK_RANGE(drive_scale),value*100.0); + } else { + if(scale_status!=DRIVE) { + if(scale_status!=NONE) { + g_source_remove(scale_timer); + gtk_widget_destroy(scale_dialog); + scale_status=NONE; + } + } + if(scale_status==NONE) { + scale_status=DRIVE; + scale_dialog=gtk_dialog_new_with_buttons("Drive",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog)); + drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00); + gtk_widget_set_size_request (drive_scale, 400, 30); + gtk_range_set_value (GTK_RANGE(drive_scale),value*100.0); + gtk_widget_show(drive_scale); + gtk_container_add(GTK_CONTAINER(content),drive_scale); + scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); + //gtk_widget_show_all(scale_dialog); + int result=gtk_dialog_run(GTK_DIALOG(scale_dialog)); + } else { + g_source_remove(scale_timer); + gtk_range_set_value (GTK_RANGE(drive_scale),value*100.0); + scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); + } + } } static void drive_value_changed_cb(GtkWidget *widget, gpointer data) { - setDrive(gtk_range_get_value(GTK_RANGE(widget))); + setDrive(gtk_range_get_value(GTK_RANGE(drive_scale))/100.0); } void set_tune(double value) { setTuneDrive(value); - gtk_range_set_value (GTK_RANGE(tune_scale),value); + if(display_sliders) { + gtk_range_set_value (GTK_RANGE(tune_scale),value*100.0); + } else { + if(scale_status!=TUNE_DRIVE) { + if(scale_status!=NONE) { + g_source_remove(scale_timer); + gtk_widget_destroy(scale_dialog); + scale_status=NONE; + } + } + if(scale_status==NONE) { + scale_status=TUNE_DRIVE; + scale_dialog=gtk_dialog_new_with_buttons("Tune Drive",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog)); + tune_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00); + gtk_widget_set_size_request (tune_scale, 400, 30); + gtk_range_set_value (GTK_RANGE(tune_scale),value*100.0); + gtk_widget_show(tune_scale); + gtk_container_add(GTK_CONTAINER(content),tune_scale); + scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); + //gtk_widget_show_all(scale_dialog); + int result=gtk_dialog_run(GTK_DIALOG(scale_dialog)); + } else { + g_source_remove(scale_timer); + gtk_range_set_value (GTK_RANGE(tune_scale),value*100.0); + scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); + } + } } static void tune_value_changed_cb(GtkWidget *widget, gpointer data) { - setTuneDrive(gtk_range_get_value(GTK_RANGE(widget))); + setTuneDrive(gtk_range_get_value(GTK_RANGE(tune_scale))/100.0); +} + +static void stop() { + if(protocol==ORIGINAL_PROTOCOL) { + old_protocol_stop(); + } else { + new_protocol_stop(); + } + gpio_close(); } static void yes_cb(GtkWidget *widget, gpointer data) { - encoder_close(); + stop(); _exit(0); } static void halt_cb(GtkWidget *widget, gpointer data) { - encoder_close(); + stop(); system("shutdown -h -P now"); _exit(0); } @@ -424,9 +573,8 @@ static void halt_cb(GtkWidget *widget, gpointer data) { static void exit_cb(GtkWidget *widget, gpointer data) { radioSaveState(); - saveProperties(property_path); - GtkWidget *dialog=gtk_dialog_new_with_buttons("Audio",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + GtkWidget *dialog=gtk_dialog_new_with_buttons("Exit",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); GtkWidget *grid=gtk_grid_new(); @@ -435,25 +583,25 @@ static void exit_cb(GtkWidget *widget, gpointer data) { gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); GtkWidget *label=gtk_label_new("Exit?"); - gtk_widget_override_font(label, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(label, pango_font_description_from_string("Arial 18")); gtk_widget_show(label); gtk_grid_attach(GTK_GRID(grid),label,1,0,1,1); - GtkWidget *b_yes=gtk_button_new_with_label("Yes (to CLI)"); - gtk_widget_override_font(b_yes, pango_font_description_from_string("Arial 18")); + GtkWidget *b_yes=gtk_button_new_with_label("Yes"); + //gtk_widget_override_font(b_yes, pango_font_description_from_string("Arial 18")); gtk_widget_show(b_yes); gtk_grid_attach(GTK_GRID(grid),b_yes,0,1,1,1); g_signal_connect(b_yes,"pressed",G_CALLBACK(yes_cb),NULL); GtkWidget *b_halt=gtk_button_new_with_label("Halt System"); - gtk_widget_override_font(b_halt, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(b_halt, pango_font_description_from_string("Arial 18")); gtk_widget_show(b_halt); gtk_grid_attach(GTK_GRID(grid),b_halt,2,1,1,1); g_signal_connect(b_halt,"pressed",G_CALLBACK(halt_cb),NULL); gtk_container_add(GTK_CONTAINER(content),grid); GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Cancel",GTK_RESPONSE_OK); - gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18")); gtk_widget_show_all(dialog); g_signal_connect_swapped (dialog, @@ -465,52 +613,6 @@ static void exit_cb(GtkWidget *widget, gpointer data) { } -static void apollo_cb(GtkWidget *widget, gpointer data); - -static void alex_cb(GtkWidget *widget, gpointer data) { -fprintf(stderr,"alex_cb\n"); - if(filter_board==ALEX) { -fprintf(stderr,"alex_cb: was ALEX setting NONE\n"); - filter_board=NONE; - } else if(filter_board==NONE) { -fprintf(stderr,"alex_cb: was NONE setting ALEX\n"); - filter_board=ALEX; - } else if(filter_board==APOLLO) { -fprintf(stderr,"alex_cb: was APOLLO setting ALEX\n"); - GtkWidget *w=(GtkWidget *)data; - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), FALSE); - filter_board=ALEX; - } - filter_board_changed(); -} - -static void apollo_cb(GtkWidget *widget, gpointer data) { -fprintf(stderr,"apollo_cb\n"); - if(filter_board==APOLLO) { -fprintf(stderr,"apollo_cb: was APOLLO setting NONE\n"); - filter_board=NONE; - } else if(filter_board==NONE) { -fprintf(stderr,"apollo_cb: was NONE setting APOLLO\n"); - filter_board=APOLLO; - } else if(filter_board==ALEX) { -fprintf(stderr,"apollo_cb: was ALEX setting APOLLO\n"); - GtkWidget *w=(GtkWidget *)data; - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), FALSE); - filter_board=APOLLO; - } - filter_board_changed(); -} - -static void apollo_tuner_cb(GtkWidget *widget, gpointer data) { - apollo_tuner=apollo_tuner==1?0:1; - tuner_changed(); -} - -static void pa_cb(GtkWidget *widget, gpointer data) { - pa=pa==1?0:1; - pa_changed(); -} - static void cw_keyer_internal_cb(GtkWidget *widget, gpointer data) { cw_keyer_internal=cw_keyer_internal==1?0:1; cw_changed(); @@ -541,6 +643,30 @@ static void cw_keyer_mode_cb(GtkWidget *widget, gpointer data) { cw_changed(); } +static void vfo_divisor_value_changed_cb(GtkWidget *widget, gpointer data) { + vfo_encoder_divisor=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static void panadapter_high_value_changed_cb(GtkWidget *widget, gpointer data) { + panadapter_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static void panadapter_low_value_changed_cb(GtkWidget *widget, gpointer data) { + panadapter_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static void waterfall_high_value_changed_cb(GtkWidget *widget, gpointer data) { + waterfall_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static void waterfall_low_value_changed_cb(GtkWidget *widget, gpointer data) { + waterfall_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static void waterfall_automatic_cb(GtkWidget *widget, gpointer data) { + waterfall_automatic=waterfall_automatic==1?0:1; +} + static void config_cb(GtkWidget *widget, gpointer data) { GtkWidget *dialog=gtk_dialog_new_with_buttons("Audio",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); @@ -548,83 +674,92 @@ static void config_cb(GtkWidget *widget, gpointer data) { gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *linein_b=gtk_check_button_new_with_label("Line In"); - gtk_widget_override_font(linein_b, pango_font_description_from_string("Arial 18")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linein_b), (orion_mic&0x01)==LINE_IN); - gtk_widget_show(linein_b); - gtk_grid_attach(GTK_GRID(grid),linein_b,0,0,1,1); - g_signal_connect(linein_b,"toggled",G_CALLBACK(linein_cb),NULL); - - GtkWidget *micboost_b=gtk_check_button_new_with_label("Boost"); - gtk_widget_override_font(micboost_b, pango_font_description_from_string("Arial 18")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (micboost_b), (orion_mic&0x02)==MIC_BOOST); - gtk_widget_show(micboost_b); - gtk_grid_attach(GTK_GRID(grid),micboost_b,0,1,1,1); - g_signal_connect(micboost_b,"toggled",G_CALLBACK(micboost_cb),NULL); - - GtkWidget *byteswap_b=gtk_check_button_new_with_label("Byte swap"); - gtk_widget_override_font(byteswap_b, pango_font_description_from_string("Arial 18")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (byteswap_b), byte_swap); - gtk_widget_show(byteswap_b); - gtk_grid_attach(GTK_GRID(grid),byteswap_b,0,2,1,1); - g_signal_connect(byteswap_b,"toggled",G_CALLBACK(byteswap_cb),NULL); - - DISCOVERED* d=&discovered[selected_device]; - if(d->device==NEW_DEVICE_ORION) { - GtkWidget *ptt_b=gtk_check_button_new_with_label("PTT Enabled"); - gtk_widget_override_font(ptt_b, pango_font_description_from_string("Arial 18")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_b), (orion_mic&0x04)==ORION_MIC_PTT_ENABLED); - gtk_widget_show(ptt_b); - gtk_grid_attach(GTK_GRID(grid),ptt_b,0,3,1,1); - g_signal_connect(ptt_b,"toggled",G_CALLBACK(ptt_cb),NULL); - - GtkWidget *ptt_ring_b=gtk_check_button_new_with_label("PTT On Ring"); - gtk_widget_override_font(ptt_ring_b, pango_font_description_from_string("Arial 18")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_ring_b), (orion_mic&0x08)==ORION_MIC_PTT_RING_BIAS_TIP); - gtk_widget_show(ptt_ring_b); - gtk_grid_attach(GTK_GRID(grid),ptt_ring_b,0,4,1,1); - g_signal_connect(ptt_ring_b,"toggled",G_CALLBACK(ptt_ring_cb),NULL); - - GtkWidget *bias_b=gtk_check_button_new_with_label("BIAS Enabled"); - gtk_widget_override_font(bias_b, pango_font_description_from_string("Arial 18")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bias_b), (orion_mic&0x10)==ORION_MIC_BIAS_ENABLED); - gtk_widget_show(bias_b); - gtk_grid_attach(GTK_GRID(grid),bias_b,0,5,1,1); - g_signal_connect(bias_b,"toggled",G_CALLBACK(bias_cb),NULL); - } - - GtkWidget *alex_b=gtk_check_button_new_with_label("ALEX"); - gtk_widget_override_font(alex_b, pango_font_description_from_string("Arial 18")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (alex_b), filter_board==ALEX); - gtk_widget_show(alex_b); - gtk_grid_attach(GTK_GRID(grid),alex_b,1,0,1,1); - - GtkWidget *apollo_b=gtk_check_button_new_with_label("APOLLO"); - gtk_widget_override_font(apollo_b, pango_font_description_from_string("Arial 18")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apollo_b), filter_board==APOLLO); - gtk_widget_show(apollo_b); - gtk_grid_attach(GTK_GRID(grid),apollo_b,1,1,1,1); - - g_signal_connect(alex_b,"toggled",G_CALLBACK(alex_cb),apollo_b); - g_signal_connect(apollo_b,"toggled",G_CALLBACK(apollo_cb),alex_b); - - GtkWidget *apollo_tuner_b=gtk_check_button_new_with_label("Auto Tuner"); - gtk_widget_override_font(apollo_tuner_b, pango_font_description_from_string("Arial 18")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apollo_tuner_b), apollo_tuner); - gtk_widget_show(apollo_tuner_b); - gtk_grid_attach(GTK_GRID(grid),apollo_tuner_b,1,2,1,1); - g_signal_connect(apollo_tuner_b,"toggled",G_CALLBACK(apollo_tuner_cb),NULL); - - GtkWidget *pa_b=gtk_check_button_new_with_label("PA"); - gtk_widget_override_font(pa_b, pango_font_description_from_string("Arial 18")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pa_b), pa); - gtk_widget_show(pa_b); - gtk_grid_attach(GTK_GRID(grid),pa_b,1,3,1,1); - g_signal_connect(pa_b,"toggled",G_CALLBACK(pa_cb),NULL); + GtkWidget *display_label=gtk_label_new("Display: "); + //gtk_widget_override_font(display_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(display_label); + gtk_grid_attach(GTK_GRID(grid),display_label,0,0,1,1); + + GtkWidget *panadapter_high_label=gtk_label_new("Panadapter High: "); + //gtk_widget_override_font(panadapter_high_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(panadapter_high_label); + gtk_grid_attach(GTK_GRID(grid),panadapter_high_label,0,1,1,1); + + GtkWidget *panadapter_high_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); + //gtk_widget_override_font(panadapter_high_r, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_high_r),(double)panadapter_high); + gtk_widget_show(panadapter_high_r); + gtk_grid_attach(GTK_GRID(grid),panadapter_high_r,1,1,1,1); + g_signal_connect(panadapter_high_r,"value_changed",G_CALLBACK(panadapter_high_value_changed_cb),NULL); + + GtkWidget *panadapter_low_label=gtk_label_new("Panadapter Low: "); + //gtk_widget_override_font(panadapter_low_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(panadapter_low_label); + gtk_grid_attach(GTK_GRID(grid),panadapter_low_label,0,2,1,1); + + GtkWidget *panadapter_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); + //gtk_widget_override_font(panadapter_low_r, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_low_r),(double)panadapter_low); + gtk_widget_show(panadapter_low_r); + gtk_grid_attach(GTK_GRID(grid),panadapter_low_r,1,2,1,1); + g_signal_connect(panadapter_low_r,"value_changed",G_CALLBACK(panadapter_low_value_changed_cb),NULL); + + GtkWidget *waterfall_automatic_label=gtk_label_new("Waterfall Automatic: "); + //gtk_widget_override_font(waterfall_automatic_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(waterfall_automatic_label); + gtk_grid_attach(GTK_GRID(grid),waterfall_automatic_label,0,3,1,1); + + GtkWidget *waterfall_automatic_b=gtk_check_button_new(); + ////gtk_widget_override_font(waterfall_automatic_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (waterfall_automatic_b), waterfall_automatic); + gtk_widget_show(waterfall_automatic_b); + gtk_grid_attach(GTK_GRID(grid),waterfall_automatic_b,1,3,1,1); + g_signal_connect(waterfall_automatic_b,"toggled",G_CALLBACK(waterfall_automatic_cb),NULL); + + GtkWidget *waterfall_high_label=gtk_label_new("Waterfall High: "); + //gtk_widget_override_font(waterfall_high_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(waterfall_high_label); + gtk_grid_attach(GTK_GRID(grid),waterfall_high_label,0,4,1,1); + + GtkWidget *waterfall_high_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); + //gtk_widget_override_font(waterfall_high_r, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(waterfall_high_r),(double)waterfall_high); + gtk_widget_show(waterfall_high_r); + gtk_grid_attach(GTK_GRID(grid),waterfall_high_r,1,4,1,1); + g_signal_connect(waterfall_high_r,"value_changed",G_CALLBACK(waterfall_high_value_changed_cb),NULL); + + GtkWidget *waterfall_low_label=gtk_label_new("Waterfall Low: "); + //gtk_widget_override_font(waterfall_low_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(waterfall_low_label); + gtk_grid_attach(GTK_GRID(grid),waterfall_low_label,0,5,1,1); + + GtkWidget *waterfall_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); + //gtk_widget_override_font(waterfall_low_r, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(waterfall_low_r),(double)waterfall_low); + gtk_widget_show(waterfall_low_r); + gtk_grid_attach(GTK_GRID(grid),waterfall_low_r,1,5,1,1); + g_signal_connect(waterfall_low_r,"value_changed",G_CALLBACK(waterfall_low_value_changed_cb),NULL); + + + GtkWidget *vfo_encoder_label=gtk_label_new("VFO Encoder: "); + //gtk_widget_override_font(vfo_encoder_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(vfo_encoder_label); + gtk_grid_attach(GTK_GRID(grid),vfo_encoder_label,0,6,1,1); + + GtkWidget *vfo_divisor_label=gtk_label_new("Divisor: "); + //gtk_widget_override_font(vfo_divisor_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(vfo_divisor_label); + gtk_grid_attach(GTK_GRID(grid),vfo_divisor_label,0,7,1,1); + + GtkWidget *vfo_divisor=gtk_spin_button_new_with_range(1.0,60.0,1.0); + //gtk_widget_override_font(vfo_divisor, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(vfo_divisor),(double)vfo_encoder_divisor); + gtk_widget_show(vfo_divisor); + gtk_grid_attach(GTK_GRID(grid),vfo_divisor,1,7,1,1); + g_signal_connect(vfo_divisor,"value_changed",G_CALLBACK(vfo_divisor_value_changed_cb),NULL); gtk_container_add(GTK_CONTAINER(content),grid); GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK); - gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18")); gtk_widget_show_all(dialog); g_signal_connect_swapped (dialog, @@ -644,67 +779,57 @@ static void cw_cb(GtkWidget *widget, gpointer data) { GtkWidget *cw_keyer_internal_b=gtk_check_button_new_with_label("CW Internal - Speed (WPM)"); - gtk_widget_override_font(cw_keyer_internal_b, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(cw_keyer_internal_b, pango_font_description_from_string("Arial 18")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_internal_b), cw_keyer_internal); gtk_widget_show(cw_keyer_internal_b); gtk_grid_attach(GTK_GRID(grid),cw_keyer_internal_b,0,0,1,1); g_signal_connect(cw_keyer_internal_b,"toggled",G_CALLBACK(cw_keyer_internal_cb),NULL); GtkWidget *cw_keyer_speed_b=gtk_spin_button_new_with_range(1.0,60.0,1.0); - gtk_widget_override_font(cw_keyer_speed_b, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(cw_keyer_speed_b, pango_font_description_from_string("Arial 18")); gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_speed_b),(double)cw_keyer_speed); gtk_widget_show(cw_keyer_speed_b); gtk_grid_attach(GTK_GRID(grid),cw_keyer_speed_b,1,0,1,1); g_signal_connect(cw_keyer_speed_b,"value_changed",G_CALLBACK(cw_keyer_speed_value_changed_cb),NULL); GtkWidget *cw_breakin_b=gtk_check_button_new_with_label("CW Break In - Delay (ms)"); - gtk_widget_override_font(cw_breakin_b, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(cw_breakin_b, pango_font_description_from_string("Arial 18")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_breakin_b), cw_breakin); gtk_widget_show(cw_breakin_b); gtk_grid_attach(GTK_GRID(grid),cw_breakin_b,0,1,1,1); g_signal_connect(cw_breakin_b,"toggled",G_CALLBACK(cw_breakin_cb),NULL); GtkWidget *cw_keyer_hang_time_b=gtk_spin_button_new_with_range(0.0,1000.0,1.0); - gtk_widget_override_font(cw_keyer_hang_time_b, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(cw_keyer_hang_time_b, pango_font_description_from_string("Arial 18")); gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_hang_time_b),(double)cw_keyer_hang_time); gtk_widget_show(cw_keyer_hang_time_b); gtk_grid_attach(GTK_GRID(grid),cw_keyer_hang_time_b,1,1,1,1); g_signal_connect(cw_keyer_hang_time_b,"value_changed",G_CALLBACK(cw_keyer_hang_time_value_changed_cb),NULL); GtkWidget *cw_keyer_straight=gtk_radio_button_new_with_label(NULL,"CW KEYER STRAIGHT"); - gtk_widget_override_font(cw_keyer_straight, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(cw_keyer_straight, pango_font_description_from_string("Arial 18")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_straight), cw_keyer_mode==KEYER_STRAIGHT); gtk_widget_show(cw_keyer_straight); gtk_grid_attach(GTK_GRID(grid),cw_keyer_straight,0,2,1,1); g_signal_connect(cw_keyer_straight,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_STRAIGHT); GtkWidget *cw_keyer_mode_a=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(cw_keyer_straight),"CW KEYER MODE A"); - gtk_widget_override_font(cw_keyer_mode_a, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(cw_keyer_mode_a, pango_font_description_from_string("Arial 18")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_mode_a), cw_keyer_mode==KEYER_MODE_A); gtk_widget_show(cw_keyer_mode_a); gtk_grid_attach(GTK_GRID(grid),cw_keyer_mode_a,0,3,1,1); g_signal_connect(cw_keyer_mode_a,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_MODE_A); GtkWidget *cw_keyer_mode_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(cw_keyer_mode_a),"CW KEYER MODE B"); - gtk_widget_override_font(cw_keyer_mode_b, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(cw_keyer_mode_b, pango_font_description_from_string("Arial 18")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_mode_b), cw_keyer_mode==KEYER_MODE_B); gtk_widget_show(cw_keyer_mode_b); gtk_grid_attach(GTK_GRID(grid),cw_keyer_mode_b,0,4,1,1); g_signal_connect(cw_keyer_mode_b,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_MODE_B); -/* -int cw_keyer_speed=12; // 1-60 WPM -int cw_keyer_weight=30; // 0-100 -int cw_keyer_spacing=0; // 0=on 1=off -int cw_keyer_sidetone_volume=127; // 0-127 -int cw_keyer_ptt_delay=20; // 0-255ms -int cw_keyer_hang_time=10; // ms -int cw_keyer_sidetone_frequency=400; // Hz -*/ - gtk_container_add(GTK_CONTAINER(content),grid); GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK); - gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18")); + //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18")); gtk_widget_show_all(dialog); g_signal_connect_swapped (dialog, @@ -715,86 +840,42 @@ int cw_keyer_sidetone_frequency=400; // Hz int result=gtk_dialog_run(GTK_DIALOG(dialog)); } +/* static void adc_cb(GtkWidget *widget, gpointer data) { int adc0=adc[0]; adc[0]=adc[1]; adc[1]=adc0; char label[16]; - gtk_grid_remove_row(GTK_GRID(toolbar_top),0); + gtk_grid_remove_row(GTK_GRID(toolbar_top_1),0); sprintf(label,"RX0=%d",adc[0]); GtkWidget *rx0=gtk_label_new(label); - gtk_widget_override_font(rx0, pango_font_description_from_string("Arial 16")); + //gtk_widget_override_font(rx0, pango_font_description_from_string("Arial 16")); gtk_widget_show(rx0); - gtk_grid_attach(GTK_GRID(toolbar_top),rx0,0,0,1,1); + gtk_grid_attach(GTK_GRID(toolbar_top_1),rx0,0,0,1,1); sprintf(label,"RX1=%d",adc[1]); GtkWidget *rx1=gtk_label_new(label); - gtk_widget_override_font(rx1, pango_font_description_from_string("Arial 16")); + //gtk_widget_override_font(rx1, pango_font_description_from_string("Arial 16")); gtk_widget_show(rx1); - gtk_grid_attach(GTK_GRID(toolbar_top),rx1,1,0,1,1); + gtk_grid_attach(GTK_GRID(toolbar_top_1),rx1,1,0,1,1); } +*/ -static void lock_cb(GtkWidget *widget, gpointer data) { +void lock_cb(GtkWidget *widget, gpointer data) { locked=locked==1?0:1; vfo_update(NULL); } -static void mox_cb(GtkWidget *widget, gpointer data) { - gtk_grid_remove_row (GTK_GRID(toolbar_top),0); +void mox_cb(GtkWidget *widget, gpointer data) { if(getTune()==1) { setTune(0); } - setMox(getMox()==0?1:0); - vfo_update(NULL); - if(getMox()) { - mic_gain_label=gtk_label_new("Mic Gain:"); - gtk_widget_override_font(mic_gain_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(mic_gain_label); - gtk_grid_attach(GTK_GRID(toolbar_top),mic_gain_label,0,0,1,1); - - mic_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 1.0, 0.01); - gtk_range_set_value (GTK_RANGE(mic_scale),mic_gain); - gtk_widget_show(mic_scale); - gtk_grid_attach(GTK_GRID(toolbar_top),mic_scale,1,0,2,1); - g_signal_connect(G_OBJECT(mic_scale),"value_changed",G_CALLBACK(micgain_value_changed_cb),NULL); - - GtkWidget *drive_label=gtk_label_new("Drive:"); - gtk_widget_override_font(drive_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(drive_label); - gtk_grid_attach(GTK_GRID(toolbar_top),drive_label,3,0,1,1); - - drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 1.0, 0.01); - gtk_range_set_value (GTK_RANGE(drive_scale),getDrive()); - gtk_widget_show(drive_scale); - gtk_grid_attach(GTK_GRID(toolbar_top),drive_scale,4,0,2,1); - g_signal_connect(G_OBJECT(drive_scale),"value_changed",G_CALLBACK(drive_value_changed_cb),NULL); - } else { - af_gain_label=gtk_label_new("AF:"); - gtk_widget_override_font(af_gain_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(af_gain_label); - gtk_grid_attach(GTK_GRID(toolbar_top),af_gain_label,0,0,1,1); - - audio_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 1.0, 0.01); - gtk_range_set_value (GTK_RANGE(audio_scale),volume); - gtk_widget_show(audio_scale); - gtk_grid_attach(GTK_GRID(toolbar_top),audio_scale,1,0,2,1); - g_signal_connect(G_OBJECT(audio_scale),"value_changed",G_CALLBACK(afgain_value_changed_cb),NULL); - - agc_gain_label=gtk_label_new("AGC:"); - gtk_widget_override_font(agc_gain_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(agc_gain_label); - gtk_grid_attach(GTK_GRID(toolbar_top),agc_gain_label,3,0,1,1); - - agc_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 120.0, 1.0); - gtk_range_set_value (GTK_RANGE(agc_scale),agc_gain); - gtk_widget_show(agc_scale); - gtk_grid_attach(GTK_GRID(toolbar_top),agc_scale,4,0,2,1); - g_signal_connect(G_OBJECT(agc_scale),"value_changed",G_CALLBACK(agcgain_value_changed_cb),NULL); - + if(canTransmit() || tx_out_of_band) { + setMox(getMox()==0?1:0); + vfo_update(NULL); } - //gtk_widget_queue_draw(toolbar_top); } int ptt_update(void *data) { @@ -811,54 +892,101 @@ int ptt_update(void *data) { return 0; } -static void tune_cb(GtkWidget *widget, gpointer data) { - gtk_grid_remove_row (GTK_GRID(toolbar_top),0); +void tune_cb(GtkWidget *widget, gpointer data) { if(getMox()==1) { setMox(0); } - setTune(getTune()==0?1:0); - vfo_update(NULL); - if(getTune()) { - GtkWidget *tune_label=gtk_label_new("Tune Drive:"); - gtk_widget_override_font(tune_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(tune_label); - gtk_grid_attach(GTK_GRID(toolbar_top),tune_label,0,0,1,1); - - tune_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 1.0, 0.01); - gtk_range_set_value (GTK_RANGE(tune_scale),getTuneDrive()); - gtk_widget_show(tune_scale); - gtk_grid_attach(GTK_GRID(toolbar_top),tune_scale,1,0,2,1); - g_signal_connect(G_OBJECT(tune_scale),"value_changed",G_CALLBACK(tune_value_changed_cb),NULL); - } else { - af_gain_label=gtk_label_new("AF:"); - gtk_widget_override_font(af_gain_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(af_gain_label); - gtk_grid_attach(GTK_GRID(toolbar_top),af_gain_label,0,0,1,1); - - audio_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 1.0, 0.01); - gtk_range_set_value (GTK_RANGE(audio_scale),volume); - gtk_widget_show(audio_scale); - gtk_grid_attach(GTK_GRID(toolbar_top),audio_scale,1,0,2,1); - g_signal_connect(G_OBJECT(audio_scale),"value_changed",G_CALLBACK(afgain_value_changed_cb),NULL); - - agc_gain_label=gtk_label_new("AGC:"); - gtk_widget_override_font(agc_gain_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(agc_gain_label); - gtk_grid_attach(GTK_GRID(toolbar_top),agc_gain_label,3,0,1,1); - - agc_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 120.0, 1.0); - gtk_range_set_value (GTK_RANGE(agc_scale),agc_gain); - gtk_widget_show(agc_scale); - gtk_grid_attach(GTK_GRID(toolbar_top),agc_scale,4,0,2,1); - g_signal_connect(G_OBJECT(agc_scale),"value_changed",G_CALLBACK(agcgain_value_changed_cb),NULL); + if(canTransmit() || tx_out_of_band) { + setTune(getTune()==0?1:0); + vfo_update(NULL); } } +GtkWidget *sliders_init(int my_width, int my_height, GtkWidget* parent) { + width=my_width; + height=my_height; + parent_window=parent; + + fprintf(stderr,"sliders_init: width=%d height=%d\n", width,height); + + sliders=gtk_grid_new(); + gtk_widget_set_size_request (sliders, width, height); + gtk_grid_set_row_homogeneous(GTK_GRID(sliders), FALSE); + gtk_grid_set_column_homogeneous(GTK_GRID(sliders),TRUE); + + af_gain_label=gtk_label_new("AF:"); + //gtk_widget_override_font(af_gain_label, pango_font_description_from_string("Arial 16")); + gtk_widget_show(af_gain_label); + gtk_grid_attach(GTK_GRID(sliders),af_gain_label,0,0,1,1); + + af_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00); + gtk_range_set_value (GTK_RANGE(af_gain_scale),volume*100.0); + gtk_widget_show(af_gain_scale); + gtk_grid_attach(GTK_GRID(sliders),af_gain_scale,1,0,2,1); + g_signal_connect(G_OBJECT(af_gain_scale),"value_changed",G_CALLBACK(afgain_value_changed_cb),NULL); + + agc_gain_label=gtk_label_new("AGC:"); + //gtk_widget_override_font(agc_gain_label, pango_font_description_from_string("Arial 16")); + gtk_widget_show(agc_gain_label); + gtk_grid_attach(GTK_GRID(sliders),agc_gain_label,3,0,1,1); + + agc_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 120.0, 1.0); + gtk_range_set_value (GTK_RANGE(agc_scale),agc_gain); + gtk_widget_show(agc_scale); + 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); + + + mic_gain_label=gtk_label_new("Mic:"); + //gtk_widget_override_font(mic_gain_label, pango_font_description_from_string("Arial 16")); + gtk_widget_show(mic_gain_label); + gtk_grid_attach(GTK_GRID(sliders),mic_gain_label,0,1,1,1); + + mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.0); + gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain*MIC_GAIN_FUDGE); + gtk_widget_show(mic_gain_scale); + gtk_grid_attach(GTK_GRID(sliders),mic_gain_scale,1,1,2,1); + g_signal_connect(G_OBJECT(mic_gain_scale),"value_changed",G_CALLBACK(micgain_value_changed_cb),NULL); + + drive_label=gtk_label_new("Drive:"); + //gtk_widget_override_font(drive_label, pango_font_description_from_string("Arial 16")); + gtk_widget_show(drive_label); + gtk_grid_attach(GTK_GRID(sliders),drive_label,3,1,1,1); + + drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.0); + gtk_range_set_value (GTK_RANGE(drive_scale),getDrive()*100.0); + gtk_widget_show(drive_scale); + gtk_grid_attach(GTK_GRID(sliders),drive_scale,4,1,2,1); + g_signal_connect(G_OBJECT(drive_scale),"value_changed",G_CALLBACK(drive_value_changed_cb),NULL); + + tune_label=gtk_label_new("Tune:"); + //gtk_widget_override_font(tune_label, pango_font_description_from_string("Arial 16")); + gtk_widget_show(tune_label); + gtk_grid_attach(GTK_GRID(sliders),tune_label,6,1,1,1); + + tune_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.0); + gtk_range_set_value (GTK_RANGE(tune_scale),getTuneDrive()*100.0); + gtk_widget_show(tune_scale); + gtk_grid_attach(GTK_GRID(sliders),tune_scale,7,1,2,1); + g_signal_connect(G_OBJECT(tune_scale),"value_changed",G_CALLBACK(tune_value_changed_cb),NULL); + + dummy_label=gtk_label_new(" "); + //gtk_widget_override_font(dummy_label, pango_font_description_from_string("Arial 16")); + gtk_widget_show(dummy_label); + gtk_grid_attach(GTK_GRID(sliders),dummy_label,9,1,1,1); + + return sliders; +} + GtkWidget *toolbar_init(int my_width, int my_height, GtkWidget* parent) { width=my_width; height=my_height; parent_window=parent; + int button_width=width/8; + + fprintf(stderr,"toolbar_init: width=%d height=%d button_width=%d\n", width,height,button_width); + white.red=1.0; white.green=1.0; white.blue=1.0; @@ -871,137 +999,40 @@ GtkWidget *toolbar_init(int my_width, int my_height, GtkWidget* parent) { toolbar=gtk_grid_new(); gtk_widget_set_size_request (toolbar, width, height); - gtk_grid_set_row_homogeneous(GTK_GRID(toolbar), TRUE); + gtk_grid_set_column_homogeneous(GTK_GRID(toolbar),TRUE); - toolbar_top=gtk_grid_new(); - gtk_grid_set_column_homogeneous(GTK_GRID(toolbar_top),TRUE); - - toolbar_bottom=gtk_grid_new(); - gtk_grid_set_column_homogeneous(GTK_GRID(toolbar_bottom),FALSE); - GtkWidget *band=gtk_button_new_with_label("Band"); - gtk_widget_override_font(band, pango_font_description_from_string("Arial 20")); + gtk_widget_set_size_request (band, button_width, 0); + //gtk_widget_override_font(band, pango_font_description_from_string("Arial 16")); g_signal_connect(G_OBJECT(band),"clicked",G_CALLBACK(band_cb),NULL); - gtk_widget_show(band); - gtk_grid_attach(GTK_GRID(toolbar_bottom),band,column,0,1,1); - column++; + gtk_grid_attach(GTK_GRID(toolbar),band,0,0,4,1); GtkWidget *mode=gtk_button_new_with_label("Mode"); - gtk_widget_override_font(mode, pango_font_description_from_string("Arial 20")); + //gtk_widget_override_font(mode, pango_font_description_from_string("Arial 16")); g_signal_connect(G_OBJECT(mode),"clicked",G_CALLBACK(mode_cb),NULL); - gtk_widget_show(mode); - gtk_grid_attach(GTK_GRID(toolbar_bottom),mode,column,0,1,1); - column++; + gtk_grid_attach(GTK_GRID(toolbar),mode,4,0,4,1); GtkWidget *filter=gtk_button_new_with_label("Filter"); - gtk_widget_override_font(filter, pango_font_description_from_string("Arial 20")); + //gtk_widget_override_font(filter, pango_font_description_from_string("Arial 16")); g_signal_connect(G_OBJECT(filter),"clicked",G_CALLBACK(filter_cb),NULL); - gtk_widget_show(filter); - gtk_grid_attach(GTK_GRID(toolbar_bottom),filter,column,0,1,1); - column++; - - GtkWidget *audio=gtk_button_new_with_label("Audio"); - gtk_widget_override_font(audio, pango_font_description_from_string("Arial 20")); - g_signal_connect(G_OBJECT(audio),"clicked",G_CALLBACK(audio_cb),NULL); - gtk_widget_show(audio); - gtk_grid_attach(GTK_GRID(toolbar_bottom),audio,column,0,1,1); - column++; - - GtkWidget *config=gtk_button_new_with_label("Config"); - gtk_widget_override_font(config, pango_font_description_from_string("Arial 20")); - g_signal_connect(G_OBJECT(config),"clicked",G_CALLBACK(config_cb),NULL); - gtk_widget_show(config); - gtk_grid_attach(GTK_GRID(toolbar_bottom),config,column,0,1,1); - column++; - - GtkWidget *cw=gtk_button_new_with_label("CW"); - gtk_widget_override_font(cw, pango_font_description_from_string("Arial 20")); - g_signal_connect(G_OBJECT(cw),"clicked",G_CALLBACK(cw_cb),NULL); - gtk_widget_show(cw); - gtk_grid_attach(GTK_GRID(toolbar_bottom),cw,column,0,1,1); - column++; - - GtkWidget *exit=gtk_button_new_with_label("Exit"); - gtk_widget_override_font(exit, pango_font_description_from_string("Arial 20")); - g_signal_connect(G_OBJECT(exit),"clicked",G_CALLBACK(exit_cb),NULL); - gtk_widget_show(exit); - gtk_grid_attach(GTK_GRID(toolbar_bottom),exit,column,0,1,1); - column++; + gtk_grid_attach(GTK_GRID(toolbar),filter,8,0,4,1); GtkWidget *lock=gtk_button_new_with_label("Lock"); - gtk_widget_override_font(lock, pango_font_description_from_string("Arial 20")); + //gtk_widget_override_font(lock, pango_font_description_from_string("Arial 16")); g_signal_connect(G_OBJECT(lock),"clicked",G_CALLBACK(lock_cb),NULL); - gtk_widget_show(lock); - gtk_grid_attach(GTK_GRID(toolbar_bottom),lock,column,0,1,1); - column++; + gtk_grid_attach(GTK_GRID(toolbar),lock,16,0,4,1); GtkWidget *tune=gtk_button_new_with_label("Tune"); - gtk_widget_override_font(tune, pango_font_description_from_string("Arial 20")); + //gtk_widget_override_font(tune, pango_font_description_from_string("Arial 16")); g_signal_connect(G_OBJECT(tune),"clicked",G_CALLBACK(tune_cb),NULL); - gtk_widget_show(tune); - gtk_grid_attach(GTK_GRID(toolbar_bottom),tune,column,0,1,1); - column++; + gtk_grid_attach(GTK_GRID(toolbar),tune,24,0,4,1); GtkWidget *tx=gtk_button_new_with_label("Mox"); - gtk_widget_override_font(tx, pango_font_description_from_string("Arial 20")); + //gtk_widget_override_font(tx, pango_font_description_from_string("Arial 16")); g_signal_connect(G_OBJECT(tx),"clicked",G_CALLBACK(mox_cb),NULL); - gtk_widget_show(tx); - gtk_grid_attach(GTK_GRID(toolbar_bottom),tx,column,0,1,1); - column++; - - - // default to receive controls on top bar - af_gain_label=gtk_label_new("AF:"); - gtk_widget_override_font(af_gain_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(af_gain_label); - gtk_grid_attach(GTK_GRID(toolbar_top),af_gain_label,0,0,1,1); - - audio_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 1.0, 0.01); - gtk_range_set_value (GTK_RANGE(audio_scale),volume); - gtk_widget_show(audio_scale); - gtk_grid_attach(GTK_GRID(toolbar_top),audio_scale,1,0,2,1); - g_signal_connect(G_OBJECT(audio_scale),"value_changed",G_CALLBACK(afgain_value_changed_cb),NULL); - - agc_gain_label=gtk_label_new("AGC:"); - gtk_widget_override_font(agc_gain_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(agc_gain_label); - gtk_grid_attach(GTK_GRID(toolbar_top),agc_gain_label,3,0,1,1); - - agc_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 120.0, 1.0); - gtk_range_set_value (GTK_RANGE(agc_scale),agc_gain); - gtk_widget_show(agc_scale); - gtk_grid_attach(GTK_GRID(toolbar_top),agc_scale,4,0,2,1); - g_signal_connect(G_OBJECT(agc_scale),"value_changed",G_CALLBACK(agcgain_value_changed_cb),NULL); - -/* - - GtkWidget *drive_label=gtk_label_new("Drive:"); - gtk_widget_override_font(drive_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(drive_label); - gtk_grid_attach(toolbar_top,drive_label,6,0,1,1); - - drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 1.0, 0.01); - gtk_range_set_value (drive_scale,getTuneDrive()); - gtk_widget_show(drive_scale); - gtk_grid_attach(toolbar_top,drive_scale,7,0,2,1); - g_signal_connect(G_OBJECT(drive_scale),"value_changed",G_CALLBACK(drive_value_changed_cb),NULL); - - GtkWidget *tune_label=gtk_label_new("Tune:"); - gtk_widget_override_font(tune_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(tune_label); - gtk_grid_attach(toolbar_top,tune_label,9,0,1,1); - - tune_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 1.0, 0.01); - gtk_range_set_value (tune_scale,getTuneDrive()); - gtk_widget_show(tune_scale); - gtk_grid_attach(toolbar_top,tune_scale,10,0,2,1); - g_signal_connect(G_OBJECT(tune_scale),"value_changed",G_CALLBACK(tune_value_changed_cb),NULL); -*/ + gtk_grid_attach(GTK_GRID(toolbar),tx,28,0,4,1); - gtk_grid_attach(GTK_GRID(toolbar),toolbar_top,0,0,1,1); - gtk_widget_show(toolbar_top); - gtk_grid_attach(GTK_GRID(toolbar),toolbar_bottom,0,1,1,1); - gtk_widget_show(toolbar_bottom); + gtk_widget_show_all(toolbar); return toolbar; } diff --git a/toolbar.h b/toolbar.h index 53c25f3..99940ea 100644 --- a/toolbar.h +++ b/toolbar.h @@ -1,6 +1,30 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + void set_agc_gain(double value); void set_af_gain(double value); +void set_mic_gain(double value); void set_drive(double drive); void set_tune(double tune); int ptt_update(void *data); +void lock_cb(GtkWidget *widget, gpointer data); +void mox_cb(GtkWidget *widget, gpointer data); +void tune_cb(GtkWidget *widget, gpointer data); GtkWidget *toolbar_init(int my_width, int my_height, GtkWidget* parent); +GtkWidget *sliders_init(int my_width, int my_height, GtkWidget* parent); diff --git a/version.c b/version.c new file mode 100644 index 0000000..c3bd1b1 --- /dev/null +++ b/version.c @@ -0,0 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +char build_date[]=__DATE__; +char build_time[]=__TIME__; + diff --git a/version.h b/version.h new file mode 100644 index 0000000..a250627 --- /dev/null +++ b/version.h @@ -0,0 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +extern char build_date[]; +extern char build_time[]; + diff --git a/vfo.c b/vfo.c index 648f31d..b0ba261 100644 --- a/vfo.c +++ b/vfo.c @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include #include #include @@ -7,32 +26,29 @@ #include #include +#include "main.h" +#include "agc.h" #include "mode.h" #include "filter.h" #include "bandstack.h" #include "band.h" +#include "frequency.h" #include "new_protocol.h" -#include "rotary_encoder.h" #include "radio.h" #include "vfo.h" #include "channel.h" +#include "gpio.h" #include "wdsp.h" static GtkWidget *parent_window; +static int my_width; +static int my_height; static GtkWidget *vfo; static cairo_surface_t *vfo_surface = NULL; -static pthread_t rotary_encoder_thread_id; - static int steps[]={1,10,25,50,100,250,500,1000,2500,5000,6250,9000,10000,12500,15000,20000,25000,30000,50000,100000,0}; static char *step_labels[]={"1Hz","10Hz","25Hz","50Hz","100Hz","250Hz","500Hz","1kHz","2.5kHz","5kHz","6.25kHz","9kHz","10kHz","12.5kHz","15kHz","20kHz","25kHz","30kHz","50kHz","100kHz",0}; -static int af_function=0; -static int previous_af_function=0; -static int rf_function=0; -static int previous_rf_function=0; -static int band_button=0; -static int previous_band_button=0; static GtkWidget* menu=NULL; static GtkWidget* band_menu=NULL; @@ -55,167 +71,13 @@ void vfo_move(int hz) { } } -static int rotary_encoder_changed(void *data) { - if(!locked) { - int pos=*(int*)data; - BANDSTACK_ENTRY* entry=bandstack_entry_get_current(); - entry->frequencyA=entry->frequencyA+(pos*step); - setFrequency(entry->frequencyA); - vfo_update(NULL); - } - free(data); - return 0; -} - -static int af_encoder_changed(void *data) { - int pos=*(int*)data; - if(pos!=0) { - if(af_function) { - // agc gain - double gain=agc_gain; - gain+=(double)pos; - if(gain<0.0) { - gain=0.0; - } else if(gain>120.0) { - gain=120.0; - } - set_agc_gain(gain); - } else { - // af gain - double gain=volume; - gain+=(double)pos/20.0; - if(gain<0.0) { - gain=0.0; - } else if(gain>1.0) { - gain=1.0; - } - set_af_gain(gain); - } - } - free(data); - return 0; -} - -static int rf_encoder_changed(void *data) { - int pos=*(int*)data; - if(pos!=0) { - if(rf_function) { - // tune drive - double d=getTuneDrive(); - d+=(double)pos/10.0; - if(d<0.0) { - d=0.0; - } else if(d>1.0) { - d=1.0; - } - set_tune(d); - } else { - // drive - double d=getDrive(); - d+=(double)pos/10.0; - if(d<0.0) { - d=0.0; - } else if(d>1.0) { - d=1.0; - } - set_drive(d); - } - } - free(data); - return 0; -} - -static int band_pressed(void *data) { - int function=*(int*)data; - - BANDSTACK_ENTRY *entry; - if(function) { - entry=bandstack_entry_next(); - } else { - int b=band_get_current(); - b++; - if(b>=BANDS) { - b=0; - } - BAND* band=band_set_current(b); - entry=bandstack_entry_get_current(); - } - - setFrequency(entry->frequencyA); - setMode(entry->mode); - FILTER* band_filters=filters[entry->mode]; - FILTER* band_filter=&band_filters[entry->filter]; - setFilter(band_filter->low,band_filter->high); - - BAND *band=band_get_current_band(); - set_alex_rx_antenna(band->alexRxAntenna); - set_alex_tx_antenna(band->alexTxAntenna); - set_alex_attenuation(band->alexAttenuation); - vfo_update(NULL); - - - free(data); - return 0; -} - -static void* rotary_encoder_thread(void *arg) { - int pos; - while(1) { - - pos=vfo_encoder_get_pos(); - if(pos!=0) { - int *p=malloc(sizeof(int)); - *p=pos; - g_idle_add(rotary_encoder_changed,(gpointer)p); - } - - af_function=af_function_get_state(); - if(af_function!=previous_af_function) { - fprintf(stderr,"af_function: %d\n",af_function); - previous_af_function=af_function; - } - pos=af_encoder_get_pos(); - if(pos!=0) { - int *p=malloc(sizeof(int)); - *p=pos; - g_idle_add(af_encoder_changed,(gpointer)p); - } - - rf_function=rf_function_get_state(); - if(rf_function!=previous_rf_function) { - fprintf(stderr,"rf_function: %d\n",rf_function); - previous_rf_function=rf_function; - } - pos=rf_encoder_get_pos(); - if(pos!=0) { - int *p=malloc(sizeof(int)); - *p=pos; - g_idle_add(rf_encoder_changed,(gpointer)p); - } - - int band_button=band_get_state(); - if(band_button!=previous_band_button) { - fprintf(stderr,"band_button: %d\n",band_button); - previous_band_button=band_button; - if(band_button) { - int function=function_get_state(); - g_idle_add(band_pressed,(gpointer)function); - } - } - -#ifdef raspberrypi - gpioDelay(100000); // 10 per second -#endif -#ifdef odroid - usleep(100000); -#endif - } -} - static gboolean vfo_configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, gpointer data) { +fprintf(stderr,"vfo_configure_event_cb: width=%d height=%d\n", + gtk_widget_get_allocated_width (widget), + gtk_widget_get_allocated_height (widget)); if (vfo_surface) cairo_surface_destroy (vfo_surface); @@ -257,7 +119,8 @@ int vfo_update(void *data) { cairo_select_font_face(cr, "Arial", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size(cr, 36); + //cairo_set_font_size(cr, 36); + cairo_set_font_size(cr, 28); if(isTransmitting()) { cairo_set_source_rgb(cr, 1, 0, 0); @@ -266,14 +129,18 @@ int vfo_update(void *data) { } char sf[32]; - sprintf(sf,"%0lld.%06lld MHz %s %s",entry->frequencyA/(long long)1000000,entry->frequencyA%(long long)1000000,mode_string[entry->mode],band_filter->title); - cairo_move_to(cr, 130, 45); + sprintf(sf,"%0lld.%06lld MHz",entry->frequencyA/(long long)1000000,entry->frequencyA%(long long)1000000); + cairo_move_to(cr, 5, 30); cairo_show_text(cr, sf); - cairo_set_font_size(cr, 18); - sprintf(sf,"Step %dHz",step); - cairo_move_to(cr, 10, 25); - cairo_show_text(cr, sf); + cairo_set_font_size(cr, 12); + + cairo_move_to(cr, (my_width/2)+20, 30); + cairo_show_text(cr, getFrequencyInfo(entry->frequencyA)); + +// sprintf(sf,"Step %dHz",step); +// cairo_move_to(cr, 10, 25); +// cairo_show_text(cr, sf); if(locked) { cairo_set_source_rgb(cr, 1, 0, 0); @@ -281,6 +148,52 @@ int vfo_update(void *data) { cairo_show_text(cr, "Locked"); } + if(function) { + cairo_set_source_rgb(cr, 1, 0.5, 0); + cairo_move_to(cr, 70, 50); + cairo_show_text(cr, "Function"); + } + + cairo_set_source_rgb(cr, 1, 1, 0); + cairo_move_to(cr, 130, 50); + cairo_show_text(cr, mode_string[entry->mode]); + + cairo_move_to(cr, 190, 50); + cairo_show_text(cr, band_filter->title); + + cairo_move_to(cr, 250, 50); + if(nr) { + cairo_show_text(cr, "NR"); + } + if(nb) { + cairo_show_text(cr, "NB"); + } + if(anf) { + cairo_show_text(cr, "ANF"); + } + if(snb) { + cairo_show_text(cr, "NR2"); + } + + cairo_move_to(cr, 310, 50); + switch(agc) { + case AGC_OFF: + cairo_show_text(cr, "AGC OFF"); + break; + case AGC_LONG: + cairo_show_text(cr, "AGC LONG"); + break; + case AGC_SLOW: + cairo_show_text(cr, "AGC SLOW"); + break; + case AGC_MEDIUM: + cairo_show_text(cr, "AGC MEDIUM"); + break; + case AGC_FAST: + cairo_show_text(cr, "AGC FAST"); + break; + } + cairo_destroy (cr); gtk_widget_queue_draw (vfo); } @@ -300,7 +213,7 @@ vfo_press_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { - GtkWidget *dialog=gtk_dialog_new_with_buttons("VFO",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + GtkWidget *dialog=gtk_dialog_new_with_buttons("Step",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); GtkWidget *grid=gtk_grid_new(); @@ -319,12 +232,13 @@ vfo_press_event_cb (GtkWidget *widget, gtk_widget_override_font(step_rb, pango_font_description_from_string("Arial 18")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (step_rb), steps[i]==step); gtk_widget_show(step_rb); - gtk_grid_attach(GTK_GRID(grid),step_rb,i/5,i%5,1,1); + gtk_grid_attach(GTK_GRID(grid),step_rb,i%5,i/5,1,1); g_signal_connect(step_rb,"pressed",G_CALLBACK(vfo_step_select_cb),(gpointer *)i); i++; } gtk_container_add(GTK_CONTAINER(content),grid); + GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK); gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18")); gtk_widget_show_all(dialog); @@ -341,10 +255,12 @@ vfo_press_event_cb (GtkWidget *widget, GtkWidget* vfo_init(int width,int height,GtkWidget *parent) { +fprintf(stderr,"vfo_init: width=%d height=%d\n", width, height); parent_window=parent; + my_width=width; + my_height=height; vfo = gtk_drawing_area_new (); - /* set a minimum size */ gtk_widget_set_size_request (vfo, width, height); /* Signals used to handle the backing surface */ @@ -353,15 +269,6 @@ GtkWidget* vfo_init(int width,int height,GtkWidget *parent) { g_signal_connect (vfo,"configure-event", G_CALLBACK (vfo_configure_event_cb), NULL); - if(encoder_init() == 0) { - int rc=pthread_create(&rotary_encoder_thread_id, NULL, rotary_encoder_thread, NULL); - if(rc<0) { - fprintf(stderr,"pthread_create for rotary_encoder_thread failed %d\n",rc); - } - } else { - fprintf(stderr,"encoder_init failed\n"); - } - /* Event signals */ g_signal_connect (vfo, "button-press-event", G_CALLBACK (vfo_press_event_cb), NULL); diff --git a/vfo.h b/vfo.h index 22d2da1..008e8e0 100644 --- a/vfo.h +++ b/vfo.h @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + GtkWidget* vfo_init(int width,int height,GtkWidget *parent); void vfo_step(int steps); diff --git a/waterfall.c b/waterfall.c index 176e868..e3dd218 100644 --- a/waterfall.c +++ b/waterfall.c @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + #include #include @@ -5,16 +24,13 @@ #include #include #include +#include "radio.h" #include "vfo.h" -#include "new_protocol.h" #include "waterfall.h" static GtkWidget *waterfall; static GdkPixbuf *pixbuf = NULL; -static float highThreshold = -100.0f; -static float lowThreshold = -150.0f; - static int colorLowR=0; // black static int colorLowG=0; static int colorLowB=0; @@ -144,17 +160,17 @@ void waterfall_update(float *data) { for(i=0;ihighThreshold) { + } else if(sample>(float)waterfall_high) { *p++=colorHighR; *p++=colorHighG; *p++=colorHighB; } else { - float range=highThreshold-lowThreshold; - float offset=sample-lowThreshold; + float range=(float)waterfall_high-(float)waterfall_low; + float offset=sample-(float)waterfall_low; float percent=offset/range; if(percent<(2.0f/9.0f)) { float local_percent = percent / (2.0f/9.0f); @@ -197,8 +213,10 @@ void waterfall_update(float *data) { } - lowThreshold=(float)((average/display_width)); - highThreshold=lowThreshold+50.0; + if(waterfall_automatic) { + waterfall_low=average/display_width; + waterfall_high=waterfall_low+50; + } gtk_widget_queue_draw (waterfall); diff --git a/waterfall.h b/waterfall.h index 7b5e379..c656298 100644 --- a/waterfall.h +++ b/waterfall.h @@ -1,3 +1,22 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + void waterfall_update(float *data); GtkWidget* waterfall_init(int width,int height); diff --git a/wdsp_init.c b/wdsp_init.c new file mode 100644 index 0000000..da15bda --- /dev/null +++ b/wdsp_init.c @@ -0,0 +1,280 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "alex.h" +#include "new_protocol.h" +#include "channel.h" +#include "discovered.h" +#include "mode.h" +#include "filter.h" +#include "wdsp.h" +#include "radio.h" +#include "vfo.h" +#include "toolbar.h" +#include "wdsp_init.h" + +#define PI 3.1415926535897932F + +static int receiver; +static int running=0; + +static int buffer_size=BUFFER_SIZE; +static int tx_buffer_size=BUFFER_SIZE; +static int fft_size=4096; +static int dspRate=48000; +static int outputRate=48000; + +static int micSampleRate=48000; +static int micDspRate=48000; +static int micOutputRate=192000; + +static int spectrumWIDTH=800; +static int SPECTRUM_UPDATES_PER_SECOND=10; + +static void initAnalyzer(int channel,int buffer_size); + +void setMode(int m) { + mode=m; + SetRXAMode(receiver, mode); + SetTXAMode(CHANNEL_TX, mode); +} + +int getMode() { + return mode; +} + +void setFilter(int low,int high) { + if(mode==modeCWL) { + filterLow=-cwPitch-low; + filterHigh=-cwPitch+high; + } else if(mode==modeCWU) { + filterLow=cwPitch-low; + filterHigh=cwPitch+high; + } else { + filterLow=low; + filterHigh=high; + } + + RXANBPSetFreqs(receiver,(double)filterLow,(double)filterHigh); + SetRXABandpassFreqs(receiver, (double)filterLow, (double)filterHigh); + SetRXASNBAOutputBandwidth(receiver, (double)filterLow, (double)filterHigh); + + SetTXABandpassFreqs(CHANNEL_TX, (double)filterLow, (double)filterHigh); +} + +int getFilterLow() { + return filterLow; +} + +int getFilterHigh() { + return filterHigh; +} + +void wdsp_init(int rx,int pixels,int protocol) { + int rc; + receiver=rx; + spectrumWIDTH=pixels; + + fprintf(stderr,"wdsp_init: %d\n",rx); + + if(protocol==ORIGINAL_PROTOCOL) { + micOutputRate=48000; + } else { + micOutputRate=192000; + } + + while (gtk_events_pending ()) + gtk_main_iteration (); + + fprintf(stderr,"OpenChannel %d buffer_size=%d fft_size=%d sample_rate=%d dspRate=%d outputRate=%d\n", + rx, + buffer_size, + fft_size, + sample_rate, + dspRate, + outputRate); + + OpenChannel(rx, + buffer_size, + fft_size, + sample_rate, + dspRate, + outputRate, + 0, // receive + 1, // run + 0.010, 0.025, 0.0, 0.010, 0); + + while (gtk_events_pending ()) + gtk_main_iteration (); + + switch(sample_rate) { + case 48000: + tx_buffer_size=BUFFER_SIZE; + break; + case 96000: + tx_buffer_size=BUFFER_SIZE/2; + break; + case 192000: + tx_buffer_size=BUFFER_SIZE/4; + break; + case 384000: + tx_buffer_size=BUFFER_SIZE/8; + break; + } + fprintf(stderr,"OpenChannel %d buffer_size=%d fft_size=%d sample_rate=%d dspRate=%d outputRate=%d\n", + CHANNEL_TX, + tx_buffer_size, + fft_size, + sample_rate, //micSampleRate, + micDspRate, + micOutputRate); + + OpenChannel(CHANNEL_TX, + buffer_size, + fft_size, + sample_rate, //micSampleRate, + micDspRate, + micOutputRate, + 1, // transmit + 1, // run + 0.010, 0.025, 0.0, 0.010, 0); + + while (gtk_events_pending ()) + gtk_main_iteration (); + + fprintf(stderr,"XCreateAnalyzer %d\n",rx); + int success; + XCreateAnalyzer(rx, &success, 262144, 1, 1, ""); + if (success != 0) { + fprintf(stderr, "XCreateAnalyzer %d failed: %d\n" ,rx,success); + } + initAnalyzer(rx,buffer_size); + + while (gtk_events_pending ()) + gtk_main_iteration (); + + XCreateAnalyzer(CHANNEL_TX, &success, 262144, 1, 1, ""); + if (success != 0) { + fprintf(stderr, "XCreateAnalyzer CHANNEL_TX failed: %d\n" ,success); + } + initAnalyzer(CHANNEL_TX,tx_buffer_size); + + SetRXAMode(rx, mode); + SetRXABandpassFreqs(rx, (double)filterLow, (double)filterHigh); + SetRXAAGCMode(rx, agc); + SetRXAAGCTop(rx,agc_gain); + + SetRXAAMDSBMode(CHANNEL_RX0, 0); + SetRXAShiftRun(CHANNEL_RX0, 0); + SetRXAEMNRgainMethod(CHANNEL_RX0, 1); + SetRXAEMNRnpeMethod(CHANNEL_RX0, 0); + SetRXAEMNRaeRun(CHANNEL_RX0, 1); + SetRXAEMNRPosition(CHANNEL_RX0, 0); + SetRXAEMNRRun(CHANNEL_RX0, 0); + SetRXAANRRun(CHANNEL_RX0, 0); + SetRXAANFRun(CHANNEL_RX0, 0); + + SetTXAMode(CHANNEL_TX, mode); + SetTXABandpassFreqs(CHANNEL_TX, (double)filterLow, (double)filterHigh); + SetTXABandpassWindow(CHANNEL_TX, 1); + SetTXABandpassRun(CHANNEL_TX, 1); + + SetTXACFIRRun(CHANNEL_TX, 1); + SetTXAEQRun(CHANNEL_TX, 0); + SetTXACTCSSRun(CHANNEL_TX, 0); + SetTXAAMSQRun(CHANNEL_TX, 0); + SetTXACompressorRun(CHANNEL_TX, 0); + SetTXAosctrlRun(CHANNEL_TX, 0); + SetTXAPreGenRun(CHANNEL_TX, 0); + SetTXAPostGenRun(CHANNEL_TX, 0); + +} + +static void initAnalyzer(int channel,int buffer_size) { + int flp[] = {0}; + double KEEP_TIME = 0.1; + int n_pixout=1; + int spur_elimination_ffts = 1; + int data_type = 1; + int fft_size = 8192; + int window_type = 4; + double kaiser_pi = 14.0; + int overlap = 2048; + int clip = 0; + int span_clip_l = 0; + int span_clip_h = 0; + int pixels=spectrumWIDTH; + int stitches = 1; + int avm = 0; + double tau = 0.001 * 120.0; + int MAX_AV_FRAMES = 60; + int display_average = MAX(2, (int) MIN((double) MAX_AV_FRAMES, (double) SPECTRUM_UPDATES_PER_SECOND * tau)); + double avb = exp(-1.0 / (SPECTRUM_UPDATES_PER_SECOND * tau)); + int calibration_data_set = 0; + double span_min_freq = 0.0; + double span_max_freq = 0.0; + + int max_w = fft_size + (int) MIN(KEEP_TIME * (double) SPECTRUM_UPDATES_PER_SECOND, KEEP_TIME * (double) fft_size * (double) SPECTRUM_UPDATES_PER_SECOND); + + fprintf(stderr,"SetAnalyzer channel=%d\n",channel); + SetAnalyzer(channel, + n_pixout, + spur_elimination_ffts, //number of LO frequencies = number of ffts used in elimination + data_type, //0 for real input data (I only); 1 for complex input data (I & Q) + flp, //vector with one elt for each LO frequency, 1 if high-side LO, 0 otherwise + fft_size, //size of the fft, i.e., number of input samples + buffer_size, //number of samples transferred for each OpenBuffer()/CloseBuffer() + window_type, //integer specifying which window function to use + kaiser_pi, //PiAlpha parameter for Kaiser window + overlap, //number of samples each fft (other than the first) is to re-use from the previous + clip, //number of fft output bins to be clipped from EACH side of each sub-span + span_clip_l, //number of bins to clip from low end of entire span + span_clip_h, //number of bins to clip from high end of entire span + pixels, //number of pixel values to return. may be either <= or > number of bins + stitches, //number of sub-spans to concatenate to form a complete span +/* + avm, //averaging mode + display_average, //number of spans to (moving) average for pixel result + avb, //back multiplier for weighted averaging +*/ + calibration_data_set, //identifier of which set of calibration data to use + span_min_freq, //frequency at first pixel value8192 + span_max_freq, //frequency at last pixel value + max_w //max samples to hold in input ring buffers + ); +} diff --git a/wdsp_init.h b/wdsp_init.h new file mode 100644 index 0000000..041737d --- /dev/null +++ b/wdsp_init.h @@ -0,0 +1,25 @@ +/* Copyright (C) +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +extern void setMode(int m); +extern int getMode(); +extern void setFilter(int low,int high); +extern int getFilterLow(); +extern int getFilterHigh(); +extern void wdsp_init(int rx,int pixels,int protocol); diff --git a/xvtr.h b/xvtr.h index bc948d6..4c8f448 100644 --- a/xvtr.h +++ b/xvtr.h @@ -1,14 +1,7 @@ -/** -* @file xvtr.h -* @brief XVTR definition files -* @author John Melton, G0ORX/N6LYT, Doxygen Comments Dave Larsen, KV0S -* @version 0.1 -* @date 2009-04-11 -*/ -// xvtr.h - /* Copyright (C) -* This program is free software; you can redistribute it and/or2009 - John Melton, G0ORX/N6LYT, Doxygen Comments Dave Larsen, KV0S +* 2015 - John Melton, G0ORX/N6LYT +* +* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version.