From: pa3gsb Date: Sun, 25 Feb 2018 13:56:58 +0000 (+0100) Subject: merge X-Git-Url: https://git.rkrishnan.org/pf/$top_link?a=commitdiff_plain;h=6901a4cbeacefcaa3fbaa9e38de7dc2832b59af0;p=pihpsdr.git merge --- 6901a4cbeacefcaa3fbaa9e38de7dc2832b59af0 diff --cc Makefile index b069e86,d0b4fcd..f4aa416 --- a/Makefile +++ b/Makefile @@@ -30,6 -30,6 +30,13 @@@ LOCALCW_INCLUDE=LOCALC # uncomment the line below to include support for STEMlab discovery #STEMLAB_DISCOVERY=STEMLAB_DISCOVERY ++#uncomment the line below for the platform being compiled on ++UNAME_N=raspberrypi ++#UNAME_N=odroid ++#UNAME_N=up ++#UNAME_N=pine64 ++#UNAME_N=jetsen ++ CC=gcc LINK=gcc @@@ -138,16 -137,19 +145,18 @@@ endi ifeq ($(LOCALCW_INCLUDE),LOCALCW) LOCALCW_OPTIONS=-D LOCALCW LOCALCW_SOURCES= \ + beep.c \ iambic.c LOCALCW_HEADERS= \ + beep.h \ iambic.h LOCALCW_OBJS= \ -beep.o \ iambic.o endif ifeq ($(GPIO_INCLUDE),GPIO) GPIO_OPTIONS=-D GPIO - GPIO_LIBS=-lwiringPi -lpigpio - GPIO_LIBS=-lwiringPi ++ GPIO_LIBS=-lwiringPi -lpigpio GPIO_SOURCES= \ gpio.c \ encoder_menu.c diff --cc Makefile.orig index ff0926d,ff0926d..a43e6b9 --- a/Makefile.orig +++ b/Makefile.orig @@@ -6,30 -6,30 +6,32 @@@ GIT_VERSION := $(shell git describe --a # uncomment the line below to include GPIO GPIO_INCLUDE=GPIO ++# uncomment the line below to include MCP23017 I2C ++#I2C_INCLUDE=I2C ++ # uncomment the line below to include USB Ozy support --USBOZY_INCLUDE=USBOZY ++# USBOZY_INCLUDE=USBOZY # uncomment the line below to include support for psk31 #PSK_INCLUDE=PSK # uncomment the line to below include support for FreeDV codec2 --#FREEDV_INCLUDE=FREEDV ++FREEDV_INCLUDE=FREEDV ++ ++# uncomment the line below to include Pure Signal support ++#PURESIGNAL_INCLUDE=PURESIGNAL ++ ++# uncomment the line below to include Pure Signal support ++#PURESIGNAL_INCLUDE=PURESIGNAL # uncomment the line to below include support for sx1509 i2c expander #SX1509_INCLUDE=sx1509 # uncomment the line to below include support local CW keyer --#LOCALCW_INCLUDE=LOCALCW ++LOCALCW_INCLUDE=LOCALCW --# uncomment the line below to include MCP23017 I2C --#I2C_INCLUDE=I2C -- --#uncomment the line below for the platform being compiled on --UNAME_N=raspberrypi --#UNAME_N=odroid --#UNAME_N=up --#UNAME_N=pine64 --#UNAME_N=x86 ++# uncomment the line below to include support for STEMlab discovery ++#STEMLAB_DISCOVERY=STEMLAB_DISCOVERY CC=gcc LINK=gcc @@@ -37,6 -37,6 +39,29 @@@ # uncomment the line below for various debug facilities #DEBUG_OPTION=-D DEBUG ++ifeq ($(PURESIGNAL_INCLUDE),PURESIGNAL) ++PURESIGNAL_OPTIONS=-D PURESIGNAL ++PURESIGNAL_SOURCES= \ ++ps_menu.c ++PURESIGNAL_HEADERS= \ ++ps_menu.h ++PURESIGNAL_OBJS= \ ++ps_menu.o ++endif ++ ++ifeq ($(REMOTE_INCLUDE),REMOTE) ++REMOTE_OPTIONS=-D REMOTE ++REMOTE_SOURCES= \ ++remote_radio.c \ ++remote_receiver.c ++REMOTE_HEADERS= \ ++remote_radio.h \ ++remote_receiver.h ++REMOTE_OBJS= \ ++remote_radio.o \ ++remote_receiver.o ++endif ++ ifeq ($(USBOZY_INCLUDE),USBOZY) USBOZY_OPTIONS=-D USBOZY USBOZY_LIBS=-lusb-1.0 @@@ -56,6 -56,6 +81,7 @@@ RADIOBERRY_INCLUDE=RADIOBERR ifeq ($(RADIOBERRY_INCLUDE),RADIOBERRY) RADIOBERRY_OPTIONS=-D RADIOBERRY ++RADIOBERRYLIBS=-lpigpio RADIOBERRY_SOURCES= \ radioberry_discovery.c \ radioberry.c @@@ -115,31 -115,31 +141,19 @@@ endi ifeq ($(LOCALCW_INCLUDE),LOCALCW) LOCALCW_OPTIONS=-D LOCALCW LOCALCW_SOURCES= \ --beep.c \ iambic.c LOCALCW_HEADERS= \ --beep.h \ iambic.h LOCALCW_OBJS= \ --beep.o \ iambic.o endif ifeq ($(GPIO_INCLUDE),GPIO) GPIO_OPTIONS=-D GPIO <<<<<<< HEAD -- GPIO_LIBS=-lwiringPi -lpigpio -- endif -- ifeq ($(UNAME_N),odroid) -- GPIO_LIBS=-lwiringPi -- endif -- ifeq ($(SX1509_INCLUDE),sx1509) -- GPIO_OPTIONS=-D GPIO -- GPIO_OPTIONS+=-D sx1509 -- GPIO_LIBS+=-lsx1509 -- endif --======= GPIO_LIBS=-lwiringPi -lpigpio ++======= ++ GPIO_LIBS=-lwiringPi >>>>>>> upstream/master GPIO_SOURCES= \ gpio.c \ @@@ -159,8 -159,8 +173,15 @@@ ifeq ($(I2C_INCLUDE),I2C I2C_OBJS=i2c.o endif --#uncomment if build for SHORT FRAMES (MIC and Audio) --SHORT_FRAMES=-D SHORT_FRAMES ++ifeq ($(STEMLAB_DISCOVERY), STEMLAB_DISCOVERY) ++STEMLAB_OPTIONS=-D STEMLAB_DISCOVERY \ ++ `pkg-config --cflags avahi-gobject` \ ++ `pkg-config --cflags libcurl` ++STEMLAB_LIBS=`pkg-config --libs avahi-gobject` `pkg-config --libs libcurl` ++STEMLAB_SOURCES=stemlab_discovery.c ++STEMLAB_HEADERS=stemlab_discovery.h ++STEMLAB_OBJS=stemlab_discovery.o ++endif GTKINCLUDES=`pkg-config --cflags gtk+-3.0` GTKLIBS=`pkg-config --libs gtk+-3.0` @@@ -168,21 -168,21 +189,25 @@@ AUDIO_LIBS=-lasound #AUDIO_LIBS=-lsoundio ++OPTIONS=-g -Wno-deprecated-declarations $(PURESIGNAL_OPTIONS) $(REMOTE_OPTIONS) $(RADIOBERRY_OPTIONS) $(USBOZY_OPTIONS) $(I2C_OPTIONS) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(PSK_OPTIONS) $(STEMLAB_OPTIONS) -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(DEBUG_OPTION) -O3 ++ <<<<<<< HEAD --OPTIONS=-g -D $(UNAME_N) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) $(RADIOBERRY_OPTIONS) $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(PSK_OPTIONS) $(SHORT_FRAMES) -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(DEBUG_OPTION) -O3 ++LIBS=-lrt -lm -lwdsp -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(PSKLIBS) $(GTKLIBS) $(GPIO_LIBS) $(RADIOBERRYLIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS) $(STEMLAB_LIBS) ======= --OPTIONS=-g -Wno-deprecated-declarations -D $(UNAME_N) $(USBOZY_OPTIONS) $(I2C_OPTIONS) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(PSK_OPTIONS) $(SHORT_FRAMES) -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(DEBUG_OPTION) -O3 ++LIBS=-lrt -lm -lwdsp -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(PSKLIBS) $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS) $(STEMLAB_LIBS) >>>>>>> upstream/master -- --LIBS=-lrt -lm -lwdsp -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(PSKLIBS) $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS) INCLUDES=$(GTKINCLUDES) COMPILE=$(CC) $(OPTIONS) $(INCLUDES) ++.c.o: ++ $(COMPILE) -c -o $@ $< ++ PROGRAM=pihpsdr SOURCES= \ audio.c \ ++audio_waterfall.c \ band.c \ configure.c \ frequency.c \ @@@ -191,6 -191,6 +216,7 @@@ discovery.c filter.c \ main.c \ new_menu.c \ ++about_menu.c \ exit_menu.c \ radio_menu.c \ rx_menu.c \ @@@ -211,6 -211,6 +237,7 @@@ filter_menu.c noise_menu.c \ agc_menu.c \ vox_menu.c \ ++fft_menu.c \ diversity_menu.c \ freqent_menu.c \ tx_menu.c \ @@@ -229,6 -229,6 +256,7 @@@ property.c radio.c \ receiver.c \ rigctl.c \ ++rigctl_menu.c \ toolbar.c \ transmitter.c \ sliders.c \ @@@ -240,11 -240,11 +268,15 @@@ vox.c update.c \ store.c \ store_menu.c \ --memory.c ++memory.c \ ++led.c \ ++ext.c \ ++error_handler.c HEADERS= \ audio.h \ ++audio_waterfall.h \ agc.h \ alex.h \ band.h \ @@@ -256,6 -256,6 +288,7 @@@ discovered.h discovery.h \ filter.h \ new_menu.h \ ++about_menu.h \ rx_menu.h \ exit_menu.h \ radio_menu.h \ @@@ -276,6 -276,6 +309,7 @@@ filter_menu.h noise_menu.h \ agc_menu.h \ vox_menu.h \ ++fft_menu.h \ diversity_menu.h \ freqent_menu.h \ tx_menu.h \ @@@ -293,6 -293,6 +327,7 @@@ property.h radio.h \ receiver.h \ rigctl.h \ ++rigctl_menu.h \ toolbar.h \ transmitter.h \ sliders.h \ @@@ -304,11 -304,11 +339,15 @@@ vox.h update.h \ store.h \ store_menu.h \ --memory.h ++memory.h \ ++led.h \ ++ext.h \ ++error_handler.h OBJS= \ audio.o \ ++audio_waterfall.o \ band.o \ configure.o \ frequency.o \ @@@ -318,6 -318,6 +357,7 @@@ filter.o version.o \ main.o \ new_menu.o \ ++about_menu.o \ rx_menu.o \ exit_menu.o \ radio_menu.o \ @@@ -338,6 -338,6 +378,7 @@@ filter_menu.o noise_menu.o \ agc_menu.o \ vox_menu.o \ ++fft_menu.o \ diversity_menu.o \ freqent_menu.o \ tx_menu.o \ @@@ -356,6 -356,6 +397,7 @@@ property.o radio.o \ receiver.o \ rigctl.o \ ++rigctl_menu.o \ toolbar.o \ transmitter.o \ sliders.o \ @@@ -366,37 -366,37 +408,28 @@@ vox.o update.o \ store.o \ store_menu.o \ --memory.o ++memory.o \ ++led.o \ ++ext.o \ ++error_handler.o --<<<<<<< HEAD --all: prebuild $(PROGRAM) $(HEADERS) $(LIMESDR_HEADERS) $(RADIOBERRY_HEADERS) $(FREEDV_HEADERS) $(LOCALCW_HEADERS) $(GPIO_HEADERS) $(PSK_HEADERS) $(SOURCES) $(LIMESDR_SOURCES) $(RADIOBERRY_SOURCES) $(FREEDV_SOURCES) $(GPIO_SOURCES) $(PSK_SOURCES) --======= --all: prebuild $(PROGRAM) $(HEADERS) $(USBOZY_HEADERS) $(LIMESDR_HEADERS) $(FREEDV_HEADERS) $(LOCALCW_HEADERS) $(I2C_HEADERS) $(GPIO_HEADERS) $(PSK_HEADERS) $(SOURCES) $(USBOZY_SOURCES) $(LIMESDR_SOURCES) $(FREEDV_SOURCES) $(I2C_SOURCES) $(GPIO_SOURCES) $(PSK_SOURCES) -->>>>>>> upstream/master ++$(PROGRAM): $(OBJS) $(REMOTE_OBJS) $(USBOZY_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(I2C_OBJS) $(GPIO_OBJS) $(PSK_OBJS) $(RADIOBERRY_OBJS) $(PURESIGNAL_OBJS) $(STEMLAB_OBJS) ++ $(LINK) -o $(PROGRAM) $(OBJS) $(REMOTE_OBJS) $(USBOZY_OBJS) $(I2C_OBJS) $(GPIO_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(PSK_OBJS) $(LIBS) $(RADIOBERRY_OBJS) $(PURESIGNAL_OBJS) $(STEMLAB_OBJS) ++ ++all: prebuild $(PROGRAM) $(HEADERS) $(REMOTE_HEADERS) $(RADIOBERRY_HEADERS) $(USBOZY_HEADERS) $(LIMESDR_HEADERS) $(FREEDV_HEADERS) $(LOCALCW_HEADERS) $(I2C_HEADERS) $(GPIO_HEADERS) $(PSK_HEADERS) $(PURESIGNAL_HEADERS) $(STEMLAB_HEADERS) $(SOURCES) $(REMOTE_SOURCES) $(USBOZY_SOURCES) $(LIMESDR_SOURCES) $(FREEDV_SOURCES) $(I2C_SOURCES) $(GPIO_SOURCES) $(PSK_SOURCES) $(RADIOBERRY_SOURCES) $(PURESIGNAL_SOURCES) $(STEMLAB_SOURCES) prebuild: rm -f version.o --<<<<<<< HEAD --$(PROGRAM): $(OBJS) $(LIMESDR_OBJS) $(RADIOBERRY_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(GPIO_OBJS) $(PSK_OBJS) -- $(LINK) -o $(PROGRAM) $(OBJS) $(GPIO_OBJS) $(LIMESDR_OBJS) $(RADIOBERRY_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(PSK_OBJS) $(LIBS) --======= --$(PROGRAM): $(OBJS) $(USBOZY_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(I2C_OBJS) $(GPIO_OBJS) $(PSK_OBJS) -- $(LINK) -o $(PROGRAM) $(OBJS) $(USBOZY_OBJS) $(I2C_OBJS) $(GPIO_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(PSK_OBJS) $(LIBS) -->>>>>>> upstream/master -- --.c.o: -- $(COMPILE) -c -o $@ $< -- -- clean: -rm -f *.o -rm -f $(PROGRAM) --install: -- cp pihpsdr ../pihpsdr -- cp pihpsdr ./release/pihpsdr -- cd release; echo $(GIT_VERSION) > pihpsdr/latest -- cd release; tar cvf pihpsdr_$(GIT_VERSION).tar pihpsdr ++install: $(PROGRAM) ++ cp $(PROGRAM) /usr/local/bin ++ ++release: $(PROGRAM) ++ cp $(PROGRAM) release/pihpsdr cd release; tar cvf pihpsdr.tar pihpsdr ++ cd release; tar cvf pihpsdr-$(GIT_VERSION).tar pihpsdr diff --cc audio.c index 4924159,b689bd7..cb668d5 --- a/audio.c +++ b/audio.c @@@ -159,9 -164,8 +167,10 @@@ fprintf(stderr,"audio_open_output: hand rx->playback_offset=0; rx->playback_buffer=(unsigned char *)malloc(OUTPUT_BUFFER_SIZE); + + playback_cw_buffer = (unsigned char *)malloc(OUTPUT_BUFFER_SIZE); + fprintf(stderr,"audio_open_output: rx=%d audio_device=%d handle=%p buffer=%p\n",rx->id,rx->audio_device,rx->playback_handle,rx->playback_buffer); return 0; } diff --cc gpio.c index d573739,183bd74..2d51acc --- a/gpio.c +++ b/gpio.c @@@ -66,7 -62,7 +62,9 @@@ int settle_time=DEFAULT_SETTLE_TIME; static gint release_timer=-1; -- ++#ifdef RADIOBERRY ++#include ++#endif #ifdef CONTROLLER2 @@@ -839,15 -832,6 +837,7 @@@ void gpio_restore_state() if(value) ENABLE_E4_BUTTON=atoi(value); #endif - #ifdef LOCALCW - value=getProperty("ENABLE_CW_BUTTONS"); - if(value) ENABLE_CW_BUTTONS=atoi(value); - value=getProperty("CWL_BUTTON"); - if(value) CWL_BUTTON=atoi(value); - value=getProperty("CWR_BUTTON"); - if(value) CWR_BUTTON=atoi(value); - #endif + } void gpio_save_state() { @@@ -970,56 -944,6 +950,55 @@@ fprintf(stderr,"setup_encoder_pin: pin= wiringPiISR(pin,INT_EDGE_RISING,pAlert); } +#ifdef LOCALCW +#ifdef RADIOBERRY +#define BUTTON_STEADY_TIME_US 5000 +static void setup_button(int button, gpioAlertFunc_t pAlert) { + gpioSetMode(button, PI_INPUT); + gpioSetPullUpDown(button,PI_PUD_UP); + // give time to settle to avoid false triggers + usleep(10000); + gpioSetAlertFunc(button, pAlert); + gpioGlitchFilter(button, BUTTON_STEADY_TIME_US); +} + +static void cwAlert(int gpio, int level, uint32_t tick) { + //fprintf(stderr,"cw key at pin %d \n", gpio); + if (cw_keyer_internal == 0 ){ + //fprintf(stderr,"call keyer_event...\n"); + keyer_event(gpio, cw_active_level == 0 ? level : (level==0)); + } +} + +/* +static unsigned long cwl_debounce=0; +static void cwlAlert() { + int t=millis(); + if(t - cwl_debounce > settle_time) { + int level=digitalRead(CWL_BUTTON); + if (cw_keyer_internal == 0 ){ + fprintf(stderr,"call keyer_event CWL Button \n"); + keyer_event(CWL_BUTTON, cw_active_level == 0 ? level : (level==0)); + } + cwl_debounce=t; + } +} - +static unsigned long cwr_debounce=0; +static void cwrAlert() { + int t=millis(); + if(t - cwr_debounce > settle_time) { + int level=digitalRead(CWR_BUTTON); + if (cw_keyer_internal == 0 ){ + fprintf(stderr,"call keyer_event CWR Button \n"); + keyer_event(CWR_BUTTON, cw_active_level == 0 ? level : (level==0)); + } + cwr_debounce=t; + } +} +*/ +#endif +#endif + int gpio_init() { int i; diff --cc gpio.c.orig index 0000000,0000000..72ecd23 new file mode 100644 --- /dev/null +++ b/gpio.c.orig @@@ -1,0 -1,0 +1,1570 @@@ ++/* 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 "band.h" ++#include "channel.h" ++#include "discovered.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" ++#include "vfo.h" ++#include "wdsp.h" ++#ifdef PSK ++#include "psk.h" ++#endif ++#include "new_menu.h" ++#include "encoder_menu.h" ++#include "gpio.h" ++#ifdef CONTROLLER2 ++#include "i2c.h" ++#endif ++#include "ext.h" ++#include "sliders.h" ++ ++<<<<<<< HEAD ++#ifdef RADIOBERRY ++#include ++#endif ++ ++// debounce settle time in ms ++#define DEFAULT_SETTLE_TIME 150 ++ ++int settle_time=DEFAULT_SETTLE_TIME; ++static gint release_timer=-1; ++ ++ ++======= ++// debounce settle time in ms ++#define DEFAULT_SETTLE_TIME 150 ++ ++int settle_time=DEFAULT_SETTLE_TIME; ++static gint release_timer=-1; ++ ++ ++>>>>>>> upstream/master ++#ifdef CONTROLLER2 ++ ++int ENABLE_VFO_ENCODER=1; ++int ENABLE_VFO_PULLUP=0; ++int VFO_ENCODER_A=1; ++int VFO_ENCODER_B=0; ++#ifdef VFO_HAS_FUNCTION ++int VFO_FUNCTION=12; ++#endif ++int ENABLE_E1_ENCODER=1; ++int ENABLE_E1_PULLUP=0; ++int E1_ENCODER_A=28; ++int E1_ENCODER_B=25; ++int E1_FUNCTION=3; ++int ENABLE_E2_ENCODER=1; ++int ENABLE_E2_PULLUP=0; ++int E2_ENCODER_A=7; ++int E2_ENCODER_B=29; ++int E2_FUNCTION=2; ++int ENABLE_E3_ENCODER=1; ++int ENABLE_E3_PULLUP=0; ++int E3_ENCODER_A=27; ++int E3_ENCODER_B=24; ++int E3_FUNCTION=4; ++int ENABLE_E4_ENCODER=1; ++int ENABLE_E4_PULLUP=0; ++int E4_ENCODER_A=6; ++int E4_ENCODER_B=10; ++int E4_FUNCTION=5; ++ ++int ENABLE_E1_BUTTON=1; ++int ENABLE_E2_BUTTON=1; ++int ENABLE_E3_BUTTON=1; ++int ENABLE_E4_BUTTON=1; ++ ++int I2C_INTERRUPT=16; ++ ++#else ++// uses wiringpi pin numbers ++int ENABLE_VFO_ENCODER=1; ++int ENABLE_VFO_PULLUP=1; ++int VFO_ENCODER_A=1; ++int VFO_ENCODER_B=0; ++int ENABLE_E1_ENCODER=1; ++int ENABLE_E1_PULLUP=0; ++int E1_ENCODER_A=28; ++int E1_ENCODER_B=25; ++int E1_FUNCTION=6; ++int ENABLE_E2_ENCODER=1; ++int ENABLE_E2_PULLUP=0; ++int E2_ENCODER_A=27; ++int E2_ENCODER_B=24; ++int E2_FUNCTION=10; ++int ENABLE_E3_ENCODER=1; ++int ENABLE_E3_PULLUP=0; ++int E3_ENCODER_A=7; ++int E3_ENCODER_B=29; ++int E3_FUNCTION=11; ++int ENABLE_S1_BUTTON=1; ++int S1_BUTTON=23; ++int ENABLE_S2_BUTTON=1; ++int S2_BUTTON=26; ++int ENABLE_S3_BUTTON=1; ++int S3_BUTTON=22; ++int ENABLE_S4_BUTTON=1; ++int S4_BUTTON=21; ++int ENABLE_S5_BUTTON=1; ++int S5_BUTTON=5; ++int ENABLE_S6_BUTTON=1; ++int S6_BUTTON=4; ++int ENABLE_MOX_BUTTON=1; ++int MOX_BUTTON=2; ++int ENABLE_FUNCTION_BUTTON=1; ++int FUNCTION_BUTTON=3; ++int ENABLE_E1_BUTTON=1; ++int ENABLE_E2_BUTTON=1; ++int ENABLE_E3_BUTTON=1; ++int ENABLE_CW_BUTTONS=1; ++#endif ++<<<<<<< HEAD ++#ifdef LOCALCW ++int CWL_BUTTON=1; ++int CWR_BUTTON=24; ++#endif ++======= ++ ++>>>>>>> upstream/master ++ ++static volatile int vfoEncoderPos; ++static volatile int vfo_A; ++static volatile int vfo_B; ++static volatile int vfoFunction; ++static volatile int e1EncoderPos; ++static volatile int e1Function; ++int e1_encoder_action=ENCODER_AF_GAIN; ++static volatile int e2EncoderPos; ++static volatile int e2Function; ++int e2_encoder_action=ENCODER_DRIVE; ++static volatile int e3EncoderPos; ++static volatile int e3Function; ++int e3_encoder_action=ENCODER_ATTENUATION; ++#ifdef CONTROLLER2 ++static volatile int e4EncoderPos; ++static volatile int e4Function; ++int e4_encoder_action=ENCODER_MIC_GAIN; ++#endif ++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 gpointer rotary_encoder_thread(gpointer data); ++static GThread *rotary_encoder_thread_id; ++ ++static int previous_function_button=0; ++static int e1_function=0; ++static int previous_e1_function=0; ++static int e2_function=0; ++static int previous_e2_function=0; ++static int e3_function=0; ++static int previous_e3_function=0; ++#ifdef CONTROLLER2 ++static int e4_function=0; ++static int previous_e4_function=0; ++#endif ++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 running=0; ++ ++char *encoder_string[] = { ++"AF GAIN", ++"AGC GAIN", ++"ATTENUATION", ++"MIC GAIN", ++"DRIVE", ++"RIT", ++"CW SPEED", ++"CW FREQUENCY", ++"PANADAPTER HIGH", ++"PANADAPTER LOW", ++"SQUELCH", ++"COMP" ++}; ++ ++static int mox_pressed(void *data) { ++ if(running) sim_mox_cb(NULL,NULL); ++ return 0; ++} ++ ++static int s1_pressed(void *data) { ++ if(running) sim_s1_pressed_cb(NULL,NULL); ++ return 0; ++} ++ ++static int s1_released(void *data) { ++ if(running) sim_s1_released_cb(NULL,NULL); ++ return 0; ++} ++ ++static int s2_pressed(void *data) { ++ if(running) sim_s2_pressed_cb(NULL,NULL); ++ return 0; ++} ++ ++static int s2_released(void *data) { ++ if(running) sim_s2_released_cb(NULL,NULL); ++ return 0; ++} ++ ++static int s3_pressed(void *data) { ++ if(running) sim_s3_pressed_cb(NULL,NULL); ++ return 0; ++} ++ ++static int s3_released(void *data) { ++ if(running) sim_s3_released_cb(NULL,NULL); ++ return 0; ++} ++ ++static int s4_pressed(void *data) { ++ if(running) sim_s4_pressed_cb(NULL,NULL); ++ return 0; ++} ++ ++static int s4_released(void *data) { ++ if(running) sim_s4_released_cb(NULL,NULL); ++ return 0; ++} ++ ++static int s5_pressed(void *data) { ++ if(running) sim_s5_pressed_cb(NULL,NULL); ++ return 0; ++} ++ ++static int s5_released(void *data) { ++ if(running) sim_s5_released_cb(NULL,NULL); ++ return 0; ++} ++ ++static int s6_pressed(void *data) { ++ if(running) sim_s6_pressed_cb(NULL,NULL); ++ return 0; ++} ++ ++static int s6_released(void *data) { ++ if(running) sim_s6_released_cb(NULL,NULL); ++ return 0; ++} ++ ++static int function_pressed(void *data) { ++ if(running) sim_function_cb(NULL,NULL); ++ return 0; ++} ++ ++static int vfo_function_pressed(void *data) { ++ RECEIVER *rx; ++ if(receivers==2) { ++ if(active_receiver==receiver[0]) { ++ rx=receiver[1]; ++ } else { ++ rx=receiver[0]; ++ } ++ active_receiver=rx; ++ g_idle_add(menu_active_receiver_changed,NULL); ++ g_idle_add(ext_vfo_update,NULL); ++ g_idle_add(sliders_active_receiver_changed,NULL); ++ } ++ return 0; ++} ++ ++static int vfo_function_released(void *data) { ++ return 0; ++} ++ ++static int e_function_pressed(void *data) { ++ int encoder=(int)data; ++ start_encoder(encoder); ++ return 0; ++} ++ ++static unsigned long e1debounce=0; ++ ++static void e1FunctionAlert() { ++ int level=digitalRead(E1_FUNCTION); ++ if(level==0) { ++ if(running) g_idle_add(e_function_pressed,(gpointer)1); ++ } ++} ++ ++static unsigned long e2debounce=0; ++ ++static void e2FunctionAlert() { ++ int level=digitalRead(E2_FUNCTION); ++ if(level==0) { ++ if(running) g_idle_add(e_function_pressed,(gpointer)2); ++ } ++} ++ ++static unsigned long e3debounce=0; ++ ++static void e3FunctionAlert() { ++ int level=digitalRead(E3_FUNCTION); ++ if(level==0) { ++ if(running) g_idle_add(e_function_pressed,(gpointer)3); ++ } ++} ++ ++#ifdef CONTROLLER2 ++static unsigned long e4debounce=0; ++ ++static void e4FunctionAlert() { ++ int level=digitalRead(E4_FUNCTION); ++ if(level==0) { ++ if(running) g_idle_add(e_function_pressed,(gpointer)4); ++ } ++} ++#endif ++ ++#ifndef CONTROLLER2 ++static unsigned long function_debounce=0; ++ ++static void functionAlert() { ++ int t=millis(); ++ if(t-function_debounce > settle_time) { ++ int level=digitalRead(FUNCTION_BUTTON); ++ if(level==0) { ++ if(running) g_idle_add(function_pressed,NULL); ++ } ++ function_debounce=t; ++ } ++} ++ ++static unsigned long s1_debounce=0; ++static gint s1_timer=-1; ++ ++static gboolean s1_timer_cb(gpointer data) { ++ int level=digitalRead(S1_BUTTON); ++ if(level==1) { ++ s1_timer=-1; ++ g_idle_add(s1_released,NULL); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++static void s1Alert() { ++ int t=millis(); ++ if(t-s1_debounce > settle_time) { ++ int level=digitalRead(S1_BUTTON); ++ if(level==0) { ++ g_idle_add(s1_pressed,NULL); ++ s1_timer=g_timeout_add(settle_time,s1_timer_cb,NULL); ++ } else { ++ if(s1_timer!=-1) { ++ g_source_remove(s1_timer); ++ s1_timer==-1; ++ } ++ g_idle_add(s1_released,NULL); ++ } ++ s1_debounce=t; ++ } ++} ++ ++static unsigned long s2_debounce=0; ++static gint s2_timer=-1; ++ ++static gboolean s2_timer_cb(gpointer data) { ++ int level=digitalRead(S2_BUTTON); ++ if(level==1) { ++ s2_timer=-1; ++ g_idle_add(s2_released,NULL); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++static void s2Alert() { ++ int t=millis(); ++ if(t-s2_debounce > settle_time) { ++ int level=digitalRead(S2_BUTTON); ++ if(level==0) { ++ g_idle_add(s2_pressed,NULL); ++ s2_timer=g_timeout_add(settle_time,s2_timer_cb,NULL); ++ } else { ++ if(s2_timer!=-1) { ++ g_source_remove(s2_timer); ++ s2_timer==-1; ++ } ++ g_idle_add(s2_released,NULL); ++ } ++ s2_debounce=t; ++ } ++} ++ ++static unsigned long s3_debounce=0; ++static gint s3_timer=-1; ++ ++static gboolean s3_timer_cb(gpointer data) { ++ int level=digitalRead(S3_BUTTON); ++ if(level==1) { ++ s3_timer=-1; ++ g_idle_add(s3_released,NULL); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++static void s3Alert() { ++ int t=millis(); ++ if(t-s3_debounce > settle_time) { ++ int level=digitalRead(S3_BUTTON); ++ if(level==0) { ++ g_idle_add(s3_pressed,NULL); ++ s3_timer=g_timeout_add(settle_time,s3_timer_cb,NULL); ++ } else { ++ if(s3_timer!=-1) { ++ g_source_remove(s3_timer); ++ s3_timer==-1; ++ } ++ g_idle_add(s3_released,NULL); ++ } ++ s3_debounce=t; ++ } ++} ++ ++static unsigned long s4_debounce=0; ++static gint s4_timer=-1; ++ ++static gboolean s4_timer_cb(gpointer data) { ++ int level=digitalRead(S4_BUTTON); ++ if(level==1) { ++ s4_timer=-1; ++ g_idle_add(s4_released,NULL); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++static void s4Alert() { ++ int t=millis(); ++ if(t-s4_debounce > settle_time) { ++ int level=digitalRead(S4_BUTTON); ++ if(level==0) { ++ g_idle_add(s4_pressed,NULL); ++ s4_timer=g_timeout_add(settle_time,s4_timer_cb,NULL); ++ } else { ++ if(s4_timer!=-1) { ++ g_source_remove(s4_timer); ++ s4_timer==-1; ++ } ++ g_idle_add(s4_released,NULL); ++ } ++ s4_debounce=t; ++ } ++} ++ ++static unsigned long s5_debounce=0; ++static gint s5_timer=-1; ++ ++static gboolean s5_timer_cb(gpointer data) { ++ int level=digitalRead(S5_BUTTON); ++ if(level==1) { ++ s5_timer=-1; ++ g_idle_add(s5_released,NULL); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++static void s5Alert() { ++ int t=millis(); ++ if(t-s5_debounce > settle_time) { ++ int level=digitalRead(S5_BUTTON); ++ if(level==0) { ++ g_idle_add(s5_pressed,NULL); ++ s5_timer=g_timeout_add(settle_time,s5_timer_cb,NULL); ++ } else { ++ if(s5_timer!=-1) { ++ g_source_remove(s5_timer); ++ s5_timer==-1; ++ } ++ g_idle_add(s5_released,NULL); ++ } ++ s5_debounce=t; ++ } ++} ++ ++static unsigned long s6_debounce=0; ++static gint s6_timer=-1; ++ ++static gboolean s6_timer_cb(gpointer data) { ++ int level=digitalRead(S6_BUTTON); ++ if(level==1) { ++ s6_timer=-1; ++ g_idle_add(s6_released,NULL); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++static void s6Alert() { ++ int t=millis(); ++ if(t-s6_debounce > settle_time) { ++ int level=digitalRead(S6_BUTTON); ++ if(level==0) { ++ g_idle_add(s6_pressed,NULL); ++ s6_timer=g_timeout_add(settle_time,s6_timer_cb,NULL); ++ } else { ++ if(s6_timer!=-1) { ++ g_source_remove(s6_timer); ++ s6_timer==-1; ++ } ++ g_idle_add(s6_released,NULL); ++ } ++ s6_debounce=t; ++ } ++} ++ ++static unsigned long mox_debounce=0; ++ ++static void moxAlert() { ++ int t=millis(); ++ if(t-mox_debounce > settle_time) { ++ int level=digitalRead(MOX_BUTTON); ++ if(level==0) { ++ g_idle_add(mox_pressed,(gpointer)NULL); ++ } ++ mox_debounce=t; ++ } ++} ++#endif ++ ++ ++#ifdef VFO_HAS_FUNCTION ++static unsigned long vfo_debounce=0; ++ ++static void vfoFunctionAlert() { ++ int t=millis(); ++ if(t-vfo_debounce > settle_time) { ++ int level=digitalRead(VFO_FUNCTION); ++ if(level==0) { ++ if(running) g_idle_add(vfo_function_pressed,NULL); ++ } else { ++ if(running) g_idle_add(vfo_function_released,NULL); ++ } ++ vfo_debounce=t; ++ } ++} ++#endif ++ ++static void vfoEncoderInt(int A_or_B) { ++ int switch_A=digitalRead(VFO_ENCODER_A); ++ int switch_B=digitalRead(VFO_ENCODER_B); ++ if(vfo_A==switch_A && vfo_B==switch_B) { ++ return; // same as last ++ } ++ vfo_A=switch_A; ++ vfo_B=switch_B; ++ if(switch_A && switch_B) { ++ if(A_or_B==VFO_ENCODER_B) { ++ vfoEncoderPos--; ++ } else { ++ vfoEncoderPos++; ++ } ++ } ++} ++ ++static void vfoEncoderA() { ++ vfoEncoderInt(VFO_ENCODER_A); ++} ++ ++static void vfoEncoderB() { ++ vfoEncoderInt(VFO_ENCODER_B); ++} ++ ++static void e1EncoderInterrupt(int gpio) { ++ static int e1CurrentA=1, e1CurrentB=1; ++ ++ int levelA=digitalRead(E1_ENCODER_A); ++ int levelB=digitalRead(E1_ENCODER_B); ++ ++ if(e1CurrentA==levelA && e1CurrentB==levelB) { ++ return; ++ } ++ ++ e1CurrentA=levelA; ++ e1CurrentB=levelB; ++ ++ if(levelA && levelB) { ++ if(gpio==E1_ENCODER_B) { ++ --e1EncoderPos; ++ } else { ++ ++e1EncoderPos; ++ } ++ } ++} ++ ++static void e1EncoderA() { ++ e1EncoderInterrupt(E1_ENCODER_A); ++} ++ ++static void e1EncoderB() { ++ e1EncoderInterrupt(E1_ENCODER_B); ++} ++ ++static void e2EncoderInterrupt(int gpio) { ++ static int e2CurrentA=1, e2CurrentB=1; ++ ++ int levelA=digitalRead(E2_ENCODER_A); ++ int levelB=digitalRead(E2_ENCODER_B); ++ ++ if(e2CurrentA==levelA && e2CurrentB==levelB) { ++ return; ++ } ++ ++ e2CurrentA=levelA; ++ e2CurrentB=levelB; ++ ++ if(levelA && levelB) { ++ if(gpio==E2_ENCODER_B) { ++ --e2EncoderPos; ++ } else { ++ ++e2EncoderPos; ++ } ++ } ++} ++ ++static void e2EncoderA() { ++ e2EncoderInterrupt(E2_ENCODER_A); ++} ++ ++static void e2EncoderB() { ++ e2EncoderInterrupt(E2_ENCODER_B); ++} ++ ++static void e3EncoderInterrupt(int gpio) { ++ static int e3CurrentA=1, e3CurrentB=1; ++ ++ int levelA=digitalRead(E3_ENCODER_A); ++ int levelB=digitalRead(E3_ENCODER_B); ++ ++ if(e3CurrentA==levelA && e3CurrentB==levelB) { ++ return; ++ } ++ ++ e3CurrentA=levelA; ++ e3CurrentB=levelB; ++ ++ if(levelA && levelB) { ++ if(gpio==E3_ENCODER_B) { ++ --e3EncoderPos; ++ } else { ++ ++e3EncoderPos; ++ } ++ } ++} ++ ++static void e3EncoderA() { ++ e3EncoderInterrupt(E3_ENCODER_A); ++} ++ ++static void e3EncoderB() { ++ e3EncoderInterrupt(E3_ENCODER_B); ++} ++ ++#ifdef CONTROLLER2 ++static void e4EncoderInterrupt(int gpio) { ++ static int e4CurrentA=1, e4CurrentB=1; ++ ++ int levelA=digitalRead(E4_ENCODER_A); ++ int levelB=digitalRead(E4_ENCODER_B); ++ ++ if(e4CurrentA==levelA && e4CurrentB==levelB) { ++ return; ++ } ++ ++ e4CurrentA=levelA; ++ e4CurrentB=levelB; ++ ++ if(levelA && levelB) { ++ if(gpio==E4_ENCODER_B) { ++ --e4EncoderPos; ++ } else { ++ ++e4EncoderPos; ++ } ++ } ++<<<<<<< HEAD ++} ++ ++static void e4EncoderA() { ++ e4EncoderInterrupt(E4_ENCODER_A); ++======= ++} ++ ++static void e4EncoderA() { ++ e4EncoderInterrupt(E4_ENCODER_A); ++} ++ ++static void e4EncoderB() { ++ e4EncoderInterrupt(E4_ENCODER_B); ++>>>>>>> upstream/master ++} ++#endif ++ ++<<<<<<< HEAD ++static void e4EncoderB() { ++ e4EncoderInterrupt(E4_ENCODER_B); ++} ++#endif ++ ++======= ++>>>>>>> upstream/master ++#ifdef CONTROLLER2 ++static void pI2CInterrupt() { ++ int level=digitalRead(I2C_INTERRUPT); ++ if(level==0) { ++ i2c_interrupt(); ++ } ++} ++#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); ++ value=getProperty("ENABLE_E1_ENCODER"); ++ if(value) ENABLE_E1_ENCODER=atoi(value); ++ value=getProperty("ENABLE_E1_PULLUP"); ++ if(value) ENABLE_E1_PULLUP=atoi(value); ++ value=getProperty("E1_ENCODER_A"); ++ if(value) E1_ENCODER_A=atoi(value); ++ value=getProperty("E1_ENCODER_B"); ++ if(value) E1_ENCODER_B=atoi(value); ++ value=getProperty("ENABLE_E2_ENCODER"); ++ if(value) ENABLE_E2_ENCODER=atoi(value); ++ value=getProperty("ENABLE_E2_PULLUP"); ++ if(value) ENABLE_E2_PULLUP=atoi(value); ++ value=getProperty("E2_ENCODER_A"); ++ if(value) E2_ENCODER_A=atoi(value); ++ value=getProperty("E2_ENCODER_B"); ++ if(value) E2_ENCODER_B=atoi(value); ++ value=getProperty("ENABLE_E3_ENCODER"); ++ if(value) ENABLE_E3_ENCODER=atoi(value); ++ value=getProperty("ENABLE_E3_PULLUP"); ++ if(value) ENABLE_E3_PULLUP=atoi(value); ++ value=getProperty("E3_ENCODER_A"); ++ if(value) E3_ENCODER_A=atoi(value); ++ value=getProperty("E3_ENCODER_B"); ++ if(value) E3_ENCODER_B=atoi(value); ++#ifdef CONTROLLER2 ++ value=getProperty("ENABLE_E4_ENCODER"); ++ if(value) ENABLE_E4_ENCODER=atoi(value); ++ value=getProperty("ENABLE_E4_PULLUP"); ++ if(value) ENABLE_E4_PULLUP=atoi(value); ++ value=getProperty("E4_ENCODER_A"); ++ if(value) E4_ENCODER_A=atoi(value); ++ value=getProperty("E4_ENCODER_B"); ++ if(value) E4_ENCODER_B=atoi(value); ++#endif ++#ifndef CONTROLLER2 ++ value=getProperty("ENABLE_S1_BUTTON"); ++ if(value) ENABLE_S1_BUTTON=atoi(value); ++ value=getProperty("S1_BUTTON"); ++ if(value) S1_BUTTON=atoi(value); ++ value=getProperty("ENABLE_S2_BUTTON"); ++ if(value) ENABLE_S2_BUTTON=atoi(value); ++ value=getProperty("S2_BUTTON"); ++ if(value) S2_BUTTON=atoi(value); ++ value=getProperty("ENABLE_S3_BUTTON"); ++ if(value) ENABLE_S3_BUTTON=atoi(value); ++ value=getProperty("S3_BUTTON"); ++ if(value) S3_BUTTON=atoi(value); ++ value=getProperty("ENABLE_S4_BUTTON"); ++ if(value) ENABLE_S4_BUTTON=atoi(value); ++ value=getProperty("S4_BUTTON"); ++ if(value) S4_BUTTON=atoi(value); ++ value=getProperty("ENABLE_S5_BUTTON"); ++ if(value) ENABLE_S5_BUTTON=atoi(value); ++ value=getProperty("S5_BUTTON"); ++ if(value) S5_BUTTON=atoi(value); ++ value=getProperty("ENABLE_S6_BUTTON"); ++ if(value) ENABLE_S6_BUTTON=atoi(value); ++ value=getProperty("S6_BUTTON"); ++ if(value) S6_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); ++#endif ++ ++ value=getProperty("ENABLE_E1_BUTTON"); ++ if(value) ENABLE_E1_BUTTON=atoi(value); ++ value=getProperty("ENABLE_E2_BUTTON"); ++ if(value) ENABLE_E2_BUTTON=atoi(value); ++ value=getProperty("ENABLE_E3_BUTTON"); ++ if(value) ENABLE_E3_BUTTON=atoi(value); ++#ifdef CONTROLLER2 ++ value=getProperty("ENABLE_E4_BUTTON"); ++ if(value) ENABLE_E4_BUTTON=atoi(value); ++#endif ++ ++<<<<<<< HEAD ++#ifdef LOCALCW ++ value=getProperty("ENABLE_CW_BUTTONS"); ++ if(value) ENABLE_CW_BUTTONS=atoi(value); ++ value=getProperty("CWL_BUTTON"); ++ if(value) CWL_BUTTON=atoi(value); ++ value=getProperty("CWR_BUTTON"); ++ if(value) CWR_BUTTON=atoi(value); ++#endif ++ ++======= ++>>>>>>> upstream/master ++} ++ ++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); ++ sprintf(value,"%d",ENABLE_E1_ENCODER); ++ setProperty("ENABLE_E1_ENCODER",value); ++ sprintf(value,"%d",ENABLE_E1_PULLUP); ++ setProperty("ENABLE_E1_PULLUP",value); ++ sprintf(value,"%d",E1_ENCODER_A); ++ setProperty("E1_ENCODER_A",value); ++ sprintf(value,"%d",E1_ENCODER_B); ++ setProperty("E1_ENCODER_B",value); ++ sprintf(value,"%d",ENABLE_E2_ENCODER); ++ setProperty("ENABLE_E2_ENCODER",value); ++ sprintf(value,"%d",ENABLE_E2_PULLUP); ++ setProperty("ENABLE_E2_PULLUP",value); ++ sprintf(value,"%d",E2_ENCODER_A); ++ setProperty("E2_ENCODER_A",value); ++ sprintf(value,"%d",E2_ENCODER_B); ++ setProperty("E2_ENCODER_B",value); ++ sprintf(value,"%d",ENABLE_E3_ENCODER); ++ setProperty("ENABLE_E3_ENCODER",value); ++ sprintf(value,"%d",ENABLE_E3_PULLUP); ++ setProperty("ENABLE_E3_PULLUP",value); ++ sprintf(value,"%d",E3_ENCODER_A); ++ setProperty("E3_ENCODER_A",value); ++ sprintf(value,"%d",E3_ENCODER_B); ++ setProperty("E3_ENCODER_B",value); ++#ifdef CONTROLLER2 ++ sprintf(value,"%d",ENABLE_E4_ENCODER); ++ setProperty("ENABLE_E4_ENCODER",value); ++ sprintf(value,"%d",ENABLE_E4_PULLUP); ++ setProperty("ENABLE_E4_PULLUP",value); ++ sprintf(value,"%d",E4_ENCODER_A); ++ setProperty("E4_ENCODER_A",value); ++ sprintf(value,"%d",E4_ENCODER_B); ++ setProperty("E4_ENCODER_B",value); ++#endif ++#ifndef CONTROLLER2 ++ sprintf(value,"%d",ENABLE_S1_BUTTON); ++ setProperty("ENABLE_S1_BUTTON",value); ++ sprintf(value,"%d",S1_BUTTON); ++ setProperty("S1_BUTTON",value); ++ sprintf(value,"%d",ENABLE_S2_BUTTON); ++ setProperty("ENABLE_S2_BUTTON",value); ++ sprintf(value,"%d",S2_BUTTON); ++ setProperty("S2_BUTTON",value); ++ sprintf(value,"%d",ENABLE_S3_BUTTON); ++ setProperty("ENABLE_S3_BUTTON",value); ++ sprintf(value,"%d",S3_BUTTON); ++ setProperty("S3_BUTTON",value); ++ sprintf(value,"%d",ENABLE_S4_BUTTON); ++ setProperty("ENABLE_S4_BUTTON",value); ++ sprintf(value,"%d",S4_BUTTON); ++ setProperty("S4_BUTTON",value); ++ sprintf(value,"%d",ENABLE_S5_BUTTON); ++ setProperty("ENABLE_S5_BUTTON",value); ++ sprintf(value,"%d",S5_BUTTON); ++ setProperty("S5_BUTTON",value); ++ sprintf(value,"%d",ENABLE_S6_BUTTON); ++ setProperty("ENABLE_S6_BUTTON",value); ++ sprintf(value,"%d",S6_BUTTON); ++ setProperty("S6_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); ++#endif ++ ++ sprintf(value,"%d",ENABLE_E1_BUTTON); ++ setProperty("ENABLE_E1_BUTTON",value); ++ sprintf(value,"%d",ENABLE_E2_BUTTON); ++ setProperty("ENABLE_E2_BUTTON",value); ++ sprintf(value,"%d",ENABLE_E3_BUTTON); ++ setProperty("ENABLE_E3_BUTTON",value); ++#ifdef CONTROLLER2 ++ sprintf(value,"%d",ENABLE_E4_BUTTON); ++ setProperty("ENABLE_E4_BUTTON",value); ++<<<<<<< HEAD ++#endif ++ ++#ifdef LOCALCW ++ sprintf(value,"%d",ENABLE_CW_BUTTONS); ++ setProperty("ENABLE_CW_BUTTONS",value); ++ sprintf(value,"%d",CWL_BUTTON); ++ setProperty("CWL_BUTTON",value); ++ sprintf(value,"%d",CWR_BUTTON); ++ setProperty("CWR_BUTTON",value); ++======= ++>>>>>>> upstream/master ++#endif ++ saveProperties("gpio.props"); ++} ++ ++static void setup_pin(int pin, int up_down, void(*pAlert)(void)) { ++fprintf(stderr,"setup_pin: pin=%d mode=%d updown=%d\n",pin,INPUT,up_down); ++ pinMode(pin,INPUT); ++ pullUpDnControl(pin,up_down); ++<<<<<<< HEAD ++ usleep(10000); ++ wiringPiISR(pin,INT_EDGE_BOTH,pAlert); ++} ++ ++ ++static void setup_encoder_pin(int pin, int up_down, void(*pAlert)(void)) { ++fprintf(stderr,"setup_encoder_pin: pin=%d updown=%d\n",pin,up_down); ++ pinMode(pin,INPUT); ++ pullUpDnControl(pin,up_down); ++ usleep(10000); ++ wiringPiISR(pin,INT_EDGE_RISING,pAlert); ++} ++ ++#ifdef LOCALCW ++#ifdef RADIOBERRY ++#define BUTTON_STEADY_TIME_US 5000 ++static void setup_button(int button, gpioAlertFunc_t pAlert) { ++ gpioSetMode(button, PI_INPUT); ++ gpioSetPullUpDown(button,PI_PUD_UP); ++ // give time to settle to avoid false triggers ++======= ++>>>>>>> upstream/master ++ usleep(10000); ++ wiringPiISR(pin,INT_EDGE_BOTH,pAlert); ++} ++ ++<<<<<<< HEAD ++static void cwAlert(int gpio, int level, uint32_t tick) { ++ //fprintf(stderr,"cw key at pin %d \n", gpio); ++ if (cw_keyer_internal == 0 ){ ++ //fprintf(stderr,"call keyer_event...\n"); ++ keyer_event(gpio, cw_active_level == 0 ? level : (level==0)); ++ } ++} ++ ++/* ++static unsigned long cwl_debounce=0; ++static void cwlAlert() { ++ int t=millis(); ++ if(t - cwl_debounce > settle_time) { ++ int level=digitalRead(CWL_BUTTON); ++ if (cw_keyer_internal == 0 ){ ++ fprintf(stderr,"call keyer_event CWL Button \n"); ++ keyer_event(CWL_BUTTON, cw_active_level == 0 ? level : (level==0)); ++ } ++ cwl_debounce=t; ++ } ++} ++ ++static unsigned long cwr_debounce=0; ++static void cwrAlert() { ++ int t=millis(); ++ if(t - cwr_debounce > settle_time) { ++ int level=digitalRead(CWR_BUTTON); ++ if (cw_keyer_internal == 0 ){ ++ fprintf(stderr,"call keyer_event CWR Button \n"); ++ keyer_event(CWR_BUTTON, cw_active_level == 0 ? level : (level==0)); ++ } ++ cwr_debounce=t; ++ } ++} ++*/ ++#endif ++#endif ++======= ++ ++static void setup_encoder_pin(int pin, int up_down, void(*pAlert)(void)) { ++fprintf(stderr,"setup_encoder_pin: pin=%d updown=%d\n",pin,up_down); ++ pinMode(pin,INPUT); ++ pullUpDnControl(pin,up_down); ++ usleep(10000); ++ wiringPiISR(pin,INT_EDGE_RISING,pAlert); ++} ++>>>>>>> upstream/master ++ ++int gpio_init() { ++ int i; ++ ++ fprintf(stderr,"gpio_wiringpi: gpio_init\n"); ++ ++ gpio_restore_state(); ++ ++ wiringPiSetup(); // use WiringPi pin numbers ++<<<<<<< HEAD ++ ++#ifdef RADIOBERRY ++ if (gpioInitialise() < 0) { ++ fprintf(stderr,"radioberry_protocol: gpio could not be initialized. \n"); ++ exit(-1); ++ } ++#endif ++======= ++>>>>>>> upstream/master ++ ++ if(ENABLE_VFO_ENCODER) { ++#ifdef CONTROLLER2 ++#ifdef VFO_HAS_FUNCTION ++ setup_pin(VFO_FUNCTION, PUD_UP, &vfoFunctionAlert); ++ vfoFunction=0; ++#endif ++ vfo_A=1; ++ vfo_B=1; ++ setup_encoder_pin(VFO_ENCODER_A,ENABLE_VFO_PULLUP?PUD_UP:PUD_DOWN,&vfoEncoderA); ++ setup_encoder_pin(VFO_ENCODER_B,ENABLE_VFO_PULLUP?PUD_UP:PUD_DOWN,&vfoEncoderB); ++#else ++ vfo_A=1; ++ vfo_B=1; ++ setup_encoder_pin(VFO_ENCODER_A,ENABLE_VFO_PULLUP?PUD_UP:PUD_DOWN,&vfoEncoderA); ++ setup_encoder_pin(VFO_ENCODER_B,ENABLE_VFO_PULLUP?PUD_UP:PUD_DOWN,&vfoEncoderB); ++ //setup_pin(VFO_ENCODER_A,ENABLE_VFO_PULLUP?PUD_UP:PUD_OFF,&vfoEncoderA); ++ //setup_pin(VFO_ENCODER_B,ENABLE_VFO_PULLUP?PUD_UP:PUD_OFF,&vfoEncoderB); ++#endif ++ vfoEncoderPos=0; ++ } ++ ++ setup_pin(E1_FUNCTION, PUD_UP, &e1FunctionAlert); ++ e1Function=0; ++ ++ if(ENABLE_E1_ENCODER) { ++ setup_encoder_pin(E1_ENCODER_A,ENABLE_E1_PULLUP?PUD_UP:PUD_OFF,&e1EncoderA); ++ setup_encoder_pin(E1_ENCODER_B,ENABLE_E1_PULLUP?PUD_UP:PUD_OFF,&e1EncoderB); ++ e1EncoderPos=0; ++ } ++ ++ setup_pin(E2_FUNCTION, PUD_UP, &e2FunctionAlert); ++ e2Function=0; ++ ++ if(ENABLE_E2_ENCODER) { ++ setup_encoder_pin(E2_ENCODER_A,ENABLE_E2_PULLUP?PUD_UP:PUD_OFF,&e2EncoderA); ++ setup_encoder_pin(E2_ENCODER_B,ENABLE_E2_PULLUP?PUD_UP:PUD_OFF,&e2EncoderB); ++ e2EncoderPos=0; ++ } ++ ++ setup_pin(E3_FUNCTION, PUD_UP, &e3FunctionAlert); ++ e3Function=0; ++ ++ if(ENABLE_E3_ENCODER) { ++ setup_encoder_pin(E3_ENCODER_A,ENABLE_E3_PULLUP?PUD_UP:PUD_OFF,&e3EncoderA); ++ setup_encoder_pin(E3_ENCODER_B,ENABLE_E3_PULLUP?PUD_UP:PUD_OFF,&e3EncoderB); ++ e3EncoderPos=0; ++ } ++ ++#ifdef CONTROLLER2 ++ setup_pin(E4_FUNCTION, PUD_UP, &e4FunctionAlert); ++ e4Function=0; ++ ++ if(ENABLE_E4_ENCODER) { ++ setup_encoder_pin(E4_ENCODER_A,ENABLE_E4_PULLUP?PUD_UP:PUD_OFF,&e4EncoderA); ++ setup_encoder_pin(E4_ENCODER_B,ENABLE_E4_PULLUP?PUD_UP:PUD_OFF,&e4EncoderB); ++ e4EncoderPos=0; ++ } ++#endif ++ ++#ifndef CONTROLLER2 ++ if(ENABLE_FUNCTION_BUTTON) { ++<<<<<<< HEAD ++ //setup_pin(FUNCTION_BUTTON, PUD_UP, &functionAlert); ++======= ++ setup_pin(FUNCTION_BUTTON, PUD_UP, &functionAlert); ++>>>>>>> upstream/master ++ } ++ ++ if(ENABLE_MOX_BUTTON) { ++ setup_pin(MOX_BUTTON, PUD_UP, &moxAlert); ++ } ++ ++ if(ENABLE_S1_BUTTON) { ++ setup_pin(S1_BUTTON, PUD_UP, &s1Alert); ++ } ++ ++ if(ENABLE_S2_BUTTON) { ++ setup_pin(S2_BUTTON, PUD_UP, &s2Alert); ++ } ++ ++ if(ENABLE_S3_BUTTON) { ++ setup_pin(S3_BUTTON, PUD_UP, &s3Alert); ++ } ++ ++ if(ENABLE_S4_BUTTON) { ++ setup_pin(S4_BUTTON, PUD_UP, &s4Alert); ++ } ++ ++ if(ENABLE_S5_BUTTON) { ++ setup_pin(S5_BUTTON, PUD_UP, &s5Alert); ++ } ++ ++ if(ENABLE_S6_BUTTON) { ++ setup_pin(S6_BUTTON, PUD_UP, &s6Alert); ++ } ++#endif ++ ++ rotary_encoder_thread_id = g_thread_new( "rotary encoder", rotary_encoder_thread, NULL); ++ if( ! rotary_encoder_thread_id ) ++ { ++ fprintf(stderr,"g_thread_new failed on rotary_encoder_thread\n"); ++ exit( -1 ); ++ } ++ fprintf(stderr, "rotary_encoder_thread: id=%p\n",rotary_encoder_thread_id); ++ ++#ifdef CONTROLLER2 ++ // setup i2c ++ i2c_init(); ++ ++ // setup interrupt pin ++ fprintf(stderr,"setup i2c interrupt: pin=%d\n",I2C_INTERRUPT); ++ //digitalWrite(I2C_INTERRUPT,0); // clear pin ++ pinMode(I2C_INTERRUPT,INPUT); ++ pullUpDnControl(I2C_INTERRUPT,PUD_UP); ++ usleep(10000); ++ //wiringPiISR(I2C_INTERRUPT,INT_EDGE_FALLING,pI2CInterrupt); ++ wiringPiISR(I2C_INTERRUPT,INT_EDGE_BOTH,pI2CInterrupt); ++#endif ++<<<<<<< HEAD ++ ++#ifdef LOCALCW ++ fprintf(stderr,"GPIO: ENABLE_CW_BUTTONS=%d CWL_BUTTON=%d CWR_BUTTON=%d\n",ENABLE_CW_BUTTONS, CWL_BUTTON, CWR_BUTTON); ++ if(ENABLE_CW_BUTTONS) { ++ /* ++ setup_pin(CWL_BUTTON, PUD_UP, &cwlAlert); ++ setup_pin(CWR_BUTTON, PUD_UP, &cwrAlert); ++ */ ++ ++ #ifdef RADIOBERRY ++ setup_button(CWL_BUTTON, cwAlert); ++ setup_button(CWR_BUTTON, cwAlert); ++ #endif ++ ++ ++ } ++#endif ++======= ++>>>>>>> upstream/master ++ ++ return 0; ++} ++ ++void gpio_close() { ++ running=0; ++} ++ ++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 && posid].mode]; ++ FILTER *band_filter; ++ FILTER *filter; ++ int new_val; ++ ++ switch(action) { ++ case ENCODER_AF_GAIN: ++ value=active_receiver->volume; ++ value+=(double)pos/100.0; ++ if(value<0.0) { ++ value=0.0; ++ } else if(value>1.0) { ++ value=1.0; ++ } ++ set_af_gain(value); ++ break; ++ case ENCODER_AGC_GAIN: ++ value=active_receiver->agc_gain; ++ value+=(double)pos; ++ if(value<-20.0) { ++ value=-20.0; ++ } else if(value>120.0) { ++ value=120.0; ++ } ++ set_agc_gain(value); ++ break; ++ case ENCODER_ATTENUATION: ++ value=(double)adc_attenuation[active_receiver->adc]; ++ value+=(double)pos; ++ if(value<0.0) { ++ value=0.0; ++ } else if (value>31.0) { ++ value=31.0; ++ } ++ set_attenuation_value(value); ++ break; ++ case ENCODER_MIC_GAIN: ++ value=mic_gain; ++ //gain+=(double)pos/100.0; ++ value+=(double)pos; ++ if(value<-10.0) { ++ value=-10.0; ++ } else if(value>50.0) { ++ value=50.0; ++ } ++ set_mic_gain(value); ++ break; ++ case ENCODER_DRIVE: ++ value=getDrive(); ++ value+=(double)pos; ++ if(value<0.0) { ++ value=0.0; ++ } else if(value>100.0) { ++ value=100.0; ++ } ++ set_drive(value); ++ break; ++ case ENCODER_RIT: ++ value=(double)vfo[active_receiver->id].rit; ++ value+=(double)(pos*rit_increment); ++ if(value<-1000.0) { ++ value=-1000.0; ++ } else if(value>1000.0) { ++ value=1000.0; ++ } ++ vfo[active_receiver->id].rit=(int)value; ++ if(protocol==NEW_PROTOCOL) { ++ schedule_high_priority(); ++ } ++ vfo_update(); ++ break; ++ case ENCODER_CW_SPEED: ++ value=(double)cw_keyer_speed; ++ value+=(double)pos; ++ if(value<1.0) { ++ value=1.0; ++ } else if(value>60.0) { ++ value=60.0; ++ } ++ cw_keyer_speed=(int)value; ++ vfo_update(); ++ break; ++ case ENCODER_CW_FREQUENCY: ++ value=(double)cw_keyer_sidetone_frequency; ++ value+=(double)pos; ++ if(value<0.0) { ++ value=0.0; ++ } else if(value>1000.0) { ++ value=1000.0; ++ } ++ cw_keyer_sidetone_frequency=(int)value; ++ vfo_update(); ++ break; ++ case ENCODER_PANADAPTER_HIGH: ++ value=(double)active_receiver->panadapter_high; ++ value+=(double)pos; ++ active_receiver->panadapter_high=(int)value; ++ break; ++ case ENCODER_PANADAPTER_LOW: ++ value=(double)active_receiver->panadapter_low; ++ value+=(double)pos; ++ active_receiver->panadapter_low=(int)value; ++ break; ++ case ENCODER_SQUELCH: ++ value=active_receiver->squelch; ++ value+=(double)pos; ++ if(value<0.0) { ++ value=0.0; ++ } else if(value>100.0) { ++ value=100.0; ++ } ++ active_receiver->squelch=value; ++ set_squelch(active_receiver); ++ break; ++ case ENCODER_COMP: ++ value=(double)transmitter->compressor_level; ++ value+=(double)pos; ++ if(value<0.0) { ++ value=0.0; ++ } else if(value>20.0) { ++ value=20.0; ++ } ++ transmitter->compressor_level=(int)value; ++ set_compression(transmitter); ++ break; ++ } ++} ++ ++static int e1_encoder_changed(void *data) { ++ int pos=(int)data; ++ if(active_menu==E1_MENU) { ++ encoder_select(pos); ++ } else { ++ encoder_changed(e1_encoder_action,pos); ++ } ++ //free(data); ++ return 0; ++} ++ ++static int e2_encoder_changed(void *data) { ++ int pos=(int)data; ++ if(active_menu==E2_MENU) { ++ encoder_select(pos); ++ } else { ++ encoder_changed(e2_encoder_action,pos); ++ } ++ //free(data); ++ return 0; ++} ++ ++static int e3_encoder_changed(void *data) { ++ int pos=(int)data; ++ if(active_menu==E3_MENU) { ++ encoder_select(pos); ++ } else { ++ encoder_changed(e3_encoder_action,pos); ++ } ++ //free(data); ++ return 0; ++} ++ ++#ifdef CONTROLLER2 ++static int e4_encoder_changed(void *data) { ++ int pos=(int)data; ++ if(active_menu==E4_MENU) { ++ encoder_select(pos); ++ } else { ++ encoder_changed(e4_encoder_action,pos); ++ } ++ //free(data); ++ return 0; ++} ++#endif ++ ++static gpointer rotary_encoder_thread(gpointer data) { ++ int pos; ++ ++ // ignore startup glitches ++ sleep(2); ++ ++ //g_mutex_lock(&m_running); ++ running=1; ++ //g_mutex_unlock(&m_running); ++ while(1) { ++ ++ pos=vfo_encoder_get_pos(); ++ if(pos!=0) { ++ g_idle_add(vfo_encoder_changed,(gpointer)pos); ++ } ++ ++ pos=e1_encoder_get_pos(); ++ if(pos!=0) { ++ g_idle_add(e1_encoder_changed,(gpointer)pos); ++ } ++ ++ pos=e2_encoder_get_pos(); ++ if(pos!=0) { ++ g_idle_add(e2_encoder_changed,(gpointer)pos); ++ } ++ ++ pos=e3_encoder_get_pos(); ++ if(pos!=0) { ++ g_idle_add(e3_encoder_changed,(gpointer)pos); ++ } ++ ++#ifdef CONTROLLER2 ++ pos=e4_encoder_get_pos(); ++ if(pos!=0) { ++ g_idle_add(e4_encoder_changed,(gpointer)pos); ++ } ++#endif ++ ++#ifdef sx1509 ++ // buttons only generate interrupt when ++ // pushed onODER_AF_GAIN = 0, ++ function_state = 0; ++ band_state = 0; ++ bandstack_state = 0; ++ mode_state = 0; ++ filter_state = 0; ++ noise_state = 0; ++ agc_state = 0; ++ mox_state = 0; ++ lock_state = 0; ++#endif ++//fprintf(stderr,"gpio_thread: lock\n"); ++ //g_mutex_lock(&m_running); ++ if(running==0) { ++fprintf(stderr,"gpio_thread: unlock (running==0)\n"); ++ //g_mutex_unlock(&m_running); ++ g_thread_exit(NULL); ++ } ++ usleep(100000); ++ ++//fprintf(stderr,"gpio_thread: unlock (running==1)\n"); ++ //g_mutex_unlock(&m_running); ++ } ++ return NULL; ++} diff --cc radio.c.orig index f912707,f912707..d7b94ed --- a/radio.c.orig +++ b/radio.c.orig @@@ -1,4 -1,4 +1,4 @@@ --/* Copyright (C) ++/* Copyrieht (C) * 2015 - John Melton, G0ORX/N6LYT * * This program is free software; you can redistribute it and/or @@@ -23,6 -23,6 +23,9 @@@ #include #include #include ++#include ++#include ++#include #include @@@ -39,8 -39,8 +42,12 @@@ #include "agc.h" #include "band.h" #include "property.h" ++#include "new_menu.h" #include "new_protocol.h" #include "old_protocol.h" ++#ifdef RADIOBERRY ++#include "radioberry.h" ++#endif #include "store.h" #ifdef LIMESDR #include "lime_protocol.h" @@@ -48,36 -48,36 +55,43 @@@ #ifdef FREEDV #include "freedv.h" #endif ++#include "audio_waterfall.h" #ifdef GPIO #include "gpio.h" #endif #include "vfo.h" ++#include "vox.h" #include "meter.h" #include "rx_panadapter.h" #include "tx_panadapter.h" #include "waterfall.h" #include "sliders.h" #include "toolbar.h" ++#include "rigctl.h" ++#include "ext.h" #define min(x,y) (xpanel,0,y); ++ receiver[i]->x=0; ++ receiver[i]->y=y; y+=rx_height/receivers; } @@@ -299,8 -299,8 +321,6 @@@ gtk_fixed_move(GTK_FIXED(fixed),sliders,0,y); } gtk_widget_show_all(sliders); -- // force change of sliders for mic or linein -- g_idle_add(linein_changed,NULL); } else { if(sliders!=NULL) { gtk_container_remove(GTK_CONTAINER(fixed),sliders); @@@ -331,7 -331,7 +351,7 @@@ void start_radio() int i; int x; int y; --fprintf(stderr,"start_radio: selected radio=%p device=%d\n",radio,radio->device); ++//fprintf(stderr,"start_radio: selected radio=%p device=%d\n",radio,radio->device); gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_WATCH)); int rc; @@@ -342,7 -342,7 +362,47 @@@ } sem_post(&property_sem); -- status_text("starting radio ..."); ++ char text[256]; ++ //for(i=0;iprotocol) { ++ case ORIGINAL_PROTOCOL: ++ case NEW_PROTOCOL: ++#ifdef USBOZY ++ if(radio->device==DEVICE_OZY) { ++ sprintf(text,"%s (%s) on USB /dev/ozy\n", radio->name, radio->protocol==ORIGINAL_PROTOCOL?"Protocol 1":"Protocol 2"); ++ } else { ++#endif ++ sprintf(text,"Starting %s (%s v%d.%d)", ++ radio->name, ++ radio->protocol==ORIGINAL_PROTOCOL?"Protocol 1":"Protocol 2", ++ radio->software_version/10, ++ radio->software_version%10); ++ break; ++ } ++ //} ++ ++ ++ ++ status_text(text); ++ ++ sprintf(text,"piHPSDR: %s (%s v%d.%d) %s (%02X:%02X:%02X:%02X:%02X:%02X) on %s", ++ radio->name, ++ radio->protocol==ORIGINAL_PROTOCOL?"Protocol 1":"Protocol 2", ++ radio->software_version/10, ++ radio->software_version%10, ++ inet_ntoa(radio->info.network.address.sin_addr), ++ radio->info.network.mac_address[0], ++ radio->info.network.mac_address[1], ++ radio->info.network.mac_address[2], ++ radio->info.network.mac_address[3], ++ radio->info.network.mac_address[4], ++ radio->info.network.mac_address[5], ++ radio->info.network.interface_name); ++ ++fprintf(stderr,"title: length=%d\n", (int)strlen(text)); ++ ++ gtk_window_set_title (GTK_WINDOW (top_window), text); ++ protocol=radio->protocol; device=radio->device; @@@ -371,21 -371,21 +431,60 @@@ sprintf(property_path,"limesdr.props"); break; #endif ++#ifdef RADIOBERRY ++ case RADIOBERRY_PROTOCOL: ++ sprintf(property_path,"radioberry.props"); ++ break; ++#endif ++ } ++ ++ switch(radio->protocol) { ++ case ORIGINAL_PROTOCOL: ++ switch(radio->device) { ++ case DEVICE_ORION2: ++ //meter_calibration=3.0; ++ //display_calibration=3.36; ++ break; ++ default: ++ //meter_calibration=-2.44; ++ //display_calibration=-2.1; ++ break; ++ } ++ break; ++ case NEW_PROTOCOL: ++ switch(radio->device) { ++ case NEW_DEVICE_ORION2: ++ //meter_calibration=3.0; ++ //display_calibration=3.36; ++ break; ++ default: ++ //meter_calibration=-2.44; ++ //display_calibration=-2.1; ++ break; ++ } ++ break; } ++ ++ ++ adc_attenuation[0]=0; ++ adc_attenuation[1]=0; ++//fprintf(stderr,"meter_calibration=%f display_calibration=%f\n", meter_calibration, display_calibration); radioRestoreState(); ++ radio_change_region(region); ++ y=0; fixed=gtk_fixed_new(); gtk_container_remove(GTK_CONTAINER(top_window),grid); gtk_container_add(GTK_CONTAINER(top_window), fixed); --fprintf(stderr,"radio: vfo_init\n"); ++//fprintf(stderr,"radio: vfo_init\n"); vfo_panel = vfo_init(VFO_WIDTH,VFO_HEIGHT,top_window); gtk_fixed_put(GTK_FIXED(fixed),vfo_panel,0,y); --fprintf(stderr,"radio: meter_init\n"); ++//fprintf(stderr,"radio: meter_init\n"); meter = meter_init(METER_WIDTH,METER_HEIGHT,top_window); gtk_fixed_put(GTK_FIXED(fixed),meter,VFO_WIDTH,y); @@@ -414,24 -414,24 +513,62 @@@ fprintf(stderr,"Create %d receivers: height=%d\n",receivers,rx_height); -- for(i=0;ipanel); ++ setSquelch(receiver[i]); if(ix=0; ++ receiver[i]->y=y; gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,0,y); --fprintf(stderr,"receiver %d: height=%d y=%d\n",receiver[i]->id,rx_height,y); ++ g_object_ref((gpointer)receiver[i]->panel); set_displaying(receiver[i],1); y+=rx_height; } else { set_displaying(receiver[i],0); } } ++ ++ if((protocol==ORIGINAL_PROTOCOL) && (RECEIVERS==2) && (receiver[0]->sample_rate!=receiver[1]->sample_rate)) { ++ receiver[1]->sample_rate=receiver[0]->sample_rate; ++ } ++ active_receiver=receiver[0]; fprintf(stderr,"Create transmitter\n"); transmitter=create_transmitter(CHANNEL_TX, buffer_size, fft_size, updates_per_second, display_width, tx_height); -- g_object_ref((gpointer)transmitter->panel); ++ transmitter->x=0; ++ transmitter->y=VFO_HEIGHT; ++ //gtk_fixed_put(GTK_FIXED(fixed),transmitter->panel,0,VFO_HEIGHT); ++ ++#ifdef PURESIGNAL ++ tx_set_ps_sample_rate(transmitter,protocol==NEW_PROTOCOL?192000:active_receiver->sample_rate); ++ if(((protocol==ORIGINAL_PROTOCOL) && (device!=DEVICE_METIS)) || ((protocol==NEW_PROTOCOL) && (device!=NEW_DEVICE_ATLAS))) { ++ receiver[PS_TX_FEEDBACK]=create_pure_signal_receiver(PS_TX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width); ++ receiver[PS_RX_FEEDBACK]=create_pure_signal_receiver(PS_RX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width); ++ } ++#endif ++#ifdef AUDIO_WATERFALL ++ audio_waterfall=audio_waterfall_init(200,100); ++ gtk_fixed_put(GTK_FIXED(fixed),audio_waterfall,0,VFO_HEIGHT+20); ++#endif ++ ++#ifdef GPIO ++ if(gpio_init()<0) { ++ fprintf(stderr,"GPIO failed to initialize\n"); ++ } ++#endif ++<<<<<<< HEAD ++#ifdef LOCALCW ++ // init local keyer if enabled ++ if (cw_keyer_internal == 0) { ++ fprintf(stderr,"Initialize keyer.....\n"); ++ keyer_update(); ++ } ++#endif ++======= ++>>>>>>> upstream/master ++ switch(radio->protocol) { case ORIGINAL_PROTOCOL: old_protocol_init(0,display_width,receiver[0]->sample_rate); @@@ -441,25 -441,25 +578,21 @@@ break; #ifdef LIMESDR case LIMESDR_PROTOCOL: -- lime_protocol_init(0,display_width); ++ lime_protocol_init(0,display_width,receiver[0]->sample_rate); break; ++#endif ++#ifdef RADIOBERRY ++ case RADIOBERRY_PROTOCOL: ++ radioberry_protocol_init(0,display_width); ++ break; #endif } --#ifdef GPIO -- if(gpio_init()<0) { -- fprintf(stderr,"GPIO failed to initialize\n"); -- } --#ifdef LOCALCW -- // init local keyer if enabled -- else if (cw_keyer_internal == 0) -- keyer_update(); --#endif --#endif --#ifdef I2C -- i2c_init(); --#endif ++ ++//#ifdef I2C ++// i2c_init(); ++//#endif if(display_sliders) { fprintf(stderr,"create sliders\n"); @@@ -468,57 -468,57 +601,61 @@@ y+=SLIDERS_HEIGHT; } ++ toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,top_window); gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y); y+=TOOLBAR_HEIGHT; gtk_widget_show_all (fixed); ++//#ifdef FREEDV ++// if(!active_receiver->freedv) { ++// gtk_widget_hide(audio_waterfall); ++// } ++//#endif -- // force change of sliders for mic or linein -- g_idle_add(linein_changed,NULL); ++ // save every 30 seconds --fprintf(stderr,"start save timer\n"); save_timer_id=gdk_threads_add_timeout(30000, save_cb, NULL); #ifdef PSK -- if(active_receiver->mode==modePSK) { ++ if(vfo[active_receiver->id].mode==modePSK) { show_psk(); } else { show_waterfall(); } #endif -- launch_rigctl(); ++ if(rigctl_enable) { ++ launch_rigctl(); ++ } calcDriveLevel(); -- calcTuneDriveLevel(); ++ ++#ifdef PURESIGNAL ++ if(transmitter->puresignal) { ++ tx_set_ps(transmitter,transmitter->puresignal); ++ } ++#endif if(protocol==NEW_PROTOCOL) { schedule_high_priority(); } -- g_idle_add(vfo_update,(gpointer)NULL); ++ g_idle_add(ext_vfo_update,(gpointer)NULL); --fprintf(stderr,"set cursor\n"); gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW)); --for(i=0;ifreedv) { ++ freedv_reset_tx_text_index(); ++ } ++#endif ++#ifdef PURESIGNAL ++ RECEIVER *rx_feedback=receiver[PS_RX_FEEDBACK]; ++ RECEIVER *tx_feedback=receiver[PS_TX_FEEDBACK]; ++ ++ rx_feedback->samples=0; ++ tx_feedback->samples=0; ++#endif ++ for(i=0;iid,0,i==(receivers-1)); set_displaying(receiver[i],0); if(protocol==NEW_PROTOCOL) { schedule_high_priority(); ++ schedule_receive_specific(); ++ } ++ g_object_ref((gpointer)receiver[i]->panel); ++ g_object_ref((gpointer)receiver[i]->panadapter); ++ if(receiver[i]->waterfall!=NULL) { ++ g_object_ref((gpointer)receiver[i]->waterfall); } gtk_container_remove(GTK_CONTAINER(fixed),receiver[i]->panel); } -- gtk_fixed_put(GTK_FIXED(fixed),transmitter->panel,0,y); ++//#ifdef FREEDV ++// if(active_receiver->freedv) { ++// gtk_widget_show(audio_waterfall); ++// } ++//#endif ++ gtk_fixed_put(GTK_FIXED(fixed),transmitter->panel,transmitter->x,transmitter->y); SetChannelState(transmitter->id,1,0); tx_set_displaying(transmitter,1); --#ifdef FREEDV -- if(active_receiver->mode==modeFREEDV) { -- freedv_reset_tx_text_index(); -- } --#endif } else { SetChannelState(transmitter->id,0,1); if(protocol==NEW_PROTOCOL) { schedule_high_priority(); ++ schedule_receive_specific(); } tx_set_displaying(transmitter,0); ++ g_object_ref((gpointer)transmitter->panel); ++ g_object_ref((gpointer)transmitter->panadapter); gtk_container_remove(GTK_CONTAINER(fixed),transmitter->panel); -- int rx_height=display_height-VFO_HEIGHT-TOOLBAR_HEIGHT; -- if(display_sliders) { -- rx_height-=SLIDERS_HEIGHT; -- } ++//#ifdef FREEDV ++// if(active_receiver->freedv) { ++// gtk_widget_hide(audio_waterfall); ++// } ++//#endif for(i=0;ipanel,receiver[i]->x,receiver[i]->y); SetChannelState(receiver[i]->id,1,0); set_displaying(receiver[i],1); -- gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,0,y); -- y+=(rx_height/receivers); } ++//#ifdef FREEDV ++// if(active_receiver->freedv) { ++// gtk_widget_show(audio_waterfall); ++// } ++//#endif } -- gtk_widget_show_all(fixed); -- g_idle_add(linein_changed,NULL); ++#ifdef PURESIGNAL ++ if(transmitter->puresignal) { ++ SetPSMox(transmitter->id,state); ++ } ++#endif } void setMox(int state) { @@@ -620,8 -620,8 +793,14 @@@ void setVox(int state) vox=state; rxtx(state); } ++ g_idle_add(ext_vfo_update,(gpointer)NULL); ++} ++ ++void vox_changed(int state) { ++ setVox(state); } ++ void setTune(int state) { int i; @@@ -659,63 -659,63 +838,50 @@@ } } -- int mode=vfo[VFO_A].mode;; ++ int mode=vfo[VFO_A].mode; if(split) { mode=vfo[VFO_B].mode; } -- double freq=(double)cw_keyer_sidetone_frequency; -- -- pre_tune_filter_low=transmitter->filter_low; -- pre_tune_filter_high=transmitter->filter_high; ++ pre_tune_mode=mode; switch(mode) { -- case modeUSB: -- case modeCWU: -- case modeDIGU: -- SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency); -- transmitter->filter_low=cw_keyer_sidetone_frequency-100; -- transmitter->filter_high=cw_keyer_sidetone_frequency+100; -- freq=(double)(cw_keyer_sidetone_frequency+100); -- break; case modeLSB: case modeCWL: case modeDIGL: SetTXAPostGenToneFreq(transmitter->id,-(double)cw_keyer_sidetone_frequency); -- transmitter->filter_low=-cw_keyer_sidetone_frequency-100; -- transmitter->filter_high=-cw_keyer_sidetone_frequency+100; -- freq=(double)(-cw_keyer_sidetone_frequency-100); -- break; -- case modeDSB: -- SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency); -- transmitter->filter_low=cw_keyer_sidetone_frequency-100; -- transmitter->filter_high=cw_keyer_sidetone_frequency+100; -- freq=(double)(cw_keyer_sidetone_frequency+100); break; -- case modeAM: -- case modeSAM: -- case modeFMN: ++ default: SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency); -- transmitter->filter_low=cw_keyer_sidetone_frequency-100; -- transmitter->filter_high=cw_keyer_sidetone_frequency+100; -- freq=(double)(cw_keyer_sidetone_frequency+100); break; } -- SetTXABandpassFreqs(transmitter->id,transmitter->filter_low,transmitter->filter_high); -- -- -- SetTXAMode(transmitter->id,modeDIGU); -- SetTXAPostGenMode(transmitter->id,0); SetTXAPostGenToneMag(transmitter->id,0.99999); ++ SetTXAPostGenMode(transmitter->id,0); SetTXAPostGenRun(transmitter->id,1); ++ ++ switch(mode) { ++ case modeCWL: ++ cw_keyer_internal=0; ++ tx_set_mode(transmitter,modeLSB); ++ break; ++ case modeCWU: ++ cw_keyer_internal=0; ++ tx_set_mode(transmitter,modeUSB); ++ break; ++ } ++ rxtx(tune); } else { ++ rxtx(tune); SetTXAPostGenRun(transmitter->id,0); -- SetTXAMode(transmitter->id,transmitter->mode); -- transmitter->filter_low=pre_tune_filter_low; -- transmitter->filter_high=pre_tune_filter_high; -- SetTXABandpassFreqs(transmitter->id,transmitter->filter_low,transmitter->filter_high); ++ switch(pre_tune_mode) { ++ case modeCWL: ++ case modeCWU: ++ tx_set_mode(transmitter,pre_tune_mode); ++ cw_keyer_internal=1; ++ break; ++ } ++ } -- rxtx(tune); } } @@@ -723,8 -723,8 +889,31 @@@ int getTune() return tune; } ++void radio_cw_setup() { ++ int mode=vfo[VFO_A].mode;; ++ if(split) { ++ mode=vfo[VFO_B].mode; ++ } ++ ++ double freq=(double)cw_keyer_sidetone_frequency; ++ switch(mode) { ++ case modeCWU: ++ SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency); ++ break; ++ case modeLSB: ++ SetTXAPostGenToneFreq(transmitter->id,-(double)cw_keyer_sidetone_frequency); ++ break; ++ } ++ SetTXAPostGenMode(transmitter->id,0); ++ SetTXAPostGenToneMag(transmitter->id,0.99999); ++} ++ ++void radio_cw_key(int state) { ++ SetTXAPostGenRun(transmitter->id,state); ++} ++ int isTransmitting() { -- return ptt || mox || vox || tune; ++ return ptt | mox | vox | tune; } void setFrequency(long long f) { @@@ -735,18 -735,18 +924,12 @@@ switch(protocol) { case NEW_PROTOCOL: case ORIGINAL_PROTOCOL: --<<<<<<< HEAD #ifdef RADIOBERRY case RADIOBERRY_PROTOCOL: #endif -- if(ctun) { -- long long minf=entry->frequencyA-(long long)(sample_rate/2); -- long long maxf=entry->frequencyA+(long long)(sample_rate/2); --======= if(vfo[v].ctun) { long long minf=vfo[v].frequency-(long long)(active_receiver->sample_rate/2); long long maxf=vfo[v].frequency+(long long)(active_receiver->sample_rate/2); -->>>>>>> upstream/master if(fmaxf) f=maxf; vfo[v].offset=f-vfo[v].frequency; @@@ -760,12 -760,12 +943,13 @@@ #ifdef LIMESDR case LIMESDR_PROTOCOL: { -- long long minf=entry->frequency-(long long)(active_receiver->sample_rate/2); -- long long maxf=entry->frequency+(long long)(active_receiver->sample_rate/2); ++fprintf(stderr,"setFrequency: %lld\n",f); ++ long long minf=vfo[v].frequency-(long long)(active_receiver->sample_rate/2); ++ long long maxf=vfo[v].frequency+(long long)(active_receiver->sample_rate/2); if(fmaxf) f=maxf; -- ddsOffset=f-entry->frequency; -- wdsp_set_offset(ddsOffset); ++ vfo[v].offset=f-vfo[v].frequency; ++ set_offset(active_receiver,vfo[v].offset); return; } break; @@@ -780,13 -780,13 +964,12 @@@ #ifdef RADIOBERRY case RADIOBERRY_PROTOCOL: #endif -- schedule_frequency_changed(); break; #ifdef LIMESDR case LIMESDR_PROTOCOL: lime_protocol_set_frequency(f); -- ddsOffset=0; -- wdsp_set_offset(ddsOffset); ++ vfo[v].offset=0; ++ set_offset(active_receiver,vfo[v].offset); break; #endif } @@@ -797,7 -797,7 +980,7 @@@ long long getFrequency() } double getDrive() { -- return drive; ++ return transmitter->drive; } static int calcLevel(double d) { @@@ -820,35 -820,35 +1003,36 @@@ } level=(int)(actual_volts*255.0); ++ ++//fprintf(stderr,"calcLevel: %f calib=%f level=%d\n",d, gbb, level); return level; } void calcDriveLevel() { -- drive_level=calcLevel(drive); ++ transmitter->drive_level=calcLevel(transmitter->drive); if(mox && protocol==NEW_PROTOCOL) { schedule_high_priority(); } ++//fprintf(stderr,"calcDriveLevel: drive=%d drive_level=%d\n",transmitter->drive,transmitter->drive_level); } void setDrive(double value) { -- drive=value; ++ transmitter->drive=value; calcDriveLevel(); } double getTuneDrive() { -- return tune_drive; ++ return transmitter->tune_percent; } --void calcTuneDriveLevel() { -- tune_drive_level=calcLevel(tune_drive); -- if(tune && protocol==NEW_PROTOCOL) { -- schedule_high_priority(); -- } --} ++void setSquelch(RECEIVER *rx) { ++ double am_sq=((rx->squelch/100.0)*160.0)-160.0; ++ SetRXAAMSQThreshold(rx->id, am_sq); ++ SetRXAAMSQRun(rx->id, rx->squelch_enable); --void setTuneDrive(double value) { -- tune_drive=value; -- calcTuneDriveLevel(); ++ double fm_sq=pow(10.0, -2.0*rx->squelch/100.0); ++ SetRXAFMSQThreshold(rx->id, fm_sq); ++ SetRXAFMSQRun(rx->id, rx->squelch_enable); } void set_attenuation(int value) { @@@ -864,10 -864,10 +1048,6 @@@ } } --int get_attenuation() { -- return active_receiver->attenuation; --} -- void set_alex_rx_antenna(int v) { if(active_receiver->id==0) { active_receiver->alex_antenna=v; @@@ -905,6 -905,6 +1085,8 @@@ fprintf(stderr,"radioRestoreState: %s\n sem_wait(&property_sem); loadProperties(property_path); ++ value=getProperty("region"); ++ if(value) region=atoi(value); value=getProperty("buffer_size"); if(value) buffer_size=atoi(value); value=getProperty("fft_size"); @@@ -945,14 -945,14 +1127,6 @@@ if(value) waterfall_high=atoi(value); value=getProperty("waterfall_low"); if(value) waterfall_low=atoi(value); -- value=getProperty("waterfall_automatic"); -- if(value) waterfall_automatic=atoi(value); --// value=getProperty("volume"); --// if(value) volume=atof(value); -- value=getProperty("drive"); -- if(value) drive=atof(value); -- value=getProperty("tune_drive"); -- if(value) tune_drive=atof(value); value=getProperty("mic_gain"); if(value) mic_gain=atof(value); value=getProperty("mic_boost"); @@@ -1009,11 -1009,11 +1183,8 @@@ if(value) OCfull_tune_time=atoi(value); value=getProperty("OCmemory_tune_time"); if(value) OCmemory_tune_time=atoi(value); --#ifdef FREEDV -- strcpy(freedv_tx_text_data,"NO TEXT DATA"); -- value=getProperty("freedv_tx_text_data"); -- if(value) strcpy(freedv_tx_text_data,value); --#endif ++ value=getProperty("analog_meter"); ++ if(value) analog_meter=atoi(value); value=getProperty("smeter"); if(value) smeter=atoi(value); value=getProperty("alc"); @@@ -1050,8 -1050,8 +1221,6 @@@ if(value) rx_equalizer[3]=atoi(value); value=getProperty("rit_increment"); if(value) rit_increment=atoi(value); -- value=getProperty("deviation"); -- if(value) deviation=atoi(value); value=getProperty("pre_emphasize"); if(value) pre_emphasize=atoi(value); @@@ -1078,6 -1078,6 +1247,9 @@@ value=getProperty("filterB"); if(value) filterB=atoi(value); ++ value=getProperty("tone_level"); ++ if(value) tone_level=atof(value); ++ #ifdef GPIO value=getProperty("e1_encoder_action"); if(value) e1_encoder_action=atoi(value); @@@ -1094,6 -1094,6 +1266,18 @@@ bandRestoreState(); memRestoreState(); vfo_restore_state(); ++#ifdef FREEDV ++ freedv_restore_state(); ++#endif ++ value=getProperty("rigctl_enable"); ++ if(value) rigctl_enable=atoi(value); ++ value=getProperty("rigctl_port_base"); ++ if(value) rigctl_port_base=atoi(value); ++ ++ value=getProperty("adc_0_attenuation"); ++ if(value) adc_attenuation[0]=atoi(value); ++ value=getProperty("adc_1_attenuation"); ++ if(value) adc_attenuation[1]=atoi(value); sem_post(&property_sem); } @@@ -1103,6 -1103,6 +1287,8 @@@ void radioSaveState() char value[80]; sem_wait(&property_sem); ++ sprintf(value,"%d",region); ++ setProperty("region",value); sprintf(value,"%d",buffer_size); setProperty("buffer_size",value); sprintf(value,"%d",fft_size); @@@ -1113,12 -1113,12 +1299,6 @@@ setProperty("filter_board",value); sprintf(value,"%d",tx_out_of_band); setProperty("tx_out_of_band",value); --/* -- sprintf(value,"%d",apollo_tuner); -- setProperty("apollo_tuner",value); -- sprintf(value,"%d",pa); -- setProperty("pa",value); --*/ sprintf(value,"%d",updates_per_second); setProperty("updates_per_second",value); sprintf(value,"%d",display_filled); @@@ -1135,24 -1135,24 +1315,12 @@@ setProperty("panadapter_low",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); setProperty("waterfall_low",value); -- sprintf(value,"%d",waterfall_automatic); -- setProperty("waterfall_automatic",value); --// sprintf(value,"%f",volume); --// setProperty("volume",value); sprintf(value,"%f",mic_gain); setProperty("mic_gain",value); -- sprintf(value,"%f",drive); -- setProperty("drive",value); -- sprintf(value,"%f",tune_drive); -- setProperty("tune_drive",value); sprintf(value,"%d",mic_boost); setProperty("mic_boost",value); sprintf(value,"%d",mic_linein); @@@ -1204,11 -1204,11 +1372,8 @@@ setProperty("OCfull_tune_time",value); sprintf(value,"%d",OCmemory_tune_time); setProperty("OCmemory_tune_time",value); --#ifdef FREEDV -- if(strlen(freedv_tx_text_data)>0) { -- setProperty("freedv_tx_text_data",freedv_tx_text_data); -- } --#endif ++ sprintf(value,"%d",analog_meter); ++ setProperty("analog_meter",value); sprintf(value,"%d",smeter); setProperty("smeter",value); sprintf(value,"%d",alc); @@@ -1221,8 -1221,8 +1386,6 @@@ #endif sprintf(value,"%d",local_microphone); setProperty("local_microphone",value); --// sprintf(value,"%d",n_selected_input_device); --// setProperty("n_selected_input_device",value); sprintf(value,"%d",enable_tx_equalizer); setProperty("enable_tx_equalizer",value); @@@ -1246,8 -1246,8 +1409,6 @@@ setProperty("rx_equalizer.3",value); sprintf(value,"%d",rit_increment); setProperty("rit_increment",value); -- sprintf(value,"%d",deviation); -- setProperty("deviation",value); sprintf(value,"%d",pre_emphasize); setProperty("pre_emphasize",value); @@@ -1255,10 -1255,10 +1416,6 @@@ setProperty("vox_enabled",value); sprintf(value,"%f",vox_threshold); setProperty("vox_threshold",value); --/* -- sprintf(value,"%f",vox_gain); -- setProperty("vox_gain",value); --*/ sprintf(value,"%f",vox_hang); setProperty("vox_hang",value); @@@ -1272,6 -1272,6 +1429,9 @@@ sprintf(value,"%d",filterB); setProperty("filterB",value); ++ sprintf(value,"%f",tone_level); ++ setProperty("tone_level",value); ++ #ifdef GPIO sprintf(value,"%d",e1_encoder_action); setProperty("e1_encoder_action",value); @@@ -1281,6 -1281,6 +1441,10 @@@ setProperty("e3_encoder_action",value); #endif ++ sprintf(value,"%d",adc_attenuation[0]); ++ setProperty("adc_0_attenuation",value); ++ sprintf(value,"%d",adc_attenuation[1]); ++ setProperty("adc_1_attenuation",value); vfo_save_state(); sprintf(value,"%d",receivers); @@@ -1289,10 -1289,10 +1453,19 @@@ receiver_save_state(receiver[i]); } transmitter_save_state(transmitter); ++#ifdef FREEDV ++ freedv_save_state(); ++#endif filterSaveState(); bandSaveState(); memSaveState(); ++ ++ sprintf(value,"%d",rigctl_enable); ++ setProperty("rigctl_enable",value); ++ sprintf(value,"%d",rigctl_port_base); ++ setProperty("rigctl_port_base",value); ++ saveProperties(property_path); sem_post(&property_sem); } @@@ -1307,3 -1307,3 +1480,62 @@@ void calculate_display_average(RECEIVE SetDisplayAvBackmult(rx->id, 0, display_avb); SetDisplayNumAverage(rx->id, 0, display_average); } ++ ++void set_filter_type(int filter_type) { ++ int i; ++ ++ fprintf(stderr,"set_filter_type: %d\n",filter_type); ++ for(i=0;ilow_latency=filter_type; ++ RXASetMP(receiver[i]->id, filter_type); ++ } ++ transmitter->low_latency=filter_type; ++ TXASetMP(transmitter->id, filter_type); ++} ++ ++void set_filter_size(int filter_size) { ++ int i; ++ ++ fprintf(stderr,"set_filter_size: %d\n",filter_size); ++ for(i=0;ifft_size=filter_size; ++ RXASetNC(receiver[i]->id, filter_size); ++ } ++ transmitter->fft_size=filter_size; ++ TXASetNC(transmitter->id, filter_size); ++} ++ ++#ifdef FREEDV ++void set_freedv(int state) { ++fprintf(stderr,"set_freedv: rx=%p state=%d\n",active_receiver,state); ++ g_mutex_lock(&active_receiver->freedv_mutex); ++ active_receiver->freedv=state; ++ if(active_receiver->freedv) { ++ SetRXAPanelRun(active_receiver->id, 0); ++ init_freedv(active_receiver); ++ transmitter->freedv_samples=0; ++ } else { ++ SetRXAPanelRun(active_receiver->id, 1); ++ close_freedv(active_receiver); ++ } ++ g_mutex_unlock(&active_receiver->freedv_mutex); ++ g_idle_add(ext_vfo_update,NULL); ++} ++#endif ++ ++void radio_change_region(int r) { ++ region=r; ++ if(region==REGION_UK) { ++ channel_entries=UK_CHANNEL_ENTRIES; ++ band_channels_60m=&band_channels_60m_UK[0]; ++ bandstack60.entries=UK_CHANNEL_ENTRIES; ++ bandstack60.current_entry=0; ++ bandstack60.entry=bandstack_entries60_UK; ++ } else { ++ channel_entries=OTHER_CHANNEL_ENTRIES; ++ band_channels_60m=&band_channels_60m_OTHER[0]; ++ bandstack60.entries=OTHER_CHANNEL_ENTRIES; ++ bandstack60.current_entry=0; ++ bandstack60.entry=bandstack_entries60_OTHER; ++ } ++} diff --cc radioberry.c index 5c832c5,712e724..9033d2d --- a/radioberry.c +++ b/radioberry.c @@@ -431,4 -332,5 +431,4 @@@ void spiWriter() printf("Code tx mode spi executed in %f milliseconds.\n", elapsd); gettimeofday(&t20, 0); } - } + } - diff --cc radioberry.c.orig index 0000000,0000000..112c171 new file mode 100644 --- /dev/null +++ b/radioberry.c.orig @@@ -1,0 -1,0 +1,383 @@@ ++/* Copyright (C) ++* 2017 - Johan Maas, PA3GSB ++* ++* 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 "audio.h" ++ ++#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" ++#include "vox.h" ++#include ++#ifdef PSK ++#include "psk.h" ++#endif ++#include "receiver.h" ++#include "transmitter.h" ++#include "vfo.h" ++ ++#include ++#include "ext.h" ++ ++#define OUTPUT_BUFFER_SIZE 1024 ++#define SPEED_48K 0x00 ++#define SPEED_96K 0x01 ++#define SPEED_192K 0x02 ++#define SPEED_384K 0x03 ++ ++static int display_width; ++static int running; ++static int sampleSpeed =0; ++ ++unsigned char iqdata[6]; ++unsigned char tx_iqdata[6]; ++ ++static pthread_t radioberry_thread_id; ++static void start_radioberry_thread(); ++static void *radioberry_thread(void* arg); ++ ++static void setSampleSpeed(); ++static void handleReceiveStream(); ++ ++struct timeval t0; ++struct timeval t1; ++struct timeval t10; ++struct timeval t11; ++struct timeval t20; ++struct timeval t21; ++float elapsed; ++ ++#define RADIOSTATE_RX 0 ++#define RADIOSTATE_TX 1 ++static int radiostate = RADIOSTATE_RX; ++ ++void spiWriter(); ++void spiReader(); ++ ++ ++int prev_drive_level; ++ ++static int rxcount =0; ++static int txcount =0; ++ ++sem_t mutex; ++ ++#ifdef PSK ++static int psk_samples=0; ++static int psk_divisor=6; ++#endif ++ ++static int h; ++ ++ ++#define HANDLER_STEADY_TIME_US 5000 ++void setup_handler(int pin, gpioAlertFunc_t pAlert) { ++ gpioSetMode(pin, PI_INPUT); ++ gpioSetPullUpDown(pin,PI_PUD_UP); ++ // give time to settle to avoid false triggers ++ usleep(10000); ++ gpioSetAlertFunc(pin, pAlert); ++ gpioGlitchFilter(pin, HANDLER_STEADY_TIME_US); ++} ++ ++void cwPTT_Alert(int gpio, int level, uint32_t tick) { ++ //fprintf(stderr,"radioberry ptt swith %d 0=ptt off and 1=ptt on\n", level); ++ //fprintf(stderr,"%d - %d -%d - %d\n", running, cw_breakin, transmitter->mode, level); ++ if (running && cw_breakin && (transmitter->mode==modeCWU || transmitter->mode==modeCWL)){ ++ g_idle_add(ext_mox_update,(gpointer)level); ++ } ++} ++ ++float timedifference_msec(struct timeval t0, struct timeval t1) ++{ ++ return (t1.tv_sec - t0.tv_sec) * 1000.0f + (t1.tv_usec - t0.tv_usec) / 1000.0f; ++} ++ ++void radioberry_protocol_init(int rx,int pixels) { ++ int i; ++ ++ fprintf(stderr,"radioberry_protocol_init\n"); ++ sem_init(&mutex, 0, 1); //mutal exlusion ++ display_width=pixels; ++ fprintf(stderr,"radioberry_protocol: buffer size: =%d\n", buffer_size); ++ ++/* ++ if (gpioInitialise() < 0) { ++ fprintf(stderr,"radioberry_protocol: gpio could not be initialized. \n"); ++ exit(-1); ++ } ++<<<<<<< HEAD ++*/ ++ ++ gpioSetMode(13, PI_INPUT); //rx1_FIFOEmpty ++ gpioSetMode(16, PI_INPUT); //rx2_FIFOEmpty ++======= ++#endif ++ ++ gpioSetMode(13, PI_INPUT); ++>>>>>>> upstream/master ++ gpioSetMode(20, PI_INPUT); ++ gpioSetMode(21, PI_OUTPUT); ++ ++ setup_handler(17, cwPTT_Alert); ++ ++ ++ h = spiOpen(0, 15625000, 49155); ++ if (h < 0) { ++ fprintf(stderr,"radioberry_protocol: spi bus could not be initialized. \n"); ++ exit(-1); ++ } ++ ++ printf("init done \n"); ++ ++ setSampleSpeed(); ++ ++ if(transmitter->local_microphone) { ++ if(audio_open_input()!=0) { ++ fprintf(stderr,"audio_open_input failed\n"); ++ transmitter->local_microphone=0; ++ } ++ } ++ ++ start_radioberry_thread(); ++} ++ ++static void start_radioberry_thread() { ++ int rc; ++ fprintf(stderr,"radioberry_protocol starting radioberry thread\n"); ++ rc=pthread_create(&radioberry_thread_id,NULL,radioberry_thread,NULL); ++ if(rc != 0) { ++ fprintf(stderr,"radioberry_protocol: pthread_create failed on radioberry_thread: rc=%d\n", rc); ++ exit(-1); ++ } ++} ++ ++static void *radioberry_thread(void* arg) { ++ fprintf(stderr, "radioberry_protocol: radioberry_thread\n"); ++ ++ running=1; ++ ++ gettimeofday(&t20, 0); ++ gettimeofday(&t0, 0); ++ ++ gpioSetMode(13, PI_INPUT); ++ gpioSetMode(20, PI_INPUT); ++ gpioSetMode(21, PI_OUTPUT); ++ ++ while(running) { ++ ++ sem_wait(&mutex); ++ ++ if (isTransmitting()) ++ radiostate = RADIOSTATE_TX; ++ else ++ radiostate = RADIOSTATE_RX; ++ ++ if(radiostate == RADIOSTATE_TX) { ++ gpioWrite(21, 1); ++ } ++ else ++ { ++ gpioWrite(21, 0); ++ spiReader(); ++ handleReceiveStream(); ++ sem_post(&mutex); ++ } ++ } ++} ++ ++void radioberry_protocol_iq_samples(int isample,int qsample) { ++ ++ if(radiostate == RADIOSTATE_TX) { ++ ++ tx_iqdata[0] = 0; ++ tx_iqdata[1] = transmitter->drive / 6.4; // convert drive level from 0-255 to 0-39 ) ++ if (prev_drive_level != transmitter->drive) { ++ printf("drive level %d - corrected drive level %d \n", transmitter->drive_level, tx_iqdata[1]); ++ prev_drive_level = transmitter->drive; ++ } ++ tx_iqdata[2] = isample>>8; ++ tx_iqdata[3] = isample; ++ tx_iqdata[4] = qsample>>8; ++ tx_iqdata[5] = qsample; ++ ++ spiWriter(); ++ ++ sem_post(&mutex); ++ } ++ ++} ++ ++void *radioberry_protocol_process_local_mic(unsigned char *buffer,int le) { ++ int b; ++ short mic_sample; ++ // always 48000 samples per second ++ ++ b=0; ++ int i; ++ for(i=0;i<1024;i++) { ++ if(le) { ++ mic_sample = (short)((buffer[b++]&0xFF) | (buffer[b++]<<8)); ++ } else { ++ mic_sample = (short)((buffer[b++]<<8) | (buffer[b++]&0xFF)); ++ } ++ if(active_receiver->freedv) { ++ add_freedv_mic_sample(transmitter,mic_sample); ++ } else { ++ add_mic_sample(transmitter,mic_sample); ++ } ++ } ++} ++ ++static void handleReceiveStream() { ++ int left_sample; ++ int right_sample; ++ double left_sample_double; ++ double right_sample_double; ++ int r; ++ ++ left_sample = (int)((signed char) iqdata[0]) << 16; ++ left_sample += (int)((unsigned char)iqdata[1]) << 8; ++ left_sample += (int)((unsigned char)iqdata[2]); ++ right_sample = (int)((signed char) iqdata[3]) << 16; ++ right_sample += (int)((unsigned char)iqdata[4]) << 8; ++ right_sample += (int)((unsigned char)iqdata[5]); ++ ++ left_sample_double=(double)left_sample/8388607.0; // 24 bit sample 2^23-1 ++ right_sample_double=(double)right_sample/8388607.0; // 24 bit sample 2^23-1 ++ ++ for(r=0;rsample_rate) { ++ case 48000: ++ sampleSpeed=SPEED_48K; ++ break; ++ case 96000: ++ sampleSpeed=SPEED_96K; ++ break; ++ case 192000: ++ sampleSpeed=SPEED_192K; ++ break; ++ case 384000: ++ sampleSpeed=SPEED_384K; ++ break; ++ } ++} ++ ++void radioberry_protocol_stop() { ++ ++ running=FALSE; ++ ++ if (h !=0) ++ spiClose(h); ++ ++#ifndef GPIO ++ gpioTerminate(); ++#endif ++ ++} ++ ++void spiReader() { ++ // wait till rxFIFO buffer is filled with at least one element ++ while ( gpioRead(13) == 1) {}; ++ ++ setSampleSpeed(); ++ ++ int v=receiver[0]->id; ++ long long rxFrequency=vfo[v].frequency-vfo[v].lo; ++ if(vfo[v].rit_enabled) { ++ rxFrequency+=vfo[v].rit; ++ } ++ if(vfo[active_receiver->id].mode==modeCWU) { ++ rxFrequency-=(long long)cw_keyer_sidetone_frequency; ++ } else if(vfo[active_receiver->id].mode==modeCWL) { ++ rxFrequency+=(long long)cw_keyer_sidetone_frequency; ++ } ++ ++ iqdata[0] = (sampleSpeed & 0x03); ++ iqdata[1] = (((active_receiver->random << 6) & 0x40) | ((active_receiver->dither <<5) & 0x20) | (attenuation & 0x1F)); ++ iqdata[2] = ((rxFrequency >> 24) & 0xFF); ++ iqdata[3] = ((rxFrequency >> 16) & 0xFF); ++ iqdata[4] = ((rxFrequency >> 8) & 0xFF); ++ iqdata[5] = (rxFrequency & 0xFF); ++ ++ spiXfer(h, iqdata, iqdata, 6); ++ ++ //firmware: tdata(56'h00010203040506) -> 0-1-2-3-4-5-6 (element 0 contains 0; second element contains 1) ++ rxcount ++; ++ if (rxcount == 48000) { ++ rxcount = 0; ++ gettimeofday(&t1, 0); ++ elapsed = timedifference_msec(t0, t1); ++ printf("Code rx mode spi executed in %f milliseconds.\n", elapsed); ++ gettimeofday(&t0, 0); ++ } ++} ++ ++void spiWriter() { ++ while ( gpioRead(20) == 1) {}; ++ ++<<<<<<< HEAD ++ spiXfer(rx1_spi_handler, tx_iqdata, tx_iqdata, 6); ++ ++ long long txFrequency; ++ if(split) { ++ txFrequency=vfo[VFO_B].frequency-vfo[VFO_A].lo+vfo[VFO_B].offset; ++ } else { ++ txFrequency=vfo[VFO_A].frequency-vfo[VFO_B].lo+vfo[VFO_A].offset; ++ } ++ tx_iqdata[0] = cw_keyer_speed | (cw_keyer_mode<<6); ++ tx_iqdata[1] = cw_keyer_weight | (cw_keyer_spacing<<7); ++ tx_iqdata[2] = ((txFrequency >> 24) & 0xFF); ++ tx_iqdata[3] = ((txFrequency >> 16) & 0xFF); ++ tx_iqdata[4] = ((txFrequency >> 8) & 0xFF); ++ tx_iqdata[5] = (txFrequency & 0xFF); ++ ++ spiXfer(rx2_spi_handler, tx_iqdata, tx_iqdata, 6); ++======= ++ spiXfer(h, tx_iqdata, tx_iqdata, 6); ++>>>>>>> upstream/master ++ ++ txcount ++; ++ if (txcount == 48000) { ++ txcount = 0; ++ gettimeofday(&t21, 0); ++ float elapsd = timedifference_msec(t20, t21); ++ printf("Code tx mode spi executed in %f milliseconds.\n", elapsd); ++ gettimeofday(&t20, 0); ++ } ++} diff --cc transmitter.c.orig index 0000000,0000000..1adc8d6 new file mode 100644 --- /dev/null +++ b/transmitter.c.orig @@@ -1,0 -1,0 +1,1013 @@@ ++/* Copyright (C) ++* 2017 - 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 "alex.h" ++#include "band.h" ++#include "bandstack.h" ++#include "channel.h" ++#include "main.h" ++#include "receiver.h" ++#include "meter.h" ++#include "mode.h" ++#include "property.h" ++#include "radio.h" ++#include "vfo.h" ++#include "vox.h" ++#include "meter.h" ++#include "toolbar.h" ++#include "tx_panadapter.h" ++#include "waterfall.h" ++#include "receiver.h" ++#include "transmitter.h" ++#include "new_protocol.h" ++#include "old_protocol.h" ++#ifdef FREEDV ++#include "freedv.h" ++#endif ++#include "audio_waterfall.h" ++#include "ext.h" ++<<<<<<< HEAD ++ ++double getNextSideToneSample(); ++======= ++>>>>>>> upstream/master ++ ++#define min(x,y) (x>>>>>> upstream/master ++static gint update_out_of_band(gpointer data) { ++ TRANSMITTER *tx=(TRANSMITTER *)data; ++ tx->out_of_band=0; ++ vfo_update(); ++ return FALSE; ++} ++ ++void transmitter_set_out_of_band(TRANSMITTER *tx) { ++ tx->out_of_band=1; ++ tx->out_of_band_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000,update_out_of_band, tx, NULL); ++} ++ ++void transmitter_set_deviation(TRANSMITTER *tx) { ++ SetTXAFMDeviation(tx->id, (double)tx->deviation); ++} ++ ++void transmitter_set_am_carrier_level(TRANSMITTER *tx) { ++ SetTXAAMCarrierLevel(tx->id, tx->am_carrier_level); ++} ++ ++void transmitter_set_ctcss(TRANSMITTER *tx,int run,double frequency) { ++ tx->ctcss=run; ++ tx->ctcss_frequency=frequency; ++fprintf(stderr,"transmitter_set_ctcss: ctcss_frequency=%f run=%d\n",tx->ctcss_frequency,tx->ctcss); ++ SetTXACTCSSFreq(tx->id, tx->ctcss_frequency); ++ SetTXACTCSSRun(tx->id, tx->ctcss); ++} ++ ++void transmitter_set_compressor_level(TRANSMITTER *tx,double level) { ++ tx->compressor_level=level; ++ SetTXACompressorGain(tx->id, tx->compressor_level); ++} ++ ++void transmitter_set_compressor(TRANSMITTER *tx,int state) { ++ tx->compressor=state; ++ SetTXACompressorRun(tx->id, tx->compressor); ++} ++ ++void reconfigure_transmitter(TRANSMITTER *tx,int height) { ++ gtk_widget_set_size_request(tx->panadapter, tx->width, height); ++} ++ ++void transmitter_save_state(TRANSMITTER *tx) { ++ char name[128]; ++ char value[128]; ++ ++ sprintf(name,"transmitter.%d.fps",tx->id); ++ sprintf(value,"%d",tx->fps); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.filter_low",tx->id); ++ sprintf(value,"%d",tx->filter_low); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.filter_high",tx->id); ++ sprintf(value,"%d",tx->filter_high); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.alex_antenna",tx->id); ++ sprintf(value,"%d",tx->alex_antenna); ++ setProperty(name,value); ++ ++ sprintf(name,"transmitter.%d.panadapter_low",tx->id); ++ sprintf(value,"%d",tx->panadapter_low); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.panadapter_high",tx->id); ++ sprintf(value,"%d",tx->panadapter_high); ++ setProperty(name,value); ++ ++ sprintf(name,"transmitter.%d.local_microphone",tx->id); ++ sprintf(value,"%d",tx->local_microphone); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.input_device",tx->id); ++ sprintf(value,"%d",tx->input_device); ++ setProperty(name,value); ++ ++ sprintf(name,"transmitter.%d.low_latency",tx->id); ++ sprintf(value,"%d",tx->low_latency); ++ setProperty(name,value); ++#ifdef PURESIGNAL ++ sprintf(name,"transmitter.%d.puresignal",tx->id); ++ sprintf(value,"%d",tx->puresignal); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.auto_on",tx->id); ++ sprintf(value,"%d",tx->auto_on); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.single_on",tx->id); ++ sprintf(value,"%d",tx->single_on); ++ setProperty(name,value); ++#endif ++ sprintf(name,"transmitter.%d.ctcss",tx->id); ++ sprintf(value,"%d",tx->ctcss); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.ctcss_frequency",tx->id); ++ sprintf(value,"%f",tx->ctcss_frequency); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.deviation",tx->id); ++ sprintf(value,"%d",tx->deviation); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.am_carrier_level",tx->id); ++ sprintf(value,"%f",tx->am_carrier_level); ++ setProperty(name,value); ++#ifdef FREEDV ++ if(strlen(tx->freedv_text_data)>0) { ++ sprintf(name,"transmitter.%d.freedv_text_data",tx->id); ++ sprintf(value,"%s",tx->freedv_text_data); ++ setProperty(name,value); ++ } ++#endif ++ sprintf(name,"transmitter.%d.drive",tx->id); ++ sprintf(value,"%d",tx->drive); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.tune_percent",tx->id); ++ sprintf(value,"%d",tx->tune_percent); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.tune_use_drive",tx->id); ++ sprintf(value,"%d",tx->tune_use_drive); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.drive_level",tx->id); ++ sprintf(value,"%d",tx->drive_level); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.compressor",tx->id); ++ sprintf(value,"%d",tx->compressor); ++ setProperty(name,value); ++ sprintf(name,"transmitter.%d.compressor_level",tx->id); ++ sprintf(value,"%f",tx->compressor_level); ++ setProperty(name,value); ++} ++ ++void transmitter_restore_state(TRANSMITTER *tx) { ++ char name[128]; ++ char *value; ++ ++ sprintf(name,"transmitter.%d.fps",tx->id); ++ value=getProperty(name); ++ if(value) tx->fps=atoi(value); ++ sprintf(name,"transmitter.%d.filter_low",tx->id); ++ value=getProperty(name); ++ if(value) tx->filter_low=atoi(value); ++ sprintf(name,"transmitter.%d.filter_high",tx->id); ++ value=getProperty(name); ++ if(value) tx->filter_high=atoi(value); ++ sprintf(name,"transmitter.%d.alex_antenna",tx->id); ++ value=getProperty(name); ++ if(value) tx->alex_antenna=atoi(value); ++ ++ sprintf(name,"transmitter.%d.panadapter_low",tx->id); ++ value=getProperty(name); ++ if(value) tx->panadapter_low=atoi(value); ++ sprintf(name,"transmitter.%d.panadapter_high",tx->id); ++ value=getProperty(name); ++ if(value) tx->panadapter_high=atoi(value); ++ ++ sprintf(name,"transmitter.%d.local_microphone",tx->id); ++ value=getProperty(name); ++ if(value) tx->local_microphone=atoi(value); ++ sprintf(name,"transmitter.%d.input_device",tx->id); ++ value=getProperty(name); ++ if(value) tx->input_device=atoi(value); ++ sprintf(name,"transmitter.%d.low_latency",tx->id); ++ value=getProperty(name); ++ if(value) tx->low_latency=atoi(value); ++#ifdef PURESIGNAL ++ sprintf(name,"transmitter.%d.puresignal",tx->id); ++ value=getProperty(name); ++ if(value) tx->puresignal=atoi(value); ++ sprintf(name,"transmitter.%d.auto_on",tx->id); ++ value=getProperty(name); ++ if(value) tx->auto_on=atoi(value); ++ sprintf(name,"transmitter.%d.single_on",tx->id); ++ value=getProperty(name); ++ if(value) tx->single_on=atoi(value); ++#endif ++ sprintf(name,"transmitter.%d.ctcss",tx->id); ++ value=getProperty(name); ++ if(value) tx->ctcss=atoi(value); ++ sprintf(name,"transmitter.%d.ctcss_frequency",tx->id); ++ value=getProperty(name); ++ if(value) tx->ctcss_frequency=atof(value); ++ sprintf(name,"transmitter.%d.deviation",tx->id); ++ value=getProperty(name); ++ if(value) tx->deviation=atoi(value); ++ sprintf(name,"transmitter.%d.am_carrier_level",tx->id); ++ value=getProperty(name); ++ if(value) tx->am_carrier_level=atof(value); ++#ifdef FREEDV ++ sprintf(name,"transmitter.%d.freedv_text_data",tx->id); ++ value=getProperty(name); ++ if(value) strcpy(tx->freedv_text_data,value); ++#endif ++ sprintf(name,"transmitter.%d.drive",tx->id); ++ value=getProperty(name); ++ if(value) tx->drive=atoi(value); ++ sprintf(name,"transmitter.%d.tune_percent",tx->id); ++ value=getProperty(name); ++ if(value) tx->tune_percent=atoi(value); ++ sprintf(name,"transmitter.%d.tune_use_drive",tx->id); ++ value=getProperty(name); ++ if(value) tx->tune_use_drive=atoi(value); ++ sprintf(name,"transmitter.%d.drive_level",tx->id); ++ value=getProperty(name); ++ if(value) tx->drive_level=atoi(value); ++ sprintf(name,"transmitter.%d.compressor",tx->id); ++ value=getProperty(name); ++ if(value) tx->compressor=atoi(value); ++ sprintf(name,"transmitter.%d.compressor_level",tx->id); ++ value=getProperty(name); ++ if(value) tx->compressor_level=atof(value); ++} ++ ++static gboolean update_display(gpointer data) { ++ TRANSMITTER *tx=(TRANSMITTER *)data; ++ int rc; ++ ++ int i; ++ ++//fprintf(stderr,"update_display: tx id=%d\n",tx->id); ++ if(tx->displaying) { ++#ifdef AUDIO_SAMPLES ++ if(audio_samples!=NULL) { ++ GetPixels(CHANNEL_AUDIO,0,audio_samples,&rc); ++ if(rc) { ++ audio_waterfall_update(); ++ } ++ } ++#endif ++#ifdef PURESIGNAL ++ if(tx->puresignal && tx->feedback) { ++ RECEIVER *tx_feedback=receiver[PS_TX_FEEDBACK]; ++ GetPixels(tx_feedback->id,0,tx_feedback->pixel_samples,&rc); ++ memcpy(tx->pixel_samples,tx_feedback->pixel_samples,sizeof(float)*tx->pixels); ++ } else { ++#endif ++ GetPixels(tx->id,0,tx->pixel_samples,&rc); ++#ifdef PURESIGNAL ++ } ++#endif ++ if(rc) { ++ tx_panadapter_update(tx); ++ } ++ ++ transmitter->alc=GetTXAMeter(tx->id, alc); ++ double constant1=3.3; ++ double constant2=0.095; ++ ++#ifdef RADIOBERRY ++ if(protocol==ORIGINAL_PROTOCOL || protocol==RADIOBERRY_PROTOCOL) { ++#else ++ if(protocol==ORIGINAL_PROTOCOL) { ++#endif ++ switch(device) { ++ case DEVICE_METIS: ++ constant1=3.3; ++ constant2=0.09; ++ break; ++ case DEVICE_HERMES: ++ constant1=3.3; ++ constant2=0.095; ++ break; ++ case DEVICE_ANGELIA: ++ constant1=3.3; ++ constant2=0.095; ++ break; ++ case DEVICE_ORION: ++ constant1=5.0; ++ constant2=0.108; ++ break; ++ case DEVICE_ORION2: ++ constant1=5.0; ++ constant2=0.108; ++ break; ++ case DEVICE_HERMES_LITE: ++ break; ++#ifdef RADIOBERRY ++ case RADIOBERRY_SPI_DEVICE: ++ break; ++#endif ++ } ++ ++ int power=alex_forward_power; ++ if(power==0) { ++ power=exciter_power; ++ } ++ double v1; ++ v1=((double)power/4095.0)*constant1; ++ transmitter->fwd=(v1*v1)/constant2; ++ ++ power=exciter_power; ++ v1=((double)power/4095.0)*constant1; ++ transmitter->exciter=(v1*v1)/constant2; ++ ++ transmitter->rev=0.0; ++ if(alex_forward_power!=0) { ++ power=alex_reverse_power; ++ v1=((double)power/4095.0)*constant1; ++ transmitter->rev=(v1*v1)/constant2; ++ } ++ } else { ++ switch(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_ORION2: ++ constant1=5.0; ++ constant2=0.108; ++ break; ++ case NEW_DEVICE_HERMES_LITE: ++ constant1=3.3; ++ constant2=0.09; ++ break; ++#ifdef RADIOBERRY ++ case RADIOBERRY_SPI_DEVICE: ++ constant1=3.3; ++ constant2=0.09; ++ break; ++#endif ++ } ++ ++ int power=alex_forward_power; ++ if(power==0) { ++ power=exciter_power; ++ } ++ double v1; ++ v1=((double)power/4095.0)*constant1; ++ transmitter->fwd=(v1*v1)/constant2; ++ ++ power=exciter_power; ++ v1=((double)power/4095.0)*constant1; ++ transmitter->exciter=(v1*v1)/constant2; ++ ++ transmitter->rev=0.0; ++ if(alex_forward_power!=0) { ++ power=alex_reverse_power; ++ v1=((double)power/4095.0)*constant1; ++ transmitter->rev=(v1*v1)/constant2; ++ } ++ } ++ ++ meter_update(active_receiver,POWER,transmitter->fwd,transmitter->rev,transmitter->exciter,transmitter->alc); ++ ++ return TRUE; // keep going ++ } ++ return FALSE; // no more timer events ++} ++ ++ ++static void init_analyzer(TRANSMITTER *tx) { ++ 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=tx->pixels; ++ int stitches = 1; ++ int avm = 0; ++ double tau = 0.001 * 120.0; ++ 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) tx->fps, keep_time * (double) fft_size * (double) tx->fps); ++ ++ overlap = (int)max(0.0, ceil(fft_size - (double)tx->mic_sample_rate / (double)tx->fps)); ++ ++ fprintf(stderr,"SetAnalyzer id=%d buffer_size=%d overlap=%d\n",tx->id,tx->output_samples,overlap); ++ ++ ++ SetAnalyzer(tx->id, ++ 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 ++ tx->output_samples, //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 ++ 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 create_visual(TRANSMITTER *tx) { ++ ++ fprintf(stderr,"transmitter: create_visual: id=%d\n",tx->id); ++ ++ tx->panel=gtk_fixed_new(); ++ gtk_widget_set_size_request (tx->panel, tx->width, tx->height); ++ ++ if(tx->display_panadapter) { ++ tx_panadapter_init(tx,tx->width,tx->height); ++ gtk_fixed_put(GTK_FIXED(tx->panel),tx->panadapter,0,0); ++ } ++ ++ gtk_widget_show_all(tx->panel); ++ ++} ++ ++TRANSMITTER *create_transmitter(int id, int buffer_size, int fft_size, int fps, int width, int height) { ++ int rc; ++ ++ TRANSMITTER *tx=malloc(sizeof(TRANSMITTER)); ++ tx->id=id; ++ tx->buffer_size=buffer_size; ++ tx->fft_size=fft_size; ++ tx->fps=fps; ++ ++#ifdef RADIOBERRY ++ if(protocol==ORIGINAL_PROTOCOL || protocol==RADIOBERRY_PROTOCOL) { ++#else ++ if(protocol==ORIGINAL_PROTOCOL) { ++#endif ++ tx->mic_sample_rate=48000; ++ tx->mic_dsp_rate=48000; ++ tx->iq_output_rate=48000; ++ tx->output_samples=tx->buffer_size; ++ tx->pixels=width; // to allow 48k to 24k conversion ++ } else { ++ tx->mic_sample_rate=48000; ++ tx->mic_dsp_rate=96000; ++ tx->iq_output_rate=192000; ++ tx->output_samples=tx->buffer_size*4; ++ tx->pixels=width*4; // to allow 192k to 24k conversion ++ } ++ ++ tx->width=width; ++ tx->height=height; ++ tx->display_panadapter=1; ++ tx->display_waterfall=0; ++ ++ tx->panadapter_high=0; ++ tx->panadapter_low=-60; ++ ++ tx->displaying=0; ++ ++ tx->alex_antenna=ALEX_TX_ANTENNA_1; ++ ++fprintf(stderr,"create_transmitter: id=%d buffer_size=%d mic_sample_rate=%d mic_dsp_rate=%d iq_output_rate=%d output_samples=%d fps=%d\n",tx->id, tx->buffer_size, tx->mic_sample_rate, tx->mic_dsp_rate, tx->iq_output_rate, tx->output_samples,tx->fps); ++ ++ tx->filter_low=tx_filter_low; ++ tx->filter_high=tx_filter_high; ++ ++ tx->out_of_band=0; ++ ++ tx->low_latency=0; ++ ++#ifdef PURESIGNAL ++ tx->puresignal=0; ++ tx->feedback=0; ++ tx->twotone=0; ++ tx->auto_on=0; ++ tx->single_on=0; ++#endif ++ ++ tx->ctcss=0; ++ tx->ctcss_frequency=100.0; ++ ++ tx->deviation=2500; ++ tx->am_carrier_level=0.5; ++ ++#ifdef FREEDV ++ strcpy(tx->freedv_text_data,"Call, Name and Location"); ++ tx->freedv_samples=0; ++#endif ++ ++ tx->drive=50; ++ tx->tune_percent=10; ++ tx->tune_use_drive=0; ++ ++ tx->compressor=0; ++ tx->compressor_level=0.0; ++ ++ tx->local_microphone=0; ++ ++ transmitter_restore_state(tx); ++ ++ ++ // allocate buffers ++fprintf(stderr,"transmitter: allocate buffers: mic_input_buffer=%d iq_output_buffer=%d pixels=%d\n",tx->buffer_size,tx->output_samples,tx->pixels); ++ tx->mic_input_buffer=malloc(sizeof(double)*2*tx->buffer_size); ++ tx->iq_output_buffer=malloc(sizeof(double)*2*tx->output_samples); ++ tx->samples=0; ++ tx->pixel_samples=malloc(sizeof(float)*tx->pixels); ++fprintf(stderr,"transmitter: allocate buffers: mic_input_buffer=%p iq_output_buffer=%p pixels=%p\n",tx->mic_input_buffer,tx->iq_output_buffer,tx->pixel_samples); ++ ++ fprintf(stderr,"create_transmitter: OpenChannel id=%d buffer_size=%d fft_size=%d sample_rate=%d dspRate=%d outputRate=%d\n", ++ tx->id, ++ tx->buffer_size, ++ 2048, // tx->fft_size, ++ tx->mic_sample_rate, ++ tx->mic_dsp_rate, ++ tx->iq_output_rate); ++ ++ OpenChannel(tx->id, ++ tx->buffer_size, ++ 2048, // tx->fft_size, ++ tx->mic_sample_rate, ++ tx->mic_dsp_rate, ++ tx->iq_output_rate, ++ 1, // transmit ++ 0, // run ++ 0.010, 0.025, 0.0, 0.010, 0); ++ ++ TXASetNC(tx->id, tx->fft_size); ++ TXASetMP(tx->id, tx->low_latency); ++ ++ ++ int mode=vfo[VFO_A].mode; ++ if(split) { ++ mode=vfo[VFO_B].mode; ++ } ++ ++ SetTXABandpassWindow(tx->id, 1); ++ SetTXABandpassRun(tx->id, 1); ++ ++ SetTXAFMEmphPosition(tx->id,pre_emphasize); ++ ++ SetTXACFIRRun(tx->id, protocol==NEW_PROTOCOL?1:0); // turned on if new protocol ++ if(enable_tx_equalizer) { ++ SetTXAGrphEQ(tx->id, tx_equalizer); ++ SetTXAEQRun(tx->id, 1); ++ } else { ++ SetTXAEQRun(tx->id, 0); ++ } ++ ++ transmitter_set_ctcss(tx,tx->ctcss,tx->ctcss_frequency); ++ SetTXAAMSQRun(tx->id, 0); ++ SetTXAosctrlRun(tx->id, 0); ++ ++ SetTXAALCAttack(tx->id, 1); ++ SetTXAALCDecay(tx->id, 10); ++ SetTXAALCSt(tx->id, 1); // turn it on (always on) ++ ++ SetTXALevelerAttack(tx->id, 1); ++ SetTXALevelerDecay(tx->id, 500); ++ SetTXALevelerTop(tx->id, 5.0); ++ SetTXALevelerSt(tx->id, tx_leveler); ++ ++ SetTXAPreGenMode(tx->id, 0); ++ SetTXAPreGenToneMag(tx->id, 0.0); ++ SetTXAPreGenToneFreq(tx->id, 0.0); ++ SetTXAPreGenRun(tx->id, 0); ++ ++ SetTXAPostGenMode(tx->id, 0); ++ SetTXAPostGenToneMag(tx->id, tone_level); ++ SetTXAPostGenTTMag(tx->id, tone_level,tone_level); ++ SetTXAPostGenToneFreq(tx->id, 0.0); ++ SetTXAPostGenRun(tx->id, 0); ++ ++ double gain=pow(10.0, mic_gain / 20.0); ++ SetTXAPanelGain1(tx->id,gain); ++ SetTXAPanelRun(tx->id, 1); ++ ++ SetTXAFMDeviation(tx->id, (double)tx->deviation); ++ SetTXAAMCarrierLevel(tx->id, tx->am_carrier_level); ++ ++ SetTXACompressorGain(tx->id, tx->compressor_level); ++ SetTXACompressorRun(tx->id, tx->compressor); ++ ++ tx_set_mode(tx,mode); ++ ++ XCreateAnalyzer(tx->id, &rc, 262144, 1, 1, ""); ++ if (rc != 0) { ++ fprintf(stderr, "XCreateAnalyzer id=%d failed: %d\n",tx->id,rc); ++ } else { ++ init_analyzer(tx); ++ } ++ ++ create_visual(tx); ++ ++ return tx; ++} ++ ++void tx_set_mode(TRANSMITTER* tx,int mode) { ++ if(tx!=NULL) { ++ tx->mode=mode; ++ SetTXAMode(tx->id, tx->mode); ++ tx_set_filter(tx,tx_filter_low,tx_filter_high); ++ } ++} ++ ++void tx_set_filter(TRANSMITTER *tx,int low,int high) { ++ int mode; ++ if(split) { ++ mode=vfo[1].mode; ++ } else { ++ mode=vfo[0].mode; ++ } ++//fprintf(stderr,"tx_set_filter: tx=%p mode=%d low=%d high=%d\n",tx,mode,low,high); ++ switch(mode) { ++ case modeLSB: ++ case modeCWL: ++ case modeDIGL: ++ tx->filter_low=-high; ++ tx->filter_high=-low; ++ break; ++ case modeUSB: ++ case modeCWU: ++ case modeDIGU: ++ tx->filter_low=low; ++ tx->filter_high=high; ++ break; ++ case modeDSB: ++ case modeAM: ++ case modeSAM: ++ tx->filter_low=-high; ++ tx->filter_high=high; ++ break; ++ case modeFMN: ++ if(tx->deviation==2500) { ++ tx->filter_low=-4000; ++ tx->filter_high=4000; ++ } else { ++ tx->filter_low=-8000; ++ tx->filter_high=8000; ++ } ++ break; ++ case modeDRM: ++ tx->filter_low=7000; ++ tx->filter_high=17000; ++ break; ++ } ++ ++ double fl=tx->filter_low; ++ double fh=tx->filter_high; ++ ++ if(split) { ++ fl+=vfo[VFO_B].offset; ++ fh+=vfo[VFO_B].offset; ++ } else { ++ fl+=vfo[VFO_A].offset; ++ fh+=vfo[VFO_A].offset; ++ } ++ SetTXABandpassFreqs(tx->id, fl,fh); ++} ++ ++void tx_set_pre_emphasize(TRANSMITTER *tx,int state) { ++ SetTXAFMEmphPosition(tx->id,state); ++} ++ ++static void full_tx_buffer(TRANSMITTER *tx) { ++ long isample; ++ long qsample; ++ double gain; ++ int j; ++ int error; ++ int mode; ++ ++ switch(protocol) { ++#ifdef RADIOBERRY ++ case RADIOBERRY_PROTOCOL: ++#endif ++ case ORIGINAL_PROTOCOL: ++ gain=32767.0; // 16 bit ++ break; ++ case NEW_PROTOCOL: ++ gain=8388607.0; // 24 bit ++ break; ++ } ++ ++ update_vox(tx); ++ ++ fexchange0(tx->id, tx->mic_input_buffer, tx->iq_output_buffer, &error); ++ if(error!=0) { ++ fprintf(stderr,"full_tx_buffer: id=%d fexchange0: error=%d\n",tx->id,error); ++ } ++ ++#ifdef PURESIGNAL ++ if(tx->displaying && !(tx->puresignal && tx->feedback)) { ++#else ++ if(tx->displaying) { ++#endif ++ Spectrum0(1, tx->id, 0, 0, tx->iq_output_buffer); ++ } ++ ++ if(isTransmitting()) { ++ ++ if(radio->device==NEW_DEVICE_ATLAS && atlas_penelope) { ++ if(tune && !transmitter->tune_use_drive) { ++ gain=gain*((double)transmitter->drive_level*100.0/(double)transmitter->tune_percent); ++ } else { ++ gain=gain*(double)transmitter->drive_level; ++ } ++ } ++ ++ for(j=0;joutput_samples;j++) { ++ double is=tx->iq_output_buffer[j*2]; ++ double qs=tx->iq_output_buffer[(j*2)+1]; ++ isample=is>=0.0?(long)floor(is*gain+0.5):(long)ceil(is*gain-0.5); ++ qsample=qs>=0.0?(long)floor(qs*gain+0.5):(long)ceil(qs*gain-0.5); ++ switch(protocol) { ++ case ORIGINAL_PROTOCOL: ++ old_protocol_iq_samples(isample,qsample); ++ break; ++ case NEW_PROTOCOL: ++ new_protocol_iq_samples(isample,qsample); ++ break; ++#ifdef RADIOBERRY ++ case RADIOBERRY_PROTOCOL: ++ radioberry_protocol_iq_samples(isample,qsample); ++ break; ++#endif ++ } ++ } ++ } ++ ++} ++ ++void add_mic_sample(TRANSMITTER *tx,short mic_sample) { ++ int mode; ++ double sample; ++ double mic_sample_double; ++ int i,s; ++ ++ if(split) { ++ mode=vfo[1].mode; ++ } else { ++ mode=vfo[0].mode; ++ } ++ ++<<<<<<< HEAD ++ if (tune) { ++ mic_sample_double=0.0; ++ } ++ else if(mode==modeCWL || mode==modeCWU) { ++ if (isTransmitting()) { ++ if (key == 1) { ++ mic_sample_double = getNextSideToneSample(); ++ cw_audio_write(mic_sample_double * cw_keyer_sidetone_volume/ 127.0); ++ mic_sample_double = mic_sample_double * 200000; //* amplitude ++ } else mic_sample_double=0.0; ++ } ++ } else { ++======= ++ if(mode==modeCWL || mode==modeCWU || tune) { ++ mic_sample_double=0.0; ++ } else { ++ //long sam=mic_sample<<16; ++ //sample=(double)sam; ++ //mic_sample_double=(1.0 / 2147483648.0) * sample; ++>>>>>>> upstream/master ++ mic_sample_double=(double)mic_sample/32768.0; ++ } ++ tx->mic_input_buffer[tx->samples*2]=mic_sample_double; ++ tx->mic_input_buffer[(tx->samples*2)+1]=0.0; //mic_sample_double; ++ tx->samples++; ++ if(tx->samples==tx->buffer_size) { ++ full_tx_buffer(tx); ++ tx->samples=0; ++ } ++ ++#ifdef AUDIO_WATERFALL ++ if(audio_samples!=NULL && isTransmitting()) { ++ if(waterfall_samples==0) { ++ audio_samples[audio_samples_index]=(float)mic_sample; ++ audio_samples_index++; ++ if(audio_samples_index>=AUDIO_WATERFALL_SAMPLES) { ++ //Spectrum(CHANNEL_AUDIO,0,0,audio_samples,audio_samples); ++ audio_samples_index=0; ++ } ++ } ++ waterfall_samples++; ++ if(waterfall_samples==waterfall_resample) { ++ waterfall_samples=0; ++ } ++ } ++#endif ++} ++ ++#ifdef PURESIGNAL ++void add_ps_iq_samples(TRANSMITTER *tx, double i_sample_tx,double q_sample_tx, double i_sample_rx, double q_sample_rx) { ++ RECEIVER *tx_feedback=receiver[PS_TX_FEEDBACK]; ++ RECEIVER *rx_feedback=receiver[PS_RX_FEEDBACK]; ++ ++//fprintf(stderr,"add_ps_iq_samples: samples=%d i_rx=%f q_rx=%f i_tx=%f q_tx=%f\n",rx_feedback->samples, i_sample_rx,q_sample_rx,i_sample_tx,q_sample_tx); ++ ++ tx_feedback->iq_input_buffer[tx_feedback->samples*2]=i_sample_tx; ++ tx_feedback->iq_input_buffer[(tx_feedback->samples*2)+1]=q_sample_tx; ++ rx_feedback->iq_input_buffer[rx_feedback->samples*2]=i_sample_rx; ++ rx_feedback->iq_input_buffer[(rx_feedback->samples*2)+1]=q_sample_rx; ++ ++ tx_feedback->samples=tx_feedback->samples+1; ++ rx_feedback->samples=rx_feedback->samples+1; ++ ++ if(rx_feedback->samples>=rx_feedback->buffer_size) { ++ if(isTransmitting()) { ++ pscc(transmitter->id, rx_feedback->buffer_size, tx_feedback->iq_input_buffer, rx_feedback->iq_input_buffer); ++ if(transmitter->displaying) { ++ if(transmitter->feedback) { ++ Spectrum0(1, tx_feedback->id, 0, 0, tx_feedback->iq_input_buffer); ++ //} else { ++ // Spectrum0(1, rx_feedback->id, 0, 0, rx_feedback->iq_input_buffer); ++ } ++ } ++ } ++ rx_feedback->samples=0; ++ tx_feedback->samples=0; ++ } ++} ++#endif ++ ++#ifdef FREEDV ++void add_freedv_mic_sample(TRANSMITTER *tx, short mic_sample) { ++ int i,s; ++ ++ //if(active_receiver->freedv && isTransmitting() && !tune) { ++ if(!tune) { ++ if(tx->freedv_samples==0) { ++ //int modem_samples=mod_sample_freedv(mic_sample); ++ short vs=(short)((double)mic_sample*pow(10.0, mic_gain / 20.0)); ++ int modem_samples=mod_sample_freedv(vs); ++ if(modem_samples!=0) { ++ for(s=0;sfreedv_samples++; ++ if(tx->freedv_samples>=freedv_resample) { ++ tx->freedv_samples=0; ++ } ++ } ++} ++#endif ++ ++void tx_set_displaying(TRANSMITTER *tx,int state) { ++ tx->displaying=state; ++ if(state) { ++ tx->update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/tx->fps, update_display, (gpointer)tx, NULL); ++<<<<<<< HEAD ++ } ++} ++ ++#ifdef PURESIGNAL ++void tx_set_ps(TRANSMITTER *tx,int state) { ++ tx->puresignal=state; ++ if(state) { ++ SetPSControl(tx->id, 0, 0, 1, 0); ++ } else { ++ SetPSControl(tx->id, 1, 0, 0, 0); ++ } ++ vfo_update(); ++} ++ ++void tx_set_twotone(TRANSMITTER *tx,int state) { ++ transmitter->twotone=state; ++ if(state) { ++ SetTXAPostGenMode(transmitter->id, 1); ++ SetTXAPostGenRun(transmitter->id, 1); ++ } else { ++ SetTXAPostGenRun(transmitter->id, 0); ++======= ++>>>>>>> upstream/master ++ } ++ g_idle_add(ext_mox_update,(gpointer)(long)state); ++} ++ ++void tx_set_ps_sample_rate(TRANSMITTER *tx,int rate) { ++ SetPSFeedbackRate (tx->id,rate); ++} ++#endif ++ ++void cw_sidetone_mute(int mute){ ++ key = mute; ++} ++ ++<<<<<<< HEAD ++int asteps = 0; ++double timebase = 0.0; ++#define TIMESTEP (1.0 / 48000) ++#ifndef M_PI ++#define M_PI 3.14159265358979323846 ++#endif ++double getNextSideToneSample() { ++ double angle = cw_keyer_sidetone_frequency * 2 * M_PI * timebase; ++ timebase += TIMESTEP; ++ asteps++; ++ if (asteps == 48000) { ++ timebase = 0.0; ++ asteps = 0; ++ } ++ return sin(angle); ++} ++======= ++#ifdef PURESIGNAL ++void tx_set_ps(TRANSMITTER *tx,int state) { ++ tx->puresignal=state; ++ if(state) { ++ SetPSControl(tx->id, 0, 0, 1, 0); ++ } else { ++ SetPSControl(tx->id, 1, 0, 0, 0); ++ } ++ vfo_update(); ++} ++ ++void tx_set_twotone(TRANSMITTER *tx,int state) { ++ transmitter->twotone=state; ++ if(state) { ++ SetTXAPostGenMode(transmitter->id, 1); ++ SetTXAPostGenRun(transmitter->id, 1); ++ } else { ++ SetTXAPostGenRun(transmitter->id, 0); ++ } ++ g_idle_add(ext_mox_update,(gpointer)(long)state); ++} ++ ++void tx_set_ps_sample_rate(TRANSMITTER *tx,int rate) { ++ SetPSFeedbackRate (tx->id,rate); ++} ++#endif ++>>>>>>> upstream/master diff --cc transmitter.h.orig index 0000000,0000000..fa7ee57 new file mode 100644 --- /dev/null +++ b/transmitter.h.orig @@@ -1,0 -1,0 +1,154 @@@ ++/* Copyright (C) ++* 2017 - 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. ++* ++*/ ++ ++#ifndef _TRANSMITTER_H ++#define _TRANSMITTER_H ++ ++#include ++ ++#define AUDIO_BUFFER_SIZE 260 ++ ++typedef struct _transmitter { ++ int id; ++ int fps; ++ int displaying; ++ int mic_sample_rate; ++ int mic_dsp_rate; ++ int iq_output_rate; ++ int buffer_size; ++ int fft_size; ++ int pixels; ++ int samples; ++ int output_samples; ++ double *mic_input_buffer; ++ double *iq_output_buffer; ++ ++ float *pixel_samples; ++ int display_panadapter; ++ int display_waterfall; ++ gint update_timer_id; ++ ++ int mode; ++ int filter_low; ++ int filter_high; ++ ++/* ++ long long frequency; ++ long long display_frequency; ++ long long dds_frequency; ++ long long dds_offset; ++*/ ++ int alex_antenna; ++ ++ int width; ++ int height; ++ ++ GtkWidget *panel; ++ GtkWidget *panadapter; ++ ++ int panadapter_low; ++ int panadapter_high; ++ ++ cairo_surface_t *panadapter_surface; ++ ++ int local_microphone; ++ int input_device; ++ ++ int out_of_band; ++ gint out_of_band_timer_id; ++ ++ int low_latency; ++ ++#ifdef PURESIGNAL ++ int puresignal; ++ int twotone; ++ int feedback; ++ int auto_on; ++ int single_on; ++#endif ++ ++ double ctcss_frequency; ++ int ctcss; ++ ++ int deviation; ++ ++ double am_carrier_level; ++ ++ int attenuation; ++ ++ int drive; ++ int tune_use_drive; ++ int tune_percent; ++ ++ int drive_level; ++ ++#ifdef FREEDV ++ char freedv_text_data[64]; ++ int freedv_text_index; ++ int freedv_samples; ++#endif ++ ++ int compressor; ++ double compressor_level; ++ ++ double fwd; ++ double exciter; ++ double rev; ++ double alc; ++ ++ int x; ++ int y; ++ ++} TRANSMITTER; ++ ++extern TRANSMITTER *create_transmitter(int id, int buffer_size, int fft_size, int fps, int width, int height); ++ ++void reconfigure_transmitter(TRANSMITTER *tx,int height); ++ ++ ++extern void tx_set_mode(TRANSMITTER* tx,int m); ++extern void tx_set_filter(TRANSMITTER *tx,int low,int high); ++extern void transmitter_set_deviation(TRANSMITTER *tx); ++extern void transmitter_set_am_carrier_level(TRANSMITTER *tx); ++extern void tx_set_pre_emphasize(TRANSMITTER *tx,int state); ++extern void transmitter_set_ctcss(TRANSMITTER *tx,int run,double frequency); ++ ++extern void add_mic_sample(TRANSMITTER *tx,short mic_sample); ++extern void add_freedv_mic_sample(TRANSMITTER *tx,short mic_sample); ++ ++extern void transmitter_save_state(TRANSMITTER *tx); ++extern void transmitter_set_out_of_band(TRANSMITTER *tx); ++extern void tx_set_displaying(TRANSMITTER *tx,int state); ++ ++extern void tx_set_ps(TRANSMITTER *tx,int state); ++extern void tx_set_twotone(TRANSMITTER *tx,int state); ++ ++extern void transmitter_set_compressor_level(TRANSMITTER *tx,double level); ++extern void transmitter_set_compressor(TRANSMITTER *tx,int state); ++ ++extern void tx_set_ps_sample_rate(TRANSMITTER *tx,int rate); ++extern void add_ps_iq_samples(TRANSMITTER *tx, double i_sample_0,double q_sample_0, double i_sample_1, double q_sample_1); ++<<<<<<< HEAD ++ ++extern void cw_sidetone_mute(int mute); ++======= ++>>>>>>> upstream/master ++#endif ++ ++