+# get the OS Name
+UNAME_S := $(shell uname -s)
+
# Get git commit version and date
GIT_DATE := $(firstword $(shell git --no-pager show --date=short --format="%ai" --name-only))
GIT_VERSION := $(shell git describe --abbrev=0 --tags)
-# uncomment the line below to include GPIO (For original piHPSDR Controller and Controller2 with i2c)
-GPIO_INCLUDE=GPIO
+# uncomment the following line to force 480x320 screen
+#SMALL_SCREEN_OPTIONS=-D SMALL_SCREEN
-# uncomment the line below to include USB Ozy support
-# USBOZY_INCLUDE=USBOZY
+# uncomment the line below to include GPIO
+# For support of:
+# CONTROLLER1 (Original Controller)
+# CONTROLLER2_V1 single encoders with MCP23017 switches
+# CONTROLLER2_V2 dual encoders with MCP23017 switches
+#
+#GPIO_INCLUDE=GPIO
# uncomment the line below to include Pure Signal support
PURESIGNAL_INCLUDE=PURESIGNAL
+# uncomment the line below to include MIDI support
+MIDI_INCLUDE=MIDI
+
+# uncomment the line below to include USB Ozy support
+# USBOZY_INCLUDE=USBOZY
+
# uncomment the line to below include support local CW keyer
-#LOCALCW_INCLUDE=LOCALCW
+LOCALCW_INCLUDE=LOCALCW
# uncomment the line below for SoapySDR
-#SOAPYSDR_INCLUDE=SOAPYSDR
+SOAPYSDR_INCLUDE=SOAPYSDR
# uncomment the line to below include support for sx1509 i2c expander
#SX1509_INCLUDE=sx1509
#STEMLAB_DISCOVERY=STEMLAB_DISCOVERY
# uncomment the line below to include support for STEMlab discovery (WITHOUT AVAHI)
-#STEMLAB_DISCOVERY=STEMLAB_DISCOVERY_NOAVAHI
+STEMLAB_DISCOVERY=STEMLAB_DISCOVERY_NOAVAHI
-# uncomment the line below to include MIDI support
-#MIDI_INCLUDE=MIDI
# uncomment the line below for various debug facilities
#DEBUG_OPTION=-D DEBUG
# very early code not included yet
#SERVER_INCLUDE=SERVER
-CC=gcc
-LINK=gcc
+CFLAGS?= -O -Wno-deprecated-declarations
+PKG_CONFIG = pkg-config
ifeq ($(MIDI_INCLUDE),MIDI)
MIDI_OPTIONS=-D MIDI
-MIDI_SOURCES= alsa_midi.c midi2.c midi3.c
-MIDI_HEADERS= midi.h
-MIDI_OBJS= alsa_midi.o midi2.o midi3.o
+MIDI_HEADERS= midi.h midi_menu.h alsa_midi.h
+ifeq ($(UNAME_S), Darwin)
+MIDI_SOURCES= mac_midi.c midi2.c midi3.c midi_menu.c
+MIDI_OBJS= mac_midi.o midi2.o midi3.o midi_menu.o
+MIDI_LIBS= -framework CoreMIDI -framework Foundation
+endif
+ifeq ($(UNAME_S), Linux)
+MIDI_SOURCES= alsa_midi.c midi2.c midi3.c midi_menu.c
+MIDI_OBJS= alsa_midi.o midi2.o midi3.o midi_menu.o
MIDI_LIBS= -lasound
endif
+endif
ifeq ($(PURESIGNAL_INCLUDE),PURESIGNAL)
PURESIGNAL_OPTIONS=-D PURESIGNAL
ozyio.o
endif
-
ifeq ($(SOAPYSDR_INCLUDE),SOAPYSDR)
SOAPYSDR_OPTIONS=-D SOAPYSDR
SOAPYSDRLIBS=-lSoapySDR
soapy_protocol.o
endif
-
-ifeq ($(LOCALCW_INCLUDE),LOCALCW)
-LOCALCW_OPTIONS=-D LOCALCW
-LOCALCW_SOURCES= iambic.c
-LOCALCW_HEADERS= iambic.h
-LOCALCW_OBJS = iambic.o
-endif
-
ifeq ($(PTT_INCLUDE),PTT)
PTT_OPTIONS=-D PTT
endif
ifeq ($(GPIO_INCLUDE),GPIO)
- GPIO_OPTIONS=-D GPIO
- GPIO_LIBS=-lwiringPi
- GPIO_SOURCES= \
+GPIOD_VERSION=$(shell pkg-config --modversion libgpiod)
+ifeq ($(GPIOD_VERSION),1.2)
+GPIOD_OPTIONS=-D OLD_GPIOD
+endif
+GPIO_OPTIONS=-D GPIO
+GPIO_LIBS=-lgpiod -li2c
+GPIO_SOURCES= \
configure.c \
i2c.c \
gpio.c \
encoder_menu.c \
switch_menu.c
- GPIO_HEADERS= \
+GPIO_HEADERS= \
configure.h \
i2c.h \
gpio.h \
encoder_menu.h \
switch_menu.h
- GPIO_OBJS= \
+GPIO_OBJS= \
configure.o \
i2c.o \
gpio.o \
switch_menu.o
endif
+ifeq ($(LOCALCW_INCLUDE),LOCALCW)
+LOCALCW_OPTIONS=-D LOCALCW
+LOCALCW_SOURCES= iambic.c
+LOCALCW_HEADERS= iambic.h
+LOCALCW_OBJS = iambic.o
+endif
+
#
# We have two versions of STEMLAB_DISCOVERY here,
# the second one has to be used
#
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`
+ $(shell $(PKG_CONFIG) --cflags avahi-gobject) \
+ $(shell $(PKG_CONFIG) --cflags libcurl)
+STEMLAB_LIBS=$(shell $(PKG_CONFIG) --libs avahi-gobject --libs libcurl)
STEMLAB_SOURCES=stemlab_discovery.c
STEMLAB_HEADERS=stemlab_discovery.h
STEMLAB_OBJS=stemlab_discovery.o
endif
ifeq ($(STEMLAB_DISCOVERY), STEMLAB_DISCOVERY_NOAVAHI)
-STEMLAB_OPTIONS=-D STEMLAB_DISCOVERY -D NO_AVAHI `pkg-config --cflags libcurl`
-STEMLAB_LIBS=`pkg-config --libs libcurl`
+STEMLAB_OPTIONS=-D STEMLAB_DISCOVERY -D NO_AVAHI $(shell $(PKG_CONFIG) --cflags libcurl)
+STEMLAB_LIBS=$(shell $(PKG_CONFIG) --libs libcurl)
STEMLAB_SOURCES=stemlab_discovery.c
STEMLAB_HEADERS=stemlab_discovery.h
STEMLAB_OBJS=stemlab_discovery.o
client_server.o server_menu.o
endif
-GTKINCLUDES=`pkg-config --cflags gtk+-3.0`
-GTKLIBS=`pkg-config --libs gtk+-3.0`
+GTKINCLUDES=$(shell $(PKG_CONFIG) --cflags gtk+-3.0)
+GTKLIBS=$(shell $(PKG_CONFIG) --libs gtk+-3.0)
-AUDIO_LIBS=-lasound
-#AUDIO_LIBS=-lsoundio
+ifeq ($(UNAME_S), Linux)
+#AUDIO_LIBS=-lpulse-simple -lpulse -lpulse-mainloop-glib
+#AUDIO_SOURCES=pulseaudio.c
+#AUDIO_OBJS=pulseaudio.o
+AUDIO_LIBS=
+AUDIO_SOURCES=audio.c
+AUDIO_OBJS=audio.o
+endif
+ifeq ($(UNAME_S), Darwin)
+AUDIO_OPTIONS=-DPORTAUDIO $(shell $(PKG_CONFIG) --cflags portaudio-2.0)
+AUDIO_LIBS=$(shell $(PKG_CONFIG) --libs portaudio-2.0)
+AUDIO_SOURCES=portaudio.c
+AUDIO_OBJS=portaudio.o
+endif
-CFLAGS= -g -Wno-deprecated-declarations -O3
-OPTIONS=$(MIDI_OPTIONS) $(PURESIGNAL_OPTIONS) $(REMOTE_OPTIONS) $(USBOZY_OPTIONS) \
- $(GPIO_OPTIONS) $(SOAPYSDR_OPTIONS) $(LOCALCW_OPTIONS) \
- $(STEMLAB_OPTIONS) \
- $(PTT_OPTIONS) \
- $(SERVER_OPTIONS) \
+ifeq ($(UNAME_S), Linux)
+SYSLIBS=-lrt
+endif
+ifeq ($(UNAME_S), Darwin)
+SYSLIBS=-framework IOkit
+endif
+
+OPTIONS=$(SMALL_SCREEN_OPTIONS) $(MIDI_OPTIONS) $(PURESIGNAL_OPTIONS) $(REMOTE_OPTIONS) $(USBOZY_OPTIONS) \
+ $(GPIO_OPTIONS) $(GPIOD_OPTIONS) $(SOAPYSDR_OPTIONS) $(LOCALCW_OPTIONS) \
+ $(STEMLAB_OPTIONS) $(PTT_OPTIONES) $(SERVER_OPTIONS) $(AUDIO_OPTIONS) \
-D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(DEBUG_OPTION)
-LIBS=-lrt -lm -lwdsp -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(STEMLAB_LIBS) $(MIDI_LIBS)
+LIBS= -lm -lwdsp -lpthread $(SYSLIBS) $(AUDIO_LIBS) $(USBOZY_LIBS) $(GTKLIBS) \
+ $(GPIO_LIBS) $(SOAPYSDRLIBS) $(STEMLAB_LIBS) $(MIDI_LIBS)
INCLUDES=$(GTKINCLUDES)
COMPILE=$(CC) $(CFLAGS) $(OPTIONS) $(INCLUDES)
PROGRAM=pihpsdr
SOURCES= \
-audio.c \
+MacOS.c \
band.c \
discovered.c \
discovery.c \
ext.c \
error_handler.c \
cwramp.c \
-protocols.c
+protocols.c \
+css.c \
+actions.c \
+i2c.c \
+gpio.c \
+encoder_menu.c \
+switch_menu.c
HEADERS= \
-audio.h \
+MacOS.h \
agc.h \
alex.h \
band.h \
led.h \
ext.h \
error_handler.h \
-protocols.h
+protocols.h \
+css.h \
+actions.h \
+configure.h \
+i2c.h \
+gpio.h \
+encoder_menu.h \
+switch_menu.h
OBJS= \
-audio.o \
+MacOS.o \
band.o \
discovered.o \
discovery.o \
ext.o \
error_handler.o \
cwramp.o \
-protocols.o
-
-$(PROGRAM): $(OBJS) $(REMOTE_OBJS) $(USBOZY_OBJS) $(SOAPYSDR_OBJS) \
- $(LOCALCW_OBJS) $(GPIO_OBJS) $(PURESIGNAL_OBJS) \
+protocols.o \
+css.o \
+actions.o \
+configure.o \
+i2c.o \
+gpio.o \
+encoder_menu.o \
+switch_menu.o
+
+$(PROGRAM): $(OBJS) $(AUDIO_OBJS) $(REMOTE_OBJS) $(USBOZY_OBJS) $(SOAPYSDR_OBJS) \
+ $(LOCALCW_OBJS) $(PURESIGNAL_OBJS) \
$(MIDI_OBJS) $(STEMLAB_OBJS) $(SERVER_OBJS)
- $(LINK) -o $(PROGRAM) $(OBJS) $(REMOTE_OBJS) $(USBOZY_OBJS) $(GPIO_OBJS) \
+ $(CC) -o $(PROGRAM) $(OBJS) $(AUDIO_OBJS) $(REMOTE_OBJS) $(USBOZY_OBJS) \
$(SOAPYSDR_OBJS) $(LOCALCW_OBJS) $(PURESIGNAL_OBJS) \
- $(MIDI_OBJS) $(STEMLAB_OBJS) $(SERVER_OBJS) $(LIBS)
-
-.PHONY: all
-all: prebuild $(PROGRAM) $(HEADERS) $(USBOZY_HEADERS) $(SOAPYSDR_HEADERS) \
- $(LOCALCW_HEADERS) $(GPIO_HEADERS) \
- $(PURESIGNAL_HEADERS) $(MIDI_HEADERS) $(STEMLAB_HEADERS) $(SERVER_HEADERS)\
- $(SOURCES) \
- $(USBOZY_SOURCES) $(SOAPYSDR_SOURCES) $(LOCALCW_SOURCE) $(GPIO_SOURCES) \
+ $(MIDI_OBJS) $(STEMLAB_OBJS) $(SERVER_OBJS) $(LIBS) $(LDFLAGS)
+
+.PHONY: all
+all: prebuild $(PROGRAM) $(HEADERS) $(AUDIO_HEADERS) $(USBOZY_HEADERS) $(SOAPYSDR_HEADERS) \
+ $(LOCALCW_HEADERS) \
+ $(PURESIGNAL_HEADERS) $(MIDI_HEADERS) $(STEMLAB_HEADERS) $(SERVER_HEADERS) \
+ $(AUDIO_SOURCES) $(SOURCES) \
+ $(USBOZY_SOURCES) $(SOAPYSDR_SOURCES) $(LOCALCW_SOURCE) \
$(PURESIGNAL_SOURCES) $(MIDI_SOURCES) $(STEMLAB_SOURCES) $(SERVER_SOURCES)
-.PHONY: prebuild
+.PHONY: prebuild
prebuild:
rm -f version.o
# Therefore, correct this here. Furthermore, we can add additional options to CPP
# in the variable CPPOPTIONS
#
-CPPOPTIONS= --enable=all --suppress=shadowVariable --suppress=variableScope
+CPPOPTIONS= --enable=all --suppress=shadowVariable --suppress=variableScope -D__APPLE__
CPPINCLUDES:=$(shell echo $(INCLUDES) | sed -e "s/-pthread / /" )
.PHONY: cppcheck
cppcheck:
cppcheck $(CPPOPTIONS) $(OPTIONS) $(CPPINCLUDES) $(SOURCES) $(REMOTE_SOURCES) \
- $(USBOZY_SOURCES) $(SOAPYSDR_SOURCES) $(GPIO_SOURCES) \
- $(PURESIGNAL_SOURCES) $(MIDI_SOURCES) $(STEMLAB_SOURCES) $(LOCALCW_SOURCES) \
- $(SERVER_SOURCES)
+ $(USBOZY_SOURCES) $(SOAPYSDR_SOURCES) $(SERVER_SOURCES) \
+ $(PURESIGNAL_SOURCES) $(MIDI_SOURCES) $(STEMLAB_SOURCES) $(LOCALCW_SOURCES)
-.PHONY: clean
+.PHONY: clean
clean:
-rm -f *.o
-rm -f $(PROGRAM) hpsdrsim
+ -rm -rf $(PROGRAM).app
-.PHONY: install
+.PHONY: install
install: $(PROGRAM)
- cp $(PROGRAM) /usr/local/bin
+ cp $(PROGRAM) $(DESTDIR)/usr/local/bin
-.PHONY: release
+.PHONY: release
release: $(PROGRAM)
cp $(PROGRAM) release/pihpsdr
cd release; tar cvf pihpsdr.tar pihpsdr
cd release; tar cvf pihpsdr-$(GIT_VERSION).tar pihpsdr
-.PHONY: nocontroller
+.PHONY: nocontroller
nocontroller: clean controller1 $(PROGRAM)
cp $(PROGRAM) release/pihpsdr
cd release; tar cvf pihpsdr-nocontroller.$(GIT_VERSION).tar pihpsdr
-.PHONY: controller1
+.PHONY: controller1
controller1: clean $(PROGRAM)
cp $(PROGRAM) release/pihpsdr
cd release; tar cvf pihpsdr-controller1.$(GIT_VERSION).tar pihpsdr
-.PHONY: controller2v1
+.PHONY: controller2v1
controller2v1: clean $(PROGRAM)
cp $(PROGRAM) release/pihpsdr
cd release; tar cvf pihpsdr-controller2-v1.$(GIT_VERSION).tar pihpsdr
-.PHONY: controller2v2
+.PHONY: controller2v2
controller2v2: clean $(PROGRAM)
cp $(PROGRAM) release/pihpsdr
cd release; tar cvf pihpsdr-controller2-v2.$(GIT_VERSION).tar pihpsdr
#
#############################################################################
-hpsdrsim.o: hpsdrsim.c hpsdrsim.h
- $(CC) -c -O -DALSASOUND hpsdrsim.c
-
+hpsdrsim.o: hpsdrsim.c hpsdrsim.h
+ $(CC) -c -O $(AUDIO_OPTIONS) hpsdrsim.c
+
newhpsdrsim.o: newhpsdrsim.c hpsdrsim.h
$(CC) -c -O newhpsdrsim.c
-hpsdrsim: hpsdrsim.o newhpsdrsim.o
- $(LINK) -o hpsdrsim hpsdrsim.o newhpsdrsim.o -lasound -lm -lpthread
-
+hpsdrsim: hpsdrsim.o newhpsdrsim.o
+ $(CC) -o hpsdrsim $(AUDIO_LIBS) hpsdrsim.o newhpsdrsim.o -lportaudio -lm -lpthread
debian:
cp $(PROGRAM) pkg/pihpsdr/usr/local/bin
cp release/pihpsdr/pihpsdr.desktop pkg/pihpsdr/usr/share/applications
cd pkg; dpkg-deb --build pihpsdr
+#############################################################################
+#
+# This is for MacOS "app" creation ONLY
+#
+# The piHPSDR working directory is
+# $HOME -> Application Support -> piHPSDR
+#
+# That is the directory where the WDSP wisdom file (created upon first
+# start of piHPSDR) but also the radio settings and the midi.props file
+# are stored.
+#
+# ONLY the wdsp library is bundled with the app, all others, including
+# the SoapySDR support modules, must be installed separatedly.
+#
+#############################################################################
+
+.PHONY: app
+app: $(OBJS) $(REMOTE_OBJS) \
+ $(USBOZY_OBJS) $(SOAPYSDR_OBJS) \
+ $(LOCALCW_OBJS) $(PURESIGNAL_OBJS) \
+ $(MIDI_OBJS) $(STEMLAB_OBJS) $(SERVER_OBJS)
+ $(CC) -headerpad_max_install_names -o $(PROGRAM) $(OBJS) $(REMOTE_OBJS) \
+ $(USBOZY_OBJS) $(SOAPYSDR_OBJS) \
+ $(LOCALCW_OBJS) $(PURESIGNAL_OBJS) \
+ $(MIDI_OBJS) $(STEMLAB_OBJS) $(SERVER_OBJS) $(LIBS) $(LDFLAGS)
+ @rm -rf pihpsdr.app
+ @mkdir -p pihpsdr.app/Contents/MacOS
+ @mkdir -p pihpsdr.app/Contents/Frameworks
+ @mkdir -p pihpsdr.app/Contents/Resources
+ @cp pihpsdr pihpsdr.app/Contents/MacOS/pihpsdr
+ @cp MacOS/PkgInfo pihpsdr.app/Contents
+ @cp MacOS/Info.plist pihpsdr.app/Contents
+ @cp MacOS/hpsdr.icns pihpsdr.app/Contents/Resources/hpsdr.icns
+ @cp MacOS/hpsdr.png pihpsdr.app/Contents/Resources
+#
+# Copy the WDSP library into the executable
+#
+ @lib=`otool -L pihpsdr.app/Contents/MacOS/pihpsdr | grep libwdsp | sed -e "s/ (.*//" | sed -e 's/ //'`; \
+ libfn=`basename $$lib`; \
+ cp "$$lib" "pihpsdr.app/Contents/Frameworks/$$libfn"; \
+ chmod u+w "pihpsdr.app/Contents/Frameworks/$$libfn"; \
+ install_name_tool -id "@executable_path/../Frameworks/$$libfn" "pihpsdr.app/Contents/Frameworks/$$libfn"; \
+ install_name_tool -change "$$lib" "@executable_path/../Frameworks/$$libfn" pihpsdr.app/Contents/MacOS/pihpsdr
+#
+#############################################################################
--- /dev/null
+#include <gtk/gtk.h>
+
+#include "main.h"
+#include "discovery.h"
+#include "receiver.h"
+#include "sliders.h"
+#include "band_menu.h"
+#include "diversity_menu.h"
+#include "vfo.h"
+#include "radio.h"
+#include "radio_menu.h"
+#include "new_menu.h"
+#include "new_protocol.h"
+#ifdef PURESIGNAL
+#include "ps_menu.h"
+#endif
+#include "agc.h"
+#include "filter.h"
+#include "mode.h"
+#include "band.h"
+#include "bandstack.h"
+#include "noise_menu.h"
+#include "wdsp.h"
+#ifdef CLIENT_SERVER
+#include "client_server.h"
+#endif
+#include "ext.h"
+#include "zoompan.h"
+#include "actions.h"
+#include "gpio.h"
+#include "toolbar.h"
+
+char *encoder_string[ENCODER_ACTIONS] = {
+ "NO ACTION",
+ "AF GAIN",
+ "AF GAIN RX1",
+ "AF GAIN RX2",
+ "AGC GAIN",
+ "AGC GAIN RX1",
+ "AGC GAIN RX2",
+ "ATTENUATION",
+ "COMP",
+ "CW FREQUENCY",
+ "CW SPEED",
+ "DIVERSITY GAIN",
+ "DIVERSITY GAIN (coarse)",
+ "DIVERSITY GAIN (fine)",
+ "DIVERSITY PHASE",
+ "DIVERSITY PHASE (coarse)",
+ "DIVERSITY PHASE (fine)",
+ "DRIVE",
+ "IF SHIFT",
+ "IF SHIFT RX1",
+ "IF SHIFT RX2",
+ "IF WIDTH",
+ "IF WIDTH RX1",
+ "IF WIDTH RX2",
+ "MIC GAIN",
+ "PAN",
+ "PANADAPTER HIGH",
+ "PANADAPTER LOW",
+ "PANADAPTER STEP",
+ "RF GAIN",
+ "RF GAIN RX1",
+ "RF GAIN RX2",
+ "RIT",
+ "RIT RX1",
+ "RIT RX2",
+ "SQUELCH",
+ "SQUELCH RX1",
+ "SQUELCH RX2",
+ "TUNE DRIVE",
+ "VFO",
+ "WATERFALL HIGH",
+ "WATERFALL LOW",
+ "XIT",
+ "ZOOM"
+};
+
+char *sw_string[SWITCH_ACTIONS] = {
+ "",
+ "A TO B",
+ "A SWAP B",
+ "AGC +",
+ "ANF",
+ "B TO A",
+ "BAND -",
+ "BAND +",
+ "BSTACK -",
+ "BSTACK +",
+ "CTUN",
+ "DIV",
+ "DUPLEX",
+ "FILTER -",
+ "FILTER +",
+ "FUNCT",
+ "LOCK",
+ "AGC",
+ "BAND",
+ "BSTACK",
+ "DIV",
+ "FILTER",
+ "FREQUENCY",
+ "MEMORY",
+ "MODE",
+ "NOISE",
+ "PS",
+ "MODE -",
+ "MODE +",
+ "MOX",
+ "MUTE",
+ "NB",
+ "NR",
+ "PAN -",
+ "PAN +",
+ "PS",
+ "RIT",
+ "RIT CL",
+ "RIT -",
+ "RIT +",
+ "RSAT",
+ "SAT",
+ "SNB",
+ "SPLIT",
+ "TUN",
+ "TUNE FULL",
+ "TUNE MEM",
+ "TWO TONE",
+ "VFOSTEP +",
+ "VFOSTEP -",
+ "XIT",
+ "XIT CL",
+ "XIT -",
+ "XIT +",
+ "ZOOM -",
+ "ZOOM +"
+};
+
+char *sw_cap_string[SWITCH_ACTIONS] = {
+ "",
+ "A>B",
+ "A<>B",
+ "AGC",
+ "ANF",
+ "B>A",
+ "BAND -",
+ "BAND +",
+ "BST-",
+ "BST+",
+ "CTUN",
+ "DIV",
+ "DUP",
+ "FILT -",
+ "FILT +",
+ "FUNC",
+ "LOCK",
+ "AGC",
+ "BAND",
+ "BSTACK",
+ "DIV",
+ "FILTER",
+ "FREQ",
+ "MEM",
+ "MODE",
+ "NOISE",
+ "PS",
+ "MODE -",
+ "MODE +",
+ "MOX",
+ "MUTE",
+ "NB",
+ "NR",
+ "PAN-",
+ "PAN+",
+ "PS",
+ "RIT",
+ "RIT CL",
+ "RIT -",
+ "RIT +",
+ "RSAT",
+ "SAT",
+ "SNB",
+ "SPLIT",
+ "TUNE",
+ "TUN-F",
+ "TUN-M",
+ "2TONE",
+ "STEP+",
+ "STEP-",
+ "XIT",
+ "XIT CL",
+ "XIT -",
+ "XIT +",
+ "ZOOM-",
+ "ZOOM+",
+};
+
+
+int encoder_action(void *data) {
+ ENCODER_ACTION *a=(ENCODER_ACTION *)data;
+ double value;
+ int mode;
+ int id;
+ FILTER * band_filters=filters[vfo[active_receiver->id].mode];
+ FILTER *band_filter;
+ FILTER *filter;
+ int new_val;
+
+ switch(a->action) {
+ case ENCODER_VFO:
+ vfo_step(a->val);
+ break;
+ case ENCODER_AF_GAIN:
+ value=active_receiver->volume;
+ value+=a->val/100.0;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>1.0) {
+ value=1.0;
+ }
+ set_af_gain(active_receiver->id,value);
+ break;
+ case ENCODER_AF_GAIN_RX1:
+ value=receiver[0]->volume;
+ value+=a->val/100.0;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>1.0) {
+ value=1.0;
+ }
+ set_af_gain(0,value);
+ break;
+ case ENCODER_AF_GAIN_RX2:
+ value=receiver[1]->volume;
+ value+=a->val/100.0;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>1.0) {
+ value=1.0;
+ }
+ set_af_gain(1,value);
+ break;
+ case ENCODER_RF_GAIN:
+ //value=active_receiver->gain;
+ value=adc[active_receiver->id].gain;
+ value+=a->val;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>100.0) {
+ value=100.0;
+ }
+ set_rf_gain(active_receiver->id,value);
+ break;
+ case ENCODER_RF_GAIN_RX1:
+ //value=receiver[0]->rf_gain;
+ value=adc[receiver[0]->id].gain;
+ value+=a->val;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>100.0) {
+ value=100.0;
+ }
+ set_rf_gain(0,value);
+ break;
+ case ENCODER_RF_GAIN_RX2:
+ //value=receiver[1]->rf_gain;
+ value=adc[receiver[1]->id].gain;
+ value+=a->val;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>71.0) {
+ value=71.0;
+ }
+ set_rf_gain(1,value);
+ break;
+ case ENCODER_AGC_GAIN:
+ value=active_receiver->agc_gain;
+ value+=a->val;
+ if(value<-20.0) {
+ value=-20.0;
+ } else if(value>120.0) {
+ value=120.0;
+ }
+ set_agc_gain(active_receiver->id,value);
+ break;
+ case ENCODER_AGC_GAIN_RX1:
+ value=receiver[0]->agc_gain;
+ value+=a->val;
+ if(value<-20.0) {
+ value=-20.0;
+ } else if(value>120.0) {
+ value=120.0;
+ }
+ set_agc_gain(0,value);
+ break;
+ case ENCODER_AGC_GAIN_RX2:
+ value=receiver[1]->agc_gain;
+ value+=a->val;
+ if(value<-20.0) {
+ value=-20.0;
+ } else if(value>120.0) {
+ value=120.0;
+ }
+ set_agc_gain(1,value);
+ break;
+ case ENCODER_IF_WIDTH:
+ filter_width_changed(active_receiver->id,a->val);
+ break;
+ case ENCODER_IF_WIDTH_RX1:
+ filter_width_changed(0,a->val);
+ break;
+ case ENCODER_IF_WIDTH_RX2:
+ filter_width_changed(1,a->val);
+ break;
+ case ENCODER_IF_SHIFT:
+ filter_shift_changed(active_receiver->id,a->val);
+ break;
+ case ENCODER_IF_SHIFT_RX1:
+ filter_shift_changed(0,a->val);
+ break;
+ case ENCODER_IF_SHIFT_RX2:
+ filter_shift_changed(1,a->val);
+ break;
+ case ENCODER_ATTENUATION:
+ value=(double)adc[active_receiver->adc].attenuation;
+ value+=(double)a->val;
+ if(have_rx_gain) {
+ if(value<-12.0) {
+ value=-12.0;
+ } else if(value>48.0) {
+ value=48.0;
+ }
+ } else {
+ 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;
+ value+=(double)a->val;
+ if(value<-12.0) {
+ value=-12.0;
+ } else if(value>50.0) {
+ value=50.0;
+ }
+ set_mic_gain(value);
+ break;
+ case ENCODER_DRIVE:
+ value=getDrive();
+ value+=(double)a->val;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>drive_max) {
+ value=drive_max;
+ }
+ set_drive(value);
+ break;
+ case ENCODER_RIT:
+ vfo_rit(active_receiver->id,a->val);
+ break;
+ case ENCODER_RIT_RX1:
+ vfo_rit(receiver[0]->id,a->val);
+ break;
+ case ENCODER_RIT_RX2:
+ vfo_rit(receiver[1]->id,a->val);
+ break;
+ case ENCODER_XIT:
+ value=(double)transmitter->xit;
+ value+=(double)(a->val*rit_increment);
+ if(value<-10000.0) {
+ value=-10000.0;
+ } else if(value>10000.0) {
+ value=10000.0;
+ }
+ transmitter->xit=(int)value;
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
+ g_idle_add(ext_vfo_update,NULL);
+ break;
+ case ENCODER_CW_SPEED:
+ value=(double)cw_keyer_speed;
+ value+=(double)a->val;
+ if(value<1.0) {
+ value=1.0;
+ } else if(value>60.0) {
+ value=60.0;
+ }
+ cw_keyer_speed=(int)value;
+ g_idle_add(ext_vfo_update,NULL);
+ break;
+ case ENCODER_CW_FREQUENCY:
+ value=(double)cw_keyer_sidetone_frequency;
+ value+=(double)a->val;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>1000.0) {
+ value=1000.0;
+ }
+ cw_keyer_sidetone_frequency=(int)value;
+ g_idle_add(ext_vfo_update,NULL);
+ break;
+ case ENCODER_PANADAPTER_HIGH:
+ value=(double)active_receiver->panadapter_high;
+ value+=(double)a->val;
+ active_receiver->panadapter_high=(int)value;
+ break;
+ case ENCODER_PANADAPTER_LOW:
+ value=(double)active_receiver->panadapter_low;
+ value+=(double)a->val;
+ active_receiver->panadapter_low=(int)value;
+ break;
+ case ENCODER_PANADAPTER_STEP:
+ value=(double)active_receiver->panadapter_step;
+ value+=(double)a->val;
+ active_receiver->panadapter_step=(int)value;
+ break;
+ case ENCODER_WATERFALL_HIGH:
+ value=(double)active_receiver->waterfall_high;
+ value+=(double)a->val;
+ active_receiver->waterfall_high=(int)value;
+ break;
+ case ENCODER_WATERFALL_LOW:
+ value=(double)active_receiver->waterfall_low;
+ value+=(double)a->val;
+ active_receiver->waterfall_low=(int)value;
+ break;
+ case ENCODER_SQUELCH:
+ value=active_receiver->squelch;
+ value+=(double)a->val;
+ 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_SQUELCH_RX1:
+ value=receiver[0]->squelch;
+ value+=(double)a->val;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>100.0) {
+ value=100.0;
+ }
+ receiver[0]->squelch=value;
+ set_squelch(receiver[0]);
+ break;
+ case ENCODER_SQUELCH_RX2:
+ value=receiver[1]->squelch;
+ value+=(double)a->val;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>100.0) {
+ value=100.0;
+ }
+ receiver[1]->squelch=value;
+ set_squelch(receiver[1]);
+ break;
+ case ENCODER_COMP:
+ value=(double)transmitter->compressor_level;
+ value+=(double)a->val;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>20.0) {
+ value=20.0;
+ }
+ transmitter->compressor_level=(int)value;
+ set_compression(transmitter);
+ break;
+ case ENCODER_DIVERSITY_GAIN:
+ update_diversity_gain((double)a->val * 0.5);
+ break;
+ case ENCODER_DIVERSITY_GAIN_COARSE:
+ update_diversity_gain((double)a->val * 2.5);
+ break;
+ case ENCODER_DIVERSITY_GAIN_FINE:
+ update_diversity_gain((double)a->val * 0.1);
+ break;
+ case ENCODER_DIVERSITY_PHASE:
+ update_diversity_phase((double)a->val* 0.5);
+ break;
+ case ENCODER_DIVERSITY_PHASE_COARSE:
+ update_diversity_phase((double)a->val*2.5);
+ break;
+ case ENCODER_DIVERSITY_PHASE_FINE:
+ update_diversity_phase((double)a->val*0.1);
+ break;
+ case ENCODER_ZOOM:
+ update_zoom((double)a->val);
+ break;
+ case ENCODER_PAN:
+ update_pan((double)a->val*100);
+ break;
+ }
+ g_free(data);
+ return 0;
+}
+
+int switch_action(void *data) {
+ int i;
+ SWITCH_ACTION *a=(SWITCH_ACTION *)data;
+ if(a->state==PRESSED) {
+ switch(a->action) {
+ case FUNCTION:
+ switch(controller) {
+ case NO_CONTROLLER:
+ case CONTROLLER1:
+ function++;
+ if(function>=MAX_FUNCTIONS) {
+ function=0;
+ }
+ toolbar_switches=switches_controller1[function];
+ switches=switches_controller1[function];
+ update_toolbar_labels();
+ break;
+ case CONTROLLER2_V1:
+ case CONTROLLER2_V2:
+ function++;
+ if(function>=MAX_FUNCTIONS) {
+ function=0;
+ }
+ toolbar_switches=switches_controller1[function];
+ update_toolbar_labels();
+ break;
+ }
+ break;
+ case TUNE:
+ if(getMox()==1) {
+ setMox(0);
+ }
+ if(getTune()==0) {
+ if(canTransmit() || tx_out_of_band) {
+ setTune(1);
+ } else {
+ transmitter_set_out_of_band(transmitter);
+ }
+ } else {
+ setTune(0);
+ }
+ g_idle_add(ext_vfo_update,NULL);
+ break;
+ case MOX:
+ if(getTune()==1) {
+ setTune(0);
+ }
+ if(getMox()==0) {
+ if(canTransmit() || tx_out_of_band) {
+ setMox(1);
+ } else {
+ transmitter_set_out_of_band(transmitter);
+ }
+ } else {
+ setMox(0);
+ }
+ g_idle_add(ext_vfo_update,NULL);
+ break;
+ case PS:
+#ifdef PURESIGNAL
+ if(can_transmit) {
+ if(transmitter->puresignal==0) {
+ tx_set_ps(transmitter,1);
+ } else {
+ tx_set_ps(transmitter,0);
+ }
+ }
+#endif
+ break;
+ case TWO_TONE:
+ if(can_transmit) {
+ int state=transmitter->twotone?0:1;
+ tx_set_twotone(transmitter,state);
+ }
+ break;
+ case VFOSTEP_PLUS:
+ for(i=0;i<STEPS;i++) {
+ if(steps[i]==step) break;
+ }
+ if(i>=STEPS) i=0;
+ i++;
+ if(i>=STEPS) i=0;
+ step=steps[i];
+ g_idle_add(ext_vfo_update, NULL);
+ break;
+ case VFOSTEP_MINUS:
+ for(i=0;i<STEPS;i++) {
+ if(steps[i]==step) break;
+ }
+ if(i>=STEPS) i=0;
+ i--;
+ if(i<0) i=STEPS-1;
+ step=steps[i];
+ g_idle_add(ext_vfo_update, NULL);
+ break;
+ case NR:
+ if(active_receiver->nr==0 && active_receiver->nr2==0) {
+ active_receiver->nr=1;
+ active_receiver->nr2=0;
+ mode_settings[vfo[active_receiver->id].mode].nr=1;
+ mode_settings[vfo[active_receiver->id].mode].nr2=0;
+ } else if(active_receiver->nr==1 && active_receiver->nr2==0) {
+ active_receiver->nr=0;
+ active_receiver->nr2=1;
+ mode_settings[vfo[active_receiver->id].mode].nr=0;
+ mode_settings[vfo[active_receiver->id].mode].nr2=1;
+ } else if(active_receiver->nr==0 && active_receiver->nr2==1) {
+ active_receiver->nr=0;
+ active_receiver->nr2=0;
+ mode_settings[vfo[active_receiver->id].mode].nr=0;
+ mode_settings[vfo[active_receiver->id].mode].nr2=0;
+ }
+ update_noise();
+ break;
+ case NB:
+ if(active_receiver->nb==0 && active_receiver->nb2==0) {
+ active_receiver->nb=1;
+ active_receiver->nb2=0;
+ mode_settings[vfo[active_receiver->id].mode].nb=1;
+ mode_settings[vfo[active_receiver->id].mode].nb2=0;
+ } else if(active_receiver->nb==1 && active_receiver->nb2==0) {
+ active_receiver->nb=0;
+ active_receiver->nb2=1;
+ mode_settings[vfo[active_receiver->id].mode].nb=0;
+ mode_settings[vfo[active_receiver->id].mode].nb2=1;
+ } else if(active_receiver->nb==0 && active_receiver->nb2==1) {
+ active_receiver->nb=0;
+ active_receiver->nb2=0;
+ mode_settings[vfo[active_receiver->id].mode].nb=0;
+ mode_settings[vfo[active_receiver->id].mode].nb2=0;
+ }
+ update_noise();
+ break;
+ case SNB:
+ if(active_receiver->snb==0) {
+ active_receiver->snb=1;
+ mode_settings[vfo[active_receiver->id].mode].snb=1;
+ } else {
+ active_receiver->snb=0;
+ mode_settings[vfo[active_receiver->id].mode].snb=0;
+ }
+ update_noise();
+ break;
+ case RIT:
+ vfo_rit_update(active_receiver->id);
+ break;
+ case RIT_CLEAR:
+ vfo_rit_clear(active_receiver->id);
+ break;
+ case RIT_MINUS:
+ vfo_rit(active_receiver->id,-1);
+ break;
+ case RIT_PLUS:
+ vfo_rit(active_receiver->id,1);
+ break;
+ case XIT:
+ if(can_transmit) {
+ transmitter->xit_enabled=transmitter->xit_enabled==1?0:1;
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
+ }
+ g_idle_add(ext_vfo_update, NULL);
+ break;
+ case XIT_CLEAR:
+ if(can_transmit) {
+ transmitter->xit=0;
+ g_idle_add(ext_vfo_update, NULL);
+ }
+ break;
+ case XIT_MINUS:
+ if(can_transmit) {
+ double value=(double)transmitter->xit;
+ value-=(double)rit_increment;
+ if(value<-10000.0) {
+ value=-10000.0;
+ } else if(value>10000.0) {
+ value=10000.0;
+ }
+ transmitter->xit=(int)value;
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
+ g_idle_add(ext_vfo_update,NULL);
+ }
+ break;
+ case XIT_PLUS:
+ if(can_transmit) {
+ double value=(double)transmitter->xit;
+ value+=(double)rit_increment;
+ if(value<-10000.0) {
+ value=-10000.0;
+ } else if(value>10000.0) {
+ value=10000.0;
+ }
+ transmitter->xit=(int)value;
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
+ g_idle_add(ext_vfo_update,NULL);
+ }
+ break;
+ case BAND_PLUS:
+ {
+ long long frequency_min=radio->frequency_min;
+ long long frequency_max=radio->frequency_max;
+ int b=vfo[active_receiver->id].band;
+ BAND *band;
+ int found=0;
+ while(!found) {
+ b++;
+ if(b>=BANDS+XVTRS) b=0;
+ band=(BAND*)band_get_band(b);
+ if(strlen(band->title)>0) {
+ if(b<BANDS) {
+ if(!(band->frequencyMin==0.0 && band->frequencyMax==0.0)) {
+ if(band->frequencyMin<frequency_min || band->frequencyMax>frequency_max) {
+ continue;
+ }
+ }
+ }
+ vfo_band_changed(active_receiver->id,b);
+ found=1;
+ }
+ }
+ }
+ break;
+ case BAND_MINUS:
+ {
+ long long frequency_min=radio->frequency_min;
+ long long frequency_max=radio->frequency_max;
+ int b=vfo[active_receiver->id].band;
+ BAND *band;
+ int found=0;
+ while(!found) {
+ b--;
+ if(b<0) b=BANDS+XVTRS-1;
+ band=(BAND*)band_get_band(b);
+ if(strlen(band->title)>0) {
+ if(b<BANDS) {
+ if(band->frequencyMin<frequency_min || band->frequencyMax>frequency_max) {
+ continue;
+ }
+ }
+ vfo_band_changed(active_receiver->id,b);
+ found=1;
+ }
+ }
+ }
+ break;
+ case BANDSTACK_PLUS:
+ {
+ BAND *band=band_get_band(vfo[active_receiver->id].band);
+ BANDSTACK *bandstack=band->bandstack;
+ int b=vfo[active_receiver->id].bandstack+1;
+ if(b>=bandstack->entries) b=0;
+ vfo_bandstack_changed(b);
+ }
+ break;
+ case BANDSTACK_MINUS:
+ {
+ BAND *band=band_get_band(vfo[active_receiver->id].band);
+ BANDSTACK *bandstack=band->bandstack;
+ int b=vfo[active_receiver->id].bandstack-1;
+ if(b<0) b=bandstack->entries-1;;
+ vfo_bandstack_changed(b);
+ }
+ break;
+ case MODE_PLUS:
+ {
+ int mode=vfo[active_receiver->id].mode;
+ mode++;
+ if(mode>=MODES) mode=0;
+ vfo_mode_changed(mode);
+ }
+ break;
+ case MODE_MINUS:
+ {
+ int mode=vfo[active_receiver->id].mode;
+ mode--;
+ if(mode<0) mode=MODES-1;
+ vfo_mode_changed(mode);
+ }
+ break;
+ case FILTER_PLUS:
+ {
+ int f=vfo[active_receiver->id].filter-1;
+ if(f<0) f=FILTERS-1;
+ vfo_filter_changed(f);
+ }
+ break;
+ case FILTER_MINUS:
+ {
+ int f=vfo[active_receiver->id].filter+1;
+ if(f>=FILTERS) f=0;
+ vfo_filter_changed(f);
+ }
+ break;
+ case A_TO_B:
+ vfo_a_to_b();
+ break;
+ case B_TO_A:
+ vfo_b_to_a();
+ break;
+ case A_SWAP_B:
+ vfo_a_swap_b();
+ break;
+ case LOCK:
+#ifdef CLIENT_SERVER
+ if(radio_is_remote) {
+ send_lock(client_socket,locked==1?0:1);
+ } else {
+#endif
+ locked=locked==1?0:1;
+ g_idle_add(ext_vfo_update, NULL);
+#ifdef CLIENT_SERVER
+ }
+#endif
+ break;
+ case CTUN:
+ vfo[active_receiver->id].ctun=!vfo[active_receiver->id].ctun;
+ if(!vfo[active_receiver->id].ctun) {
+ vfo[active_receiver->id].offset=0;
+ }
+ vfo[active_receiver->id].ctun_frequency=vfo[active_receiver->id].frequency;
+ set_offset(receiver[active_receiver->id],vfo[active_receiver->id].offset);
+ g_idle_add(ext_vfo_update, NULL);
+ break;
+ case AGC:
+ active_receiver->agc++;
+ if(active_receiver->agc>+AGC_LAST) {
+ active_receiver->agc=0;
+ }
+ set_agc(active_receiver, active_receiver->agc);
+ g_idle_add(ext_vfo_update, NULL);
+ break;
+ case SPLIT:
+ if(can_transmit) {
+ split=split==1?0:1;
+ tx_set_mode(transmitter,get_tx_mode());
+ g_idle_add(ext_vfo_update, NULL);
+ }
+ break;
+ case DIVERSITY:
+ diversity_enabled=diversity_enabled==1?0:1;
+ if (protocol == NEW_PROTOCOL) {
+ schedule_high_priority();
+ schedule_receive_specific();
+ }
+ g_idle_add(ext_vfo_update, NULL);
+ break;
+ case SAT:
+ switch(sat_mode) {
+ case SAT_NONE:
+ sat_mode=SAT_MODE;
+ break;
+ case SAT_MODE:
+ sat_mode=RSAT_MODE;
+ break;
+ case RSAT_MODE:
+ sat_mode=SAT_NONE;
+ break;
+ }
+ g_idle_add(ext_vfo_update, NULL);
+ break;
+ case MENU_AGC:
+ start_agc();
+ break;
+ case MENU_BAND:
+ start_band();
+ break;
+ case MENU_BANDSTACK:
+ start_bandstack();
+ break;
+ case MENU_MODE:
+ start_mode();
+ break;
+ case MENU_NOISE:
+ start_noise();
+ break;
+ case MENU_FILTER:
+ start_filter();
+ break;
+ case MENU_FREQUENCY:
+ start_vfo(active_receiver->id);
+ break;
+ case MENU_MEMORY:
+ start_store();
+ break;
+ case MENU_DIVERSITY:
+ start_diversity();
+ break;
+#ifdef PURESIGNAL
+ case MENU_PS:
+ start_ps();
+ break;
+#endif
+ case MUTE:
+ active_receiver->mute_radio=!active_receiver->mute_radio;
+ break;
+ case PAN_MINUS:
+ update_pan(-100.0);
+ break;
+ case PAN_PLUS:
+ update_pan(+100.0);
+ break;
+ case ZOOM_MINUS:
+ update_zoom(-1);
+ break;
+ case ZOOM_PLUS:
+ update_zoom(+1);
+ break;
+ default:
+ g_print("%s: UNKNOWN PRESSED SWITCH ACTION %d\n",__FUNCTION__,a->action);
+ break;
+ }
+ } else if(a->state==RELEASED) {
+ // only switch functions that increment/decrement while pressed
+ switch(a->action) {
+ default:
+ break;
+ }
+ }
+ g_free(data);
+ return 0;
+}
+
--- /dev/null
+
+enum {
+ ENCODER_NO_ACTION=0,
+ ENCODER_AF_GAIN,
+ ENCODER_AF_GAIN_RX1,
+ ENCODER_AF_GAIN_RX2,
+ ENCODER_AGC_GAIN,
+ ENCODER_AGC_GAIN_RX1,
+ ENCODER_AGC_GAIN_RX2,
+ ENCODER_ATTENUATION,
+ ENCODER_COMP,
+ ENCODER_CW_FREQUENCY,
+ ENCODER_CW_SPEED,
+ ENCODER_DIVERSITY_GAIN,
+ ENCODER_DIVERSITY_GAIN_COARSE,
+ ENCODER_DIVERSITY_GAIN_FINE,
+ ENCODER_DIVERSITY_PHASE,
+ ENCODER_DIVERSITY_PHASE_COARSE,
+ ENCODER_DIVERSITY_PHASE_FINE,
+ ENCODER_DRIVE,
+ ENCODER_IF_SHIFT,
+ ENCODER_IF_SHIFT_RX1,
+ ENCODER_IF_SHIFT_RX2,
+ ENCODER_IF_WIDTH,
+ ENCODER_IF_WIDTH_RX1,
+ ENCODER_IF_WIDTH_RX2,
+ ENCODER_MIC_GAIN,
+ ENCODER_PAN,
+ ENCODER_PANADAPTER_HIGH,
+ ENCODER_PANADAPTER_LOW,
+ ENCODER_PANADAPTER_STEP,
+ ENCODER_RF_GAIN,
+ ENCODER_RF_GAIN_RX1,
+ ENCODER_RF_GAIN_RX2,
+ ENCODER_RIT,
+ ENCODER_RIT_RX1,
+ ENCODER_RIT_RX2,
+ ENCODER_SQUELCH,
+ ENCODER_SQUELCH_RX1,
+ ENCODER_SQUELCH_RX2,
+ ENCODER_TUNE_DRIVE,
+ ENCODER_VFO,
+ ENCODER_WATERFALL_HIGH,
+ ENCODER_WATERFALL_LOW,
+ ENCODER_XIT,
+ ENCODER_ZOOM,
+ ENCODER_ACTIONS
+};
+
+enum {
+ NO_ACTION=0,
+ A_TO_B,
+ A_SWAP_B,
+ AGC,
+ ANF,
+ B_TO_A,
+ BAND_MINUS,
+ BAND_PLUS,
+ BANDSTACK_MINUS,
+ BANDSTACK_PLUS,
+ CTUN,
+ DIVERSITY,
+ DUPLEX,
+ FILTER_MINUS,
+ FILTER_PLUS,
+ FUNCTION,
+ LOCK,
+ MENU_AGC,
+ MENU_BAND,
+ MENU_BANDSTACK,
+ MENU_DIVERSITY,
+ MENU_FILTER,
+ MENU_FREQUENCY,
+ MENU_MEMORY,
+ MENU_MODE,
+ MENU_NOISE,
+ MENU_PS,
+ MODE_MINUS,
+ MODE_PLUS,
+ MOX,
+ MUTE,
+ NB,
+ NR,
+ PAN_MINUS,
+ PAN_PLUS,
+ PS,
+ RIT,
+ RIT_CLEAR,
+ RIT_MINUS,
+ RIT_PLUS,
+ RSAT,
+ SAT,
+ SNB,
+ SPLIT,
+ TUNE,
+ TUNE_FULL,
+ TUNE_MEMORY,
+ TWO_TONE,
+ VFOSTEP_PLUS,
+ VFOSTEP_MINUS,
+ XIT,
+ XIT_CLEAR,
+ XIT_MINUS,
+ XIT_PLUS,
+ ZOOM_MINUS,
+ ZOOM_PLUS,
+ SWITCH_ACTIONS,
+};
+
+enum {
+ PRESSED,
+ RELEASED
+};
+
+typedef struct _switch_action {
+ gint action;
+ gboolean state;
+} SWITCH_ACTION;
+
+enum {
+ RELATIVE,
+ ABSOLUTE
+};
+
+typedef struct _encoder_action {
+ gint action;
+ gboolean mode;
+ gint val;
+} ENCODER_ACTION;
+
+extern char *encoder_string[ENCODER_ACTIONS];
+extern char *sw_string[SWITCH_ACTIONS];
+extern char *sw_cap_string[SWITCH_ACTIONS];
+
+extern int encoder_action(void *data);
+extern int switch_action(void *data);
+
gboolean preamp;
gint attenuation;
gboolean enable_step_attenuation;
+ gdouble gain;
+ gdouble min_gain;
+ gdouble max_gain;
#ifdef SOAPYSDR
- gint *rx_gain;
gboolean agc;
#endif
} ADC;
* program amidi.c in alsautils.
*/
+#include <gtk/gtk.h>
#include "midi.h"
+#include "midi_menu.h"
+#include "alsa_midi.h"
#ifndef __APPLE__
#include <pthread.h>
#include <alsa/asoundlib.h>
-static pthread_t midi_thread_id;
+MIDI_DEVICE midi_devices[MAX_MIDI_DEVICES];
+int n_midi_devices;
+
+//
+// The following must not reside in midi_devices since it
+// needs special #includes
+//
+static pthread_t midi_thread_id[MAX_MIDI_DEVICES];
+static char *midi_port[MAX_MIDI_DEVICES];
+static snd_rawmidi_t *midi_input[MAX_MIDI_DEVICES];
+
static void* midi_thread(void *);
static enum {
CMD_PITCH,
} command;
-static void *midi_thread(void *data) {
+static gboolean configure=FALSE;
+
+void configure_midi_device(gboolean state) {
+ configure=state;
+}
+
+static void *midi_thread(void *arg) {
+ int index = (int) arg;
+ snd_rawmidi_t *input=midi_input[index];
+ char *port=midi_port[index];
+
int ret;
- snd_rawmidi_t *input;
int npfds;
struct pollfd *pfds;
unsigned char buf[32];
unsigned short revents;
int i;
int chan,arg1,arg2;
- char *portname = (char *) data;
-
- if ((ret = snd_rawmidi_open(&input, NULL, portname, SND_RAWMIDI_NONBLOCK)) < 0) {
- fprintf(stderr,"cannot open port \"%s\": %s\n", portname, snd_strerror(ret));
- free(portname);
- return NULL;
- }
- snd_rawmidi_read(input, NULL, 0); /* trigger reading */
+
+
npfds = snd_rawmidi_poll_descriptors_count(input);
pfds = alloca(npfds * sizeof(struct pollfd));
snd_rawmidi_poll_descriptors(input, pfds, npfds);
for (;;) {
ret = poll(pfds, npfds, 250);
+ if (!midi_devices[index].active) break;
if (ret < 0) {
fprintf(stderr,"poll failed: %s\n", strerror(errno));
// Do not give up, but also do not fire too rapidly
ret = snd_rawmidi_read(input, buf, 64);
if (ret == 0) continue;
if (ret < 0) {
- fprintf(stderr,"cannot read from port \"%s\": %s\n", portname, snd_strerror(ret));
+ fprintf(stderr,"cannot read from port \"%s\": %s\n", port, snd_strerror(ret));
continue;
}
// process bytes in buffer. Since they no not necessarily form complete messages
// messages with velocity == 0 when releasing
// a push-button
if (arg2 == 0) {
- NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+ if(configure) {
+ NewMidiConfigureEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+ } else {
+ NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+ }
} else {
- NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 1);
+ if(configure) {
+ NewMidiConfigureEvent(MIDI_EVENT_NOTE, chan, arg1, 1);
+ } else {
+ NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 1);
+ }
}
break;
case CMD_NOTEOFF:
- NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+ if(configure) {
+ NewMidiConfigureEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+ } else {
+ NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+ }
break;
case CMD_CTRL:
- NewMidiEvent(MIDI_EVENT_CTRL, chan, arg1, arg2);
+ if(configure) {
+ NewMidiConfigureEvent(MIDI_EVENT_CTRL, chan, arg1, arg2);
+ } else {
+ NewMidiEvent(MIDI_EVENT_CTRL, chan, arg1, arg2);
+ }
break;
case CMD_PITCH:
- NewMidiEvent(MIDI_EVENT_PITCH, chan, 0, arg1+128*arg2);
+ if(configure) {
+ NewMidiConfigureEvent(MIDI_EVENT_PITCH, chan, 0, arg1+128*arg2);
+ } else {
+ NewMidiEvent(MIDI_EVENT_PITCH, chan, 0, arg1+128*arg2);
+ }
break;
}
state=STATE_SKIP;
}
}
}
+ return NULL;
+}
+
+void register_midi_device(int index) {
+ int i;
+ int ret=0;
+
+ if (index < 0 || index > MAX_MIDI_DEVICES) return;
+
+ g_print("%s: open MIDI device %d\n", __FUNCTION__, index);
+
+ if ((ret = snd_rawmidi_open(&midi_input[index], NULL, midi_port[index], SND_RAWMIDI_NONBLOCK)) < 0) {
+ fprintf(stderr,"cannot open port \"%s\": %s\n", midi_port[index], snd_strerror(ret));
+ return;
+ }
+ snd_rawmidi_read(midi_input[index], NULL, 0); /* trigger reading */
+
+
+ ret = pthread_create(&midi_thread_id[index], NULL, midi_thread, (void *) index);
+ if (ret < 0) {
+ g_print("%s: Failed to create MIDI read thread\n",__FUNCTION__);
+ if((ret = snd_rawmidi_close(midi_input[index])) < 0) {
+ g_print("%s: cannot close port: %s\n",__FUNCTION__, snd_strerror(ret));
+ }
+ return;
+ }
+ midi_devices[index].active=1;
+ return;
}
-void register_midi_device(char *myname) {
+void close_midi_device(int index) {
+ int ret;
+
+ if (index < 0 || index > MAX_MIDI_DEVICES) return;
+ if (midi_devices[index].active == 0) return;
+
+ //
+ // Note that if this is called from get_midi_devices(),
+ // the port and device names do exist but may be wrong.
+ //
+ // Tell thread to stop
+ //
+ midi_devices[index].active=0;
+ //
+ // wait for thread to complete
+ //
+ ret=pthread_join(midi_thread_id[index], NULL);
+ if (ret != 0) {
+ g_print("%s: cannot join: %s\n", __FUNCTION__, strerror(ret));
+ }
+ //
+ // Close MIDI device
+ if((ret = snd_rawmidi_close(midi_input[index])) < 0) {
+ g_print("%s: cannot close port: %s\n",__FUNCTION__, snd_strerror(ret));
+ }
+}
+
+void get_midi_devices() {
- int mylen=strlen(myname);
snd_ctl_t *ctl;
snd_rawmidi_info_t *info;
int card, device, subs, sub, ret;
const char *devnam, *subnam;
int found=0;
- char name[64];
- char *portname;
+ char portname[64];
+ n_midi_devices=0;
card=-1;
if ((ret = snd_card_next(&card)) < 0) {
fprintf(stderr,"cannot determine card number: %s\n", snd_strerror(ret));
return;
}
while (card >= 0) {
- fprintf(stderr,"Found Sound Card=%d\n",card);
- sprintf(name,"hw:%d", card);
- if ((ret = snd_ctl_open(&ctl, name, 0)) < 0) {
+ //fprintf(stderr,"Found Sound Card=%d\n",card);
+ sprintf(portname,"hw:%d", card);
+ if ((ret = snd_ctl_open(&ctl, portname, 0)) < 0) {
fprintf(stderr,"cannot open control for card %d: %s\n", card, snd_strerror(ret));
return;
}
- device = -1;
- // loop through devices of the card
- for (;;) {
- if ((ret = snd_ctl_rawmidi_next_device(ctl, &device)) < 0) {
+ device = -1;
+ // loop through devices of the card
+ for (;;) {
+ if ((ret = snd_ctl_rawmidi_next_device(ctl, &device)) < 0) {
fprintf(stderr,"cannot determine device number: %s\n", snd_strerror(ret));
break;
}
- if (device < 0) break;
- fprintf(stderr,"Found Device=%d on Card=%d\n", device, card);
- // found sub-device
- snd_rawmidi_info_alloca(&info);
+ if (device < 0) break;
+ //fprintf(stderr,"Found Device=%d on Card=%d\n", device, card);
+ // found sub-device
+ snd_rawmidi_info_alloca(&info);
snd_rawmidi_info_set_device(info, device);
snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT);
ret = snd_ctl_rawmidi_info(ctl, info);
subs = snd_rawmidi_info_get_subdevices_count(info);
} else {
subs = 0;
- }
- fprintf(stderr,"Number of MIDI input devices: %d\n", subs);
- if (!subs) break;
- // subs: number of sub-devices to device on card
+ }
+ //fprintf(stderr,"Number of MIDI input devices: %d\n", subs);
+ if (!subs) break;
+ // subs: number of sub-devices to device on card
for (sub = 0; sub < subs; ++sub) {
snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT);
snd_rawmidi_info_set_subdevice(info, sub);
card, device, sub, snd_strerror(ret));
break;
}
- devnam = snd_rawmidi_info_get_name(info);
- subnam = snd_rawmidi_info_get_subdevice_name(info);
- if (!strncmp(myname, devnam, mylen)) {
- found=1;
- // free() portname at the end of midi_thread
- portname=malloc(64);
- // If there is only one sub-device and it has no name, we use
- // devnam for comparison and make a portname of form "hw:x,y",
- // else we use subnam for comparison and make a portname of form "hw:x,y,z".
- if (sub == 0 && subnam[0] == '\0') {
- sprintf(portname,"hw:%d,%d", card, device);
- } else {
- sprintf(portname,"hw:%d,%d,%d", card, device, sub);
- devnam=subnam;
- }
- fprintf(stderr,"MIDI device >%s< selected (PortName=>%s<)\n", devnam, portname);
- } else {
- fprintf(stderr,"MIDI device >%s< not matching >%s<\n", devnam, myname);
- }
if (found) break;
- }
- if (found) break;
- }
- snd_ctl_close(ctl);
- if (found) break;
- // next card
+ devnam = snd_rawmidi_info_get_name(info);
+ subnam = snd_rawmidi_info_get_subdevice_name(info);
+ // If there is only one sub-device and it has no name, we use
+ // devnam for comparison and make a portname of form "hw:x,y",
+ // else we use subnam for comparison and make a portname of form "hw:x,y,z".
+ if (sub == 0 && subnam[0] == '\0') {
+ sprintf(portname,"hw:%d,%d", card, device);
+ } else {
+ sprintf(portname,"hw:%d,%d,%d", card, device, sub);
+ devnam=subnam;
+ }
+ //
+ // If the name was already present at the same position, just keep
+ // it and do nothing.
+ // If the names do not match and the slot is occupied by a opened device,
+ // close it first
+ //
+ int match = 1;
+ if (midi_devices[n_midi_devices].name == NULL) {
+ midi_devices[n_midi_devices].name=g_new(gchar,strlen(devnam)+1);
+ strcpy(midi_devices[n_midi_devices].name, devnam);
+ match = 0;
+ } else {
+ if (strcmp(devnam, midi_devices[n_midi_devices].name)) {
+ g_free(midi_devices[n_midi_devices].name);
+ midi_devices[n_midi_devices].name=g_new(gchar,strlen(devnam)+1);
+ strcpy(midi_devices[n_midi_devices].name, devnam);
+ match = 0;
+ }
+ }
+ if (midi_port[n_midi_devices] == NULL) {
+ midi_port[n_midi_devices]=g_new(gchar,strlen(portname)+1);
+ strcpy(midi_port[n_midi_devices], portname);
+ match = 0;
+ } else {
+ if (strcmp(midi_port[n_midi_devices], portname)) {
+ g_free(midi_port[n_midi_devices]);
+ midi_port[n_midi_devices]=g_new(gchar,strlen(portname)+1);
+ strcpy(midi_port[n_midi_devices], portname);
+ match = 0;
+ }
+ }
+ //
+ // Close MIDI device if it was open, except if the device is
+ // the same as before. In this case, just let the thread
+ // proceed
+ //
+ if (match == 0 && midi_devices[n_midi_devices].active) {
+ close_midi_device(n_midi_devices);
+ }
+ n_midi_devices++;
+ }
+ }
+ snd_ctl_close(ctl);
+ // next card
if ((ret = snd_card_next(&card)) < 0) {
fprintf(stderr,"cannot determine card number: %s\n", snd_strerror(ret));
break;
}
}
- if (!found) {
- fprintf(stderr,"MIDI device %s NOT FOUND!\n", myname);
- return;
- }
- // Found our MIDI input device. Spawn off a thread reading data
- // (use the same variable midi_thread_id for all MIDI threads
- // since it is not used again).
- ret = pthread_create(&midi_thread_id, NULL, midi_thread, portname);
- if (ret < 0) {
- fprintf(stderr,"Failed to create MIDI read thread\n");
+
+ for(int i=0;i<n_midi_devices;i++) {
+ g_print("%s: %d: %s %s\n",__FUNCTION__,i,midi_devices[i].name,midi_port[i]);
}
}
#endif
--- /dev/null
+typedef struct _midi_device {
+ char *name;
+ int active;
+} MIDI_DEVICE;
+
+#define MAX_MIDI_DEVICES 10
+
+extern MIDI_DEVICE midi_devices[MAX_MIDI_DEVICES];
+extern int n_midi_devices;
+
+extern void get_midi_devices();
*/
#include <gtk/gtk.h>
-#include <gdk/gdk.h>
+#include <glib.h>
+#include <glib/gprintf.h>
#include <math.h>
#include <unistd.h>
#include <stdlib.h>
#include "main.h"
#include "channel.h"
#include "discovered.h"
+#include "actions.h"
#include "gpio.h"
#include "i2c.h"
static GtkWidget *dialog;
-static GtkWidget *b_enable_vfo_encoder;
-static GtkWidget *vfo_a_label;
-static GtkWidget *vfo_a;
-static GtkWidget *vfo_b_label;
-static GtkWidget *vfo_b;
-static GtkWidget *b_enable_vfo_pullup;
-static GtkWidget *b_enable_E2_encoder;
-static GtkWidget *E2_a_label;
-static GtkWidget *E2_a;
-static GtkWidget *E2_b_label;
-static GtkWidget *E2_b;
-static GtkWidget *b_enable_E2_pullup;
-static GtkWidget *b_enable_E2_top_encoder;
-static GtkWidget *E2_top_a_label;
-static GtkWidget *E2_top_a;
-static GtkWidget *E2_top_b_label;
-static GtkWidget *E2_top_b;
-static GtkWidget *E2_sw_label;
-static GtkWidget *E2_sw;
-static GtkWidget *b_enable_E3_encoder;
-static GtkWidget *E3_a_label;
-static GtkWidget *E3_a;
-static GtkWidget *E3_b_label;
-static GtkWidget *E3_b;
-static GtkWidget *b_enable_E3_pullup;
-static GtkWidget *b_enable_E3_top_encoder;
-static GtkWidget *E3_top_a_label;
-static GtkWidget *E3_top_a;
-static GtkWidget *E3_top_b_label;
-static GtkWidget *E3_top_b;
-static GtkWidget *E3_sw_label;
-static GtkWidget *E3_sw;
-static GtkWidget *b_enable_E4_encoder;
-static GtkWidget *E4_a_label;
-static GtkWidget *E4_a;
-static GtkWidget *E4_b_label;
-static GtkWidget *E4_b;
-static GtkWidget *b_enable_E4_pullup;
-static GtkWidget *b_enable_E4_top_encoder;
-static GtkWidget *E4_top_a_label;
-static GtkWidget *E4_top_a;
-static GtkWidget *E4_top_b_label;
-static GtkWidget *E4_top_b;
-static GtkWidget *E4_sw_label;
-static GtkWidget *E4_sw;
-static GtkWidget *b_enable_E5_encoder;
-static GtkWidget *E5_a_label;
-static GtkWidget *E5_a;
-static GtkWidget *E5_b_label;
-static GtkWidget *E5_b;
-static GtkWidget *b_enable_E5_pullup;
-static GtkWidget *b_enable_E5_top_encoder;
-static GtkWidget *E5_top_a_label;
-static GtkWidget *E5_top_a;
-static GtkWidget *E5_top_b_label;
-static GtkWidget *E5_top_b;
-static GtkWidget *E5_sw_label;
-static GtkWidget *E5_sw;
-
-static GtkWidget *b_enable_mox;
-static GtkWidget *mox_label;
-static GtkWidget *mox;
-static GtkWidget *b_enable_S1;
-static GtkWidget *S1_label;
-static GtkWidget *S1;
-static GtkWidget *b_enable_S2;
-static GtkWidget *S2_label;
-static GtkWidget *S2;
-static GtkWidget *b_enable_S3;
-static GtkWidget *S3_label;
-static GtkWidget *S3;
-static GtkWidget *b_enable_S4;
-static GtkWidget *S4_label;
-static GtkWidget *S4;
-static GtkWidget *b_enable_S5;
-static GtkWidget *S5_label;
-static GtkWidget *S5;
-static GtkWidget *b_enable_S6;
-static GtkWidget *S6_label;
-static GtkWidget *S6;
-static GtkWidget *b_enable_function;
-static GtkWidget *function_label;
-static GtkWidget *function;
-
-static GtkWidget *i2c_device_text;
-static GtkWidget *i2c_address;
static GtkWidget *i2c_sw_text[16];
-
-#ifdef LOCALCW
-static GtkWidget *cwl_label;
-static GtkWidget *cwl;
-static GtkWidget *cwr_label;
-static GtkWidget *cwr;
-static GtkWidget *cws_label;
-static GtkWidget *cws;
-static GtkWidget *b_enable_cws;
-static GtkWidget *b_enable_cwlr;
-static GtkWidget *b_cw_active_low;
-#endif
-
-#ifdef PTT
-static GtkWidget *ptt_label;
-static GtkWidget *ptt;
-static GtkWidget *b_enable_ptt;
-static GtkWidget *b_ptt_active_low;
-#endif
-
-static gboolean save_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
- if(dialog!=NULL) {
- ENABLE_VFO_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_vfo_encoder))?1:0;
- VFO_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vfo_a));
- VFO_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vfo_b));
- ENABLE_VFO_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_vfo_pullup))?1:0;
-
- ENABLE_E2_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E2_encoder))?1:0;
- E2_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E2_a));
- E2_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E2_b));
- ENABLE_E2_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E2_pullup))?1:0;
- E2_FUNCTION=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E2_sw));
-
- if(controller==CONTROLLER2_V2) {
- E2_TOP_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E2_top_a));
- E2_TOP_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E2_top_b));
- }
-
- ENABLE_E3_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E3_encoder))?1:0;
- E3_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E3_a));
- E3_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E3_b));
- ENABLE_E3_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E3_pullup))?1:0;
- E3_FUNCTION=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E3_sw));
-
- if(controller==CONTROLLER2_V2) {
- E3_TOP_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E3_top_a));
- E3_TOP_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E3_top_b));
- }
-
- ENABLE_E4_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E4_encoder))?1:0;
- E4_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E4_a));
- E4_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E4_b));
- ENABLE_E4_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E4_pullup))?1:0;
- E4_FUNCTION=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E4_sw));
-
- if(controller==CONTROLLER2_V2) {
- E4_TOP_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E4_top_a));
- E4_TOP_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E4_top_b));
- }
-
- if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
- ENABLE_E5_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E5_encoder))?1:0;
- E5_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E5_a));
- E5_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E5_b));
- ENABLE_E5_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E5_pullup))?1:0;
- E5_FUNCTION=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E5_sw));
-
- if(controller==CONTROLLER2_V2) {
- E5_TOP_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E5_top_a));
- E5_TOP_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E5_top_b));
- }
-
- const char *temp=gtk_entry_get_text(GTK_ENTRY(i2c_device_text));
- i2c_device=g_new(char,strlen(temp)+1);
- strcpy(i2c_device,temp);
- i2c_address_1=(unsigned int)strtol(gtk_entry_get_text(GTK_ENTRY(i2c_address)),NULL,16);
- for(int i=0;i<16;i++) {
- i2c_sw[i]=(unsigned int)strtol(gtk_entry_get_text(GTK_ENTRY(i2c_sw_text[i])),NULL,16);
- }
- }
-
- if(controller==CONTROLLER1) {
- ENABLE_MOX_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_mox))?1:0;
- MOX_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(mox));
-
- ENABLE_S1_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S1))?1:0;
- S1_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S1));
-
- ENABLE_S2_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S2))?1:0;
- S2_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S2));
-
- ENABLE_S3_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S3))?1:0;
- S3_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S3));
-
- ENABLE_S4_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S4))?1:0;
- S4_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S4));
-
- ENABLE_S5_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S5))?1:0;
- S5_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S5));
-
- ENABLE_S6_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S6))?1:0;
- S6_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S6));
-
- ENABLE_FUNCTION_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_function))?1:0;
- FUNCTION_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(function));
- }
-
-#ifdef LOCALCW
- ENABLE_CW_BUTTONS=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_cwlr))?1:0;
- CW_ACTIVE_LOW=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_cw_active_low))?1:0;
- CWL_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(cwl));
- CWR_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(cwr));
- ENABLE_GPIO_SIDETONE=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_cws))?1:0;
- SIDETONE_GPIO=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(cws));
-#endif
-
-#ifdef PTT
- ENABLE_PTT_GPIO=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_ptt))?1:0;
- PTT_ACTIVE_LOW=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_ptt_active_low))?1:0;
- PTT_GPIO=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ptt));
-#endif
-
+static void response_event(GtkWidget *dialog,gint id,gpointer user_data) {
+ g_print("%s: id=%d\n",__FUNCTION__,id);
+ if(id==GTK_RESPONSE_ACCEPT) {
gpio_save_state();
- gtk_widget_destroy(dialog);
+ g_print("%s: ACCEPT\n",__FUNCTION__);
}
- return TRUE;
-}
-
-static gboolean cancel_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
- if(dialog!=NULL) {
- gtk_widget_destroy(dialog);
- }
- return TRUE;
+ gtk_widget_destroy(dialog);
+ dialog=NULL;
}
void configure_gpio(GtkWidget *parent) {
- int row;
+ gint row=0;
+ gint col=0;
+ GtkWidget *widget;
+ int i;
gpio_restore_state();
- dialog=gtk_dialog_new_with_buttons("Configure GPIO (WiringPi pin numbers)",GTK_WINDOW(parent),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
- GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- GtkWidget *grid=gtk_grid_new();
- //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ GtkWidget *dialog=gtk_dialog_new_with_buttons("piHPSDR - GPIO pins (Broadcom Numbers) ",GTK_WINDOW(parent),GTK_DIALOG_DESTROY_WITH_PARENT,("OK"),GTK_RESPONSE_ACCEPT,"Cancel",GTK_RESPONSE_REJECT,NULL);
- GtkWidget *notebook=gtk_notebook_new();
+ g_signal_connect (dialog, "response", G_CALLBACK (response_event), NULL);
- GtkWidget *grid0=gtk_grid_new();
- gtk_grid_set_column_spacing (GTK_GRID(grid0),10);
+ GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- GtkWidget *save_b=gtk_button_new_with_label("Save");
- g_signal_connect (save_b, "button_press_event", G_CALLBACK(save_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid0),save_b,0,0,1,1);
+ GtkWidget *notebook=gtk_notebook_new();
- GtkWidget *cancel_b=gtk_button_new_with_label("Cancel");
- g_signal_connect (cancel_b, "button_press_event", G_CALLBACK(cancel_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid0),cancel_b,1,0,1,1);
+ // Encoders
+ gint max_encoders=MAX_ENCODERS;
+ switch(controller) {
+ case NO_CONTROLLER:
+ max_encoders=0;
+ break;
+ case CONTROLLER1:
+ max_encoders=4;
+ break;
+ case CONTROLLER2_V1:
+ max_encoders=5;
+ break;
+ case CONTROLLER2_V2:
+ max_encoders=5;
+ break;
+ }
+ GtkWidget *grid=gtk_grid_new();
+ gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE);
+ gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_column_spacing (GTK_GRID(grid),2);
+ gtk_grid_set_row_spacing (GTK_GRID(grid),2);
- if(controller!=NO_CONTROLLER) {
- // Encoders
-
- GtkWidget *grid1=gtk_grid_new();
- gtk_grid_set_column_homogeneous(GTK_GRID(grid1),FALSE);
- gtk_grid_set_row_homogeneous(GTK_GRID(grid1),TRUE);
- gtk_grid_set_column_spacing (GTK_GRID(grid1),5);
- row=0;
-
- b_enable_vfo_encoder=gtk_check_button_new_with_label("Enable VFO");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_vfo_encoder), ENABLE_VFO_ENCODER);
- gtk_widget_show(b_enable_vfo_encoder);
- gtk_grid_attach(GTK_GRID(grid1),b_enable_vfo_encoder,0,row,1,1);
-
- vfo_a_label=gtk_label_new("GPIO A:");
- gtk_widget_show(vfo_a_label);
- gtk_grid_attach(GTK_GRID(grid1),vfo_a_label,1,row,1,1);
-
- vfo_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(vfo_a),VFO_ENCODER_A);
- gtk_widget_show(vfo_a);
- gtk_grid_attach(GTK_GRID(grid1),vfo_a,2,row,1,1);
-
- vfo_b_label=gtk_label_new("GPIO B:");
- gtk_widget_show(vfo_b_label);
- gtk_grid_attach(GTK_GRID(grid1),vfo_b_label,3,row,1,1);
-
- vfo_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(vfo_b),VFO_ENCODER_B);
- gtk_widget_show(vfo_b);
- gtk_grid_attach(GTK_GRID(grid1),vfo_b,4,row,1,1);
-
- b_enable_vfo_pullup=gtk_check_button_new_with_label("Enable Pull-up");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_vfo_pullup), ENABLE_VFO_PULLUP);
- gtk_widget_show(b_enable_vfo_pullup);
- gtk_grid_attach(GTK_GRID(grid1),b_enable_vfo_pullup,7,row,1,1);
-
-
- row++;
-
- b_enable_E2_encoder=gtk_check_button_new_with_label("Enable E2");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E2_encoder), ENABLE_E2_ENCODER);
- gtk_widget_show(b_enable_E2_encoder);
- gtk_grid_attach(GTK_GRID(grid1),b_enable_E2_encoder,0,row,1,1);
-
- E2_a_label=gtk_label_new("GPIO A:");
- gtk_widget_show(E2_a_label);
- gtk_grid_attach(GTK_GRID(grid1),E2_a_label,1,row,1,1);
-
- E2_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E2_a),E2_ENCODER_A);
- gtk_widget_show(E2_a);
- gtk_grid_attach(GTK_GRID(grid1),E2_a,2,row,1,1);
-
- E2_b_label=gtk_label_new("GPIO B:");
- gtk_widget_show(E2_b_label);
- gtk_grid_attach(GTK_GRID(grid1),E2_b_label,3,row,1,1);
-
- E2_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E2_b),E2_ENCODER_B);
- gtk_widget_show(E2_b);
- gtk_grid_attach(GTK_GRID(grid1),E2_b,4,row,1,1);
-
- E2_sw_label=gtk_label_new("SW:");
- gtk_widget_show(E2_sw_label);
- gtk_grid_attach(GTK_GRID(grid1),E2_sw_label,5,row,1,1);
-
- E2_sw=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E2_sw),E2_FUNCTION);
- gtk_widget_show(E2_sw);
- gtk_grid_attach(GTK_GRID(grid1),E2_sw,6,row,1,1);
-
- b_enable_E2_pullup=gtk_check_button_new_with_label("Enable Pull-up");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E2_pullup), ENABLE_E2_PULLUP);
- gtk_widget_show(b_enable_E2_pullup);
- gtk_grid_attach(GTK_GRID(grid1),b_enable_E2_pullup,7,row,1,1);
-
-
- row++;
+/*
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<span foreground=\"#ff0000\"><b>Note: Pin number now use Broadcom GPIO</b></span>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,6,1);
- if(controller==CONTROLLER2_V2) {
- E2_top_a_label=gtk_label_new("GPIO A:");
- gtk_widget_show(E2_top_a_label);
- gtk_grid_attach(GTK_GRID(grid1),E2_top_a_label,1,row,1,1);
+ row++;
+ col=0;
+*/
+ widget=gtk_label_new("");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), controller==CONTROLLER2_V2?"<b>Bottom Encoder</b>":"<b>Encoder</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,2,1);
+ col+=2;
+
+ if(controller==CONTROLLER2_V2) {
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<b>Top Encoder</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,2,1);
+ col+=2;
+ }
- E2_top_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E2_top_a),E2_TOP_ENCODER_A);
- gtk_widget_show(E2_top_a);
- gtk_grid_attach(GTK_GRID(grid1),E2_top_a,2,row,1,1);
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<b>Switch</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
- E2_top_b_label=gtk_label_new("GPIO B:");
- gtk_widget_show(E2_top_b_label);
- gtk_grid_attach(GTK_GRID(grid1),E2_top_b_label,3,row,1,1);
+ row++;
+ col=0;
+
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<b>ID</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio A</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio B</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ if(controller==CONTROLLER2_V2) {
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio A</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio B</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ }
- E2_top_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E2_top_b),E2_TOP_ENCODER_B);
- gtk_widget_show(E2_top_b);
- gtk_grid_attach(GTK_GRID(grid1),E2_top_b,4,row,1,1);
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
- row++;
+ row++;
+ col=0;
+
+ for(i=0;i<max_encoders;i++) {
+ widget=gtk_label_new(NULL);
+ gchar id[16];
+ g_sprintf(id,"<b>%d</b>",i);
+ gtk_label_set_markup (GTK_LABEL(widget), id);
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].bottom_encoder_address_a);
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].bottom_encoder_address_b);
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ if(controller==CONTROLLER2_V2 && i<(max_encoders-1)) {
+ widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].top_encoder_address_a);
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].top_encoder_address_b);
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
}
- b_enable_E3_encoder=gtk_check_button_new_with_label("Enable E3");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E3_encoder), ENABLE_E3_ENCODER);
- gtk_widget_show(b_enable_E3_encoder);
- gtk_grid_attach(GTK_GRID(grid1),b_enable_E3_encoder,0,row,1,1);
-
- E3_a_label=gtk_label_new("GPIO A:");
- gtk_widget_show(E3_a_label);
- gtk_grid_attach(GTK_GRID(grid1),E3_a_label,1,row,1,1);
-
- E3_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E3_a),E3_ENCODER_A);
- gtk_widget_show(E3_a);
- gtk_grid_attach(GTK_GRID(grid1),E3_a,2,row,1,1);
-
- E3_b_label=gtk_label_new("GPIO B:");
- gtk_widget_show(E3_b_label);
- gtk_grid_attach(GTK_GRID(grid1),E3_b_label,3,row,1,1);
-
- E3_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E3_b),E3_ENCODER_B);
- gtk_widget_show(E3_b);
- gtk_grid_attach(GTK_GRID(grid1),E3_b,4,row,1,1);
-
- E3_sw_label=gtk_label_new("SW:");
- gtk_widget_show(E3_sw_label);
- gtk_grid_attach(GTK_GRID(grid1),E3_sw_label,5,row,1,1);
-
- E3_sw=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E3_sw),E3_FUNCTION);
- gtk_widget_show(E3_sw);
- gtk_grid_attach(GTK_GRID(grid1),E3_sw,6,row,1,1);
-
- b_enable_E3_pullup=gtk_check_button_new_with_label("Enable Pull-up");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E3_pullup), ENABLE_E3_PULLUP);
- gtk_widget_show(b_enable_E3_pullup);
- gtk_grid_attach(GTK_GRID(grid1),b_enable_E3_pullup,7,row,1,1);
-
- row++;
-
- if(controller==CONTROLLER2_V2) {
- E3_top_a_label=gtk_label_new("GPIO A:");
- gtk_widget_show(E3_top_a_label);
- gtk_grid_attach(GTK_GRID(grid1),E3_top_a_label,1,row,1,1);
-
- E3_top_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E3_top_a),E3_TOP_ENCODER_A);
- gtk_widget_show(E3_top_a);
- gtk_grid_attach(GTK_GRID(grid1),E3_top_a,2,row,1,1);
-
- E3_top_b_label=gtk_label_new("GPIO B:");
- gtk_widget_show(E3_top_b_label);
- gtk_grid_attach(GTK_GRID(grid1),E3_top_b_label,3,row,1,1);
-
- E3_top_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E3_top_b),E3_TOP_ENCODER_B);
- gtk_widget_show(E3_top_b);
- gtk_grid_attach(GTK_GRID(grid1),E3_top_b,4,row,1,1);
-
- row++;
+ if(i<(max_encoders-1)) {
+ widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].switch_address);
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
}
- b_enable_E4_encoder=gtk_check_button_new_with_label("Enable E4");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E4_encoder), ENABLE_E4_ENCODER);
- gtk_widget_show(b_enable_E4_encoder);
- gtk_grid_attach(GTK_GRID(grid1),b_enable_E4_encoder,0,row,1,1);
-
- E4_a_label=gtk_label_new("GPIO A:");
- gtk_widget_show(E4_a_label);
- gtk_grid_attach(GTK_GRID(grid1),E4_a_label,1,row,1,1);
-
- E4_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E4_a),E4_ENCODER_A);
- gtk_widget_show(E4_a);
- gtk_grid_attach(GTK_GRID(grid1),E4_a,2,row,1,1);
-
- E4_b_label=gtk_label_new("GPIO B:");
- gtk_widget_show(E4_b_label);
- gtk_grid_attach(GTK_GRID(grid1),E4_b_label,3,row,1,1);
-
- E4_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E4_b),E4_ENCODER_B);
- gtk_widget_show(E4_b);
- gtk_grid_attach(GTK_GRID(grid1),E4_b,4,row,1,1);
-
- E4_sw_label=gtk_label_new("SW:");
- gtk_widget_show(E4_sw_label);
- gtk_grid_attach(GTK_GRID(grid1),E4_sw_label,5,row,1,1);
-
- E4_sw=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E4_sw),E4_FUNCTION);
- gtk_widget_show(E4_sw);
- gtk_grid_attach(GTK_GRID(grid1),E4_sw,6,row,1,1);
-
- b_enable_E4_pullup=gtk_check_button_new_with_label("Enable Pull-up");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E4_pullup), ENABLE_E4_PULLUP);
- gtk_widget_show(b_enable_E4_pullup);
- gtk_grid_attach(GTK_GRID(grid1),b_enable_E4_pullup,7,row,1,1);
-
row++;
+ col=0;
+ }
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid,gtk_label_new("Encoders"));
- if(controller==CONTROLLER2_V2)
- {
- E4_top_a_label=gtk_label_new("GPIO A:");
- gtk_widget_show(E4_top_a_label);
- gtk_grid_attach(GTK_GRID(grid1),E4_top_a_label,1,row,1,1);
-
- E4_top_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E4_top_a),E4_TOP_ENCODER_A);
- gtk_widget_show(E4_top_a);
- gtk_grid_attach(GTK_GRID(grid1),E4_top_a,2,row,1,1);
-
- E4_top_b_label=gtk_label_new("GPIO B:");
- gtk_widget_show(E4_top_b_label);
- gtk_grid_attach(GTK_GRID(grid1),E4_top_b_label,3,row,1,1);
-
- E4_top_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E4_top_b),E4_TOP_ENCODER_B);
- gtk_widget_show(E4_top_b);
- gtk_grid_attach(GTK_GRID(grid1),E4_top_b,4,row,1,1);
-
- row++;
- }
- if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
- b_enable_E5_encoder=gtk_check_button_new_with_label("Enable E5");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E5_encoder), ENABLE_E5_ENCODER);
- gtk_widget_show(b_enable_E5_encoder);
- gtk_grid_attach(GTK_GRID(grid1),b_enable_E5_encoder,0,row,1,1);
-
- E5_a_label=gtk_label_new("GPIO A:");
- gtk_widget_show(E5_a_label);
- gtk_grid_attach(GTK_GRID(grid1),E5_a_label,1,row,1,1);
-
- E5_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E5_a),E5_ENCODER_A);
- gtk_widget_show(E5_a);
- gtk_grid_attach(GTK_GRID(grid1),E5_a,2,row,1,1);
-
- E5_b_label=gtk_label_new("GPIO B:");
- gtk_widget_show(E5_b_label);
- gtk_grid_attach(GTK_GRID(grid1),E5_b_label,3,row,1,1);
-
- E5_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E5_b),E5_ENCODER_B);
- gtk_widget_show(E5_b);
- gtk_grid_attach(GTK_GRID(grid1),E5_b,4,row,1,1);
-
- E5_sw_label=gtk_label_new("SW:");
- gtk_widget_show(E5_sw_label);
- gtk_grid_attach(GTK_GRID(grid1),E5_sw_label,5,row,1,1);
-
- E5_sw=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E5_sw),E5_FUNCTION);
- gtk_widget_show(E5_sw);
- gtk_grid_attach(GTK_GRID(grid1),E5_sw,6,row,1,1);
-
- b_enable_E5_pullup=gtk_check_button_new_with_label("Enable Pull-up");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E5_pullup), ENABLE_E5_PULLUP);
- gtk_widget_show(b_enable_E5_pullup);
- gtk_grid_attach(GTK_GRID(grid1),b_enable_E5_pullup,7,row,1,1);
-
- if(controller==CONTROLLER2_V2) {
- row++;
-
- E5_top_a_label=gtk_label_new("GPIO A:");
- gtk_widget_show(E5_top_a_label);
- gtk_grid_attach(GTK_GRID(grid1),E5_top_a_label,1,row,1,1);
-
- E5_top_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E5_top_a),E5_TOP_ENCODER_A);
- gtk_widget_show(E5_top_a);
- gtk_grid_attach(GTK_GRID(grid1),E5_top_a,2,row,1,1);
-
- E5_top_b_label=gtk_label_new("GPIO B:");
- gtk_widget_show(E5_top_b_label);
- gtk_grid_attach(GTK_GRID(grid1),E5_top_b_label,3,row,1,1);
-
- E5_top_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(E5_top_b),E5_TOP_ENCODER_B);
- gtk_widget_show(E5_top_b);
- gtk_grid_attach(GTK_GRID(grid1),E5_top_b,4,row,1,1);
- }
+ // switches
+ if(controller==CONTROLLER1) {
+ gint max_switches=MAX_SWITCHES;
+ switch(controller) {
+ case NO_CONTROLLER:
+ max_switches=0;
+ break;
+ case CONTROLLER1:
+ max_switches=8;
+ break;
+ case CONTROLLER2_V1:
+ max_switches=0;
+ break;
+ case CONTROLLER2_V2:
+ max_switches=0;
+ break;
}
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid1,gtk_label_new("Encoders"));
-
- // Switches
-
- GtkWidget *grid2=gtk_grid_new();
- gtk_grid_set_column_spacing (GTK_GRID(grid2),10);
- row=0;
-
-
- if(controller==CONTROLLER1) {
- b_enable_mox=gtk_check_button_new_with_label("Enable MOX/TUN");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_mox), ENABLE_MOX_BUTTON);
- gtk_widget_show(b_enable_mox);
- gtk_grid_attach(GTK_GRID(grid2),b_enable_mox,0,row,1,1);
-
- mox_label=gtk_label_new("GPIO:");
- gtk_widget_show(mox_label);
- gtk_grid_attach(GTK_GRID(grid2),mox_label,1,row,1,1);
-
- mox=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(mox),MOX_BUTTON);
- gtk_widget_show(mox);
- gtk_grid_attach(GTK_GRID(grid2),mox,2,row,1,1);
-
- row++;
-
- b_enable_S1=gtk_check_button_new_with_label("Enable S1");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_S1), ENABLE_S1_BUTTON);
- gtk_widget_show(b_enable_S1);
- gtk_grid_attach(GTK_GRID(grid2),b_enable_S1,0,row,1,1);
-
- S1_label=gtk_label_new("GPIO:");
- gtk_widget_show(S1_label);
- gtk_grid_attach(GTK_GRID(grid2),S1_label,1,row,1,1);
-
- S1=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(S1),S1_BUTTON);
- gtk_widget_show(S1);
- gtk_grid_attach(GTK_GRID(grid2),S1,2,row,1,1);
-
- row++;
+ grid=gtk_grid_new();
+ gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE);
+ gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_column_spacing (GTK_GRID(grid),2);
+ gtk_grid_set_row_spacing (GTK_GRID(grid),2);
- b_enable_S2=gtk_check_button_new_with_label("Enable S2");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_S2), ENABLE_S2_BUTTON);
- gtk_widget_show(b_enable_S2);
- gtk_grid_attach(GTK_GRID(grid),b_enable_S2,0,row,1,1);
-
- S2_label=gtk_label_new("GPIO:");
- gtk_widget_show(S2_label);
- gtk_grid_attach(GTK_GRID(grid),S2_label,1,row,1,1);
-
- S2=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(S2),S2_BUTTON);
- gtk_widget_show(S2);
- gtk_grid_attach(GTK_GRID(grid),S2,2,row,1,1);
+ row=0;
+ col=0;
- row++;
+/*
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<span foreground=\"#ff0000\"><b>Note: Pin number now use Broadcom GPIO</b></span>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,6,1);
- b_enable_S3=gtk_check_button_new_with_label("Enable S3");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_S3), ENABLE_S3_BUTTON);
- gtk_widget_show(b_enable_S3);
- gtk_grid_attach(GTK_GRID(grid),b_enable_S3,0,row,1,1);
-
- S3_label=gtk_label_new("GPIO:");
- gtk_widget_show(S3_label);
- gtk_grid_attach(GTK_GRID(grid),S3_label,1,row,1,1);
-
- S3=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(S3),S3_BUTTON);
- gtk_widget_show(S3);
- gtk_grid_attach(GTK_GRID(grid),S3,2,row,1,1);
-
- row++;
-
- b_enable_S4=gtk_check_button_new_with_label("Enable S4");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_S4), ENABLE_S4_BUTTON);
- gtk_widget_show(b_enable_S4);
- gtk_grid_attach(GTK_GRID(grid2),b_enable_S4,0,row,1,1);
-
- S4_label=gtk_label_new("GPIO:");
- gtk_widget_show(S4_label);
- gtk_grid_attach(GTK_GRID(grid2),S4_label,1,row,1,1);
-
- S4=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(S4),S4_BUTTON);
- gtk_widget_show(S4);
- gtk_grid_attach(GTK_GRID(grid2),S4,2,row,1,1);
-
- row++;
+ row++;
+ col=0;
+*/
+ for(i=0;i<max_switches/8;i++) {
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<b>ID</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
- b_enable_S5=gtk_check_button_new_with_label("Enable S5");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_S5), ENABLE_S5_BUTTON);
- gtk_widget_show(b_enable_S5);
- gtk_grid_attach(GTK_GRID(grid2),b_enable_S5,0,row,1,1);
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ }
- S5_label=gtk_label_new("GPIO:");
- gtk_widget_show(S5_label);
- gtk_grid_attach(GTK_GRID(grid2),S5_label,1,row,1,1);
-
- S5=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(S5),S5_BUTTON);
- gtk_widget_show(S5);
- gtk_grid_attach(GTK_GRID(grid2),S5,2,row,1,1);
-
- row++;
-
- b_enable_S6=gtk_check_button_new_with_label("Enable S6");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_S6), ENABLE_S6_BUTTON);
- gtk_widget_show(b_enable_S6);
- gtk_grid_attach(GTK_GRID(grid2),b_enable_S6,0,row,1,1);
-
- S6_label=gtk_label_new("GPIO:");
- gtk_widget_show(S6_label);
- gtk_grid_attach(GTK_GRID(grid2),S6_label,1,row,1,1);
-
- S6=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(S6),S6_BUTTON);
- gtk_widget_show(S6);
- gtk_grid_attach(GTK_GRID(grid2),S6,2,row,1,1);
-
- row++;
-
- b_enable_function=gtk_check_button_new_with_label("Enable Function");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_function), ENABLE_FUNCTION_BUTTON);
- gtk_widget_show(b_enable_function);
- gtk_grid_attach(GTK_GRID(grid2),b_enable_function,0,row,1,1);
-
- function_label=gtk_label_new("GPIO:");
- gtk_widget_show(function_label);
- gtk_grid_attach(GTK_GRID(grid2),function_label,1,row,1,1);
+ row++;
+ col=0;
+
+ for(i=0;i<max_switches;i++) {
+ widget=gtk_label_new(NULL);
+ gchar id[16];
+ g_sprintf(id,"<b>%d</b>",i);
+ gtk_label_set_markup (GTK_LABEL(widget), id);
+ gtk_grid_attach(GTK_GRID(grid),widget,(i/8)*2,(row+(i%8)),1,1);
+
+ widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),switches[i].switch_address);
+ gtk_grid_attach(GTK_GRID(grid),widget,((i/8)*2)+1,(row+(i%8)),1,1);
+ }
- function=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(function),FUNCTION_BUTTON);
- gtk_widget_show(function);
- gtk_grid_attach(GTK_GRID(grid2),function,2,row,1,1);
-
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid2,gtk_label_new("Switches"));
- } else {
- char text[16];
- GtkWidget *grid2=gtk_grid_new();
- gtk_grid_set_column_spacing (GTK_GRID(grid2),10);
- row=0;
-
- GtkWidget *label=gtk_label_new("I2C Device:");
- gtk_widget_show(label);
- gtk_grid_attach(GTK_GRID(grid2),label,0,row,1,1);
-
- i2c_device_text=gtk_entry_new();
- gtk_widget_show(i2c_device_text);
- gtk_entry_set_text (GTK_ENTRY(i2c_device_text),i2c_device);
- gtk_grid_attach(GTK_GRID(grid2),i2c_device_text,1,row,1,1);
-
- label=gtk_label_new("I2C Address:");
- gtk_widget_show(label);
- gtk_grid_attach(GTK_GRID(grid2),label,2,row,1,1);
-
- i2c_address=gtk_entry_new();
- sprintf(text,"0x%02X",i2c_address_1);
- gtk_entry_set_text (GTK_ENTRY(i2c_address),text);
- gtk_widget_show(i2c_address);
- gtk_grid_attach(GTK_GRID(grid2),i2c_address,3,row,1,1);
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid,gtk_label_new("switches"));
+ }
- row++;
+ if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
+ grid=gtk_grid_new();
+ gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE);
+ gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_column_spacing (GTK_GRID(grid),2);
+ gtk_grid_set_row_spacing (GTK_GRID(grid),2);
- for(int i=0;i<8;i++) {
- sprintf(text,"SW_%d",i+2);
- label=gtk_label_new(text);
- gtk_widget_show(label);
- gtk_grid_attach(GTK_GRID(grid2),label,0,row,1,1);
+ row=0;
+ col=0;
+
+ char text[16];
+ grid=gtk_grid_new();
+ gtk_grid_set_column_spacing (GTK_GRID(grid),10);
+
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(widget),"<b>I2C Device</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ widget=gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(widget),i2c_device);
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(widget),"<b>I2C Address</b>");
+ gtk_widget_show(widget);
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ widget=gtk_entry_new();
+ sprintf(text,"0x%02X",i2c_address_1);
+ gtk_entry_set_text(GTK_ENTRY(widget),text);
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
- i2c_sw_text[i]=gtk_entry_new();
- sprintf(text,"0x%04X",i2c_sw[i]);
- gtk_entry_set_text (GTK_ENTRY(i2c_sw_text[i]),text);
- gtk_widget_show(i2c_sw_text[i]);
- gtk_grid_attach(GTK_GRID(grid2),i2c_sw_text[i],1,row,1,1);
+ row++;
+ col=0;
- sprintf(text,"SW_%d",i+10);
- label=gtk_label_new(text);
- gtk_widget_show(label);
- gtk_grid_attach(GTK_GRID(grid2),label,2,row,1,1);
+ for(int i=0;i<8;i++) {
+ widget=gtk_label_new(NULL);
+ sprintf(text,"<b>SW_%d</b>",i+2);
+ gtk_label_set_markup(GTK_LABEL(widget),text);
+ gtk_grid_attach(GTK_GRID(grid),widget,0,row,1,1);
- i2c_sw_text[i+8]=gtk_entry_new();
- sprintf(text,"0x%04X",i2c_sw[i+8]);
- gtk_entry_set_text (GTK_ENTRY(i2c_sw_text[i+8]),text);
- gtk_widget_show(i2c_sw_text[i+8]);
- gtk_grid_attach(GTK_GRID(grid2),i2c_sw_text[i+8],3,row,1,1);
+ i2c_sw_text[i]=gtk_entry_new();
+ sprintf(text,"0x%04X",i2c_sw[i]);
+ gtk_entry_set_text (GTK_ENTRY(i2c_sw_text[i]),text);
+ gtk_grid_attach(GTK_GRID(grid),i2c_sw_text[i],1,row,1,1);
- row++;
+ widget=gtk_label_new(NULL);
+ sprintf(text,"<b>SW_%d</b>",i+10);
+ gtk_label_set_markup(GTK_LABEL(widget),text);
+ gtk_grid_attach(GTK_GRID(grid),widget,2,row,1,1);
- }
+ i2c_sw_text[i+8]=gtk_entry_new();
+ sprintf(text,"0x%04X",i2c_sw[i+8]);
+ gtk_entry_set_text (GTK_ENTRY(i2c_sw_text[i+8]),text);
+ gtk_grid_attach(GTK_GRID(grid),i2c_sw_text[i+8],3,row,1,1);
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid2,gtk_label_new("I2C"));
+ row++;
}
-
+
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid,gtk_label_new("i2c"));
}
-#ifdef LOCALCW
- // CW
-
- GtkWidget *grid3=gtk_grid_new();
- gtk_grid_set_column_spacing (GTK_GRID(grid3),10);
- row=0;
-
- cwl_label=gtk_label_new("CWL GPIO:");
- gtk_widget_show(cwl_label);
- gtk_grid_attach(GTK_GRID(grid3),cwl_label,0,row,1,1);
-
- cwl=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(cwl),CWL_BUTTON);
- gtk_widget_show(cwl);
- gtk_grid_attach(GTK_GRID(grid3),cwl,1,row,1,1);
-
- b_enable_cwlr=gtk_check_button_new_with_label("CWLR Enable");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_cwlr), ENABLE_CW_BUTTONS);
- gtk_widget_show(b_enable_cwlr);
- gtk_grid_attach(GTK_GRID(grid3),b_enable_cwlr,2,row,1,1);
-
- row++;
-
- cwr_label=gtk_label_new("CWR GPIO:");
- gtk_widget_show(cwr_label);
- gtk_grid_attach(GTK_GRID(grid3),cwr_label,0,row,1,1);
-
- cwr=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(cwr),CWR_BUTTON);
- gtk_widget_show(cwr);
- gtk_grid_attach(GTK_GRID(grid3),cwr,1,row,1,1);
-
- b_cw_active_low=gtk_check_button_new_with_label("CWLR active-low");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_cw_active_low), CW_ACTIVE_LOW);
- gtk_widget_show(b_cw_active_low);
- gtk_grid_attach(GTK_GRID(grid3),b_cw_active_low,2,row,1,1);
-
- row++;
-
- cws_label=gtk_label_new(" SideTone GPIO:");
- gtk_widget_show(cws_label);
- gtk_grid_attach(GTK_GRID(grid3),cws_label,0,row,1,1);
-
- cws=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(cws),SIDETONE_GPIO);
- gtk_widget_show(cws);
- gtk_grid_attach(GTK_GRID(grid3),cws,1,row,1,1);
-
- b_enable_cws=gtk_check_button_new_with_label("Enable");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_cws), ENABLE_GPIO_SIDETONE);
- gtk_widget_show(b_enable_cws);
- gtk_grid_attach(GTK_GRID(grid3),b_enable_cws,2,row,1,1);
-
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid3,gtk_label_new("CW"));
-#endif
-
-#ifdef PTT
- GtkWidget *grid4=gtk_grid_new();
- gtk_grid_set_column_spacing (GTK_GRID(grid4),10);
- row=0;
-
- b_enable_ptt=gtk_check_button_new_with_label("PTT Enable");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_ptt), ENABLE_PTT_GPIO);
- gtk_widget_show(b_enable_ptt);
- gtk_grid_attach(GTK_GRID(grid4),b_enable_ptt,0,row,1,1);
-
- row++;
-
- ptt_label=gtk_label_new("PTT GPIO:");
- gtk_widget_show(ptt_label);
- gtk_grid_attach(GTK_GRID(grid4),ptt_label,0,row,1,1);
-
- ptt=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(ptt),CWR_BUTTON);
- gtk_widget_show(ptt);
- gtk_grid_attach(GTK_GRID(grid4),ptt,1,row,1,1);
-
- row++;
-
- b_ptt_active_low=gtk_check_button_new_with_label("PTT active-low");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_ptt_active_low), PTT_ACTIVE_LOW);
- gtk_widget_show(b_ptt_active_low);
- gtk_grid_attach(GTK_GRID(grid4),b_ptt_active_low,0,row,1,1);
-
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid4,gtk_label_new("PTT"));
-#endif
-
- gtk_grid_attach(GTK_GRID(grid0),notebook,0,1,6,1);
- gtk_container_add(GTK_CONTAINER(content),grid0);
+ gtk_container_add(GTK_CONTAINER(content),notebook);
gtk_widget_show_all(dialog);
gtk_dialog_run(GTK_DIALOG(dialog));
-
}
#endif
--- /dev/null
+#include <gtk/gtk.h>
+
+char *css=
+" #small {\n"
+" padding: 0;\n"
+" font-family: Sans;\n"
+" font-size: 12px;\n"
+" }\n"
+;
+
+void load_css() {
+ GtkCssProvider *provider;
+ GdkDisplay *display;
+ GdkScreen *screen;
+
+ g_print("%s\n",__FUNCTION__);
+ provider = gtk_css_provider_new ();
+ display = gdk_display_get_default ();
+ screen = gdk_display_get_default_screen (display);
+ gtk_style_context_add_provider_for_screen (screen,
+ GTK_STYLE_PROVIDER(provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+ gtk_css_provider_load_from_data(provider, css, -1, NULL);
+ g_object_unref (provider);
+}
typedef struct _dac {
gint antenna;
- gint *tx_gain;
+ gdouble gain;
} DAC;
#endif
char hardware_key[64];
char driver_key[64];
int rtlsdr_count;
+ int sdrplay_count;
int sample_rate;
size_t rx_channels;
size_t rx_gains;
SoapySDRRange *tx_range;
size_t tx_antennas;
char **tx_antenna;
+ size_t sensors;
+ char **sensor;
+ gboolean has_temp;
+ char address[64];
} soapy;
#endif
} info;
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-#ifdef MIDI
-#include <sys/stat.h>
-#include <fcntl.h>
-#endif
#include "discovered.h"
#include "old_discovery.h"
return TRUE;
}
-#ifdef MIDI
-//
-// This is a file open dialog. If we choose a readable file here, it is just copied
-// to file "midi.props" in the local directory
-//
-static gboolean midi_cb(GtkWidget *widget, GdkEventButton *event, gpointer data) {
- GtkWidget *opfile,*message;
- GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
- gint res;
- int fdin, fdout;
- size_t len,bytes_read,bytes_written;
-
- opfile = gtk_file_chooser_dialog_new ("Import MIDI description",
- GTK_WINDOW(top_window),
- action,
- "Cancel",
- GTK_RESPONSE_CANCEL,
- "Open",
- GTK_RESPONSE_ACCEPT,
- NULL);
-
- res = gtk_dialog_run (GTK_DIALOG (opfile));
- if (res == GTK_RESPONSE_ACCEPT) {
- char *filename, *cp;
- struct stat statbuf;
- GtkFileChooser *chooser = GTK_FILE_CHOOSER (opfile);
- char *contents = NULL;
- filename = gtk_file_chooser_get_filename (chooser);
- fdin =open(filename, O_RDONLY);
- bytes_read = bytes_written = 0;
- if (fdin >= 0) {
- fstat(fdin, &statbuf);
- len=statbuf.st_size;
- //
- // Now first read the whole contents of the file, and then write it out.
- // This is for new-bees trying to import the midi.props in the working dir
- //
- contents=g_new(char, len);
- bytes_read = bytes_written = 0;
- if (contents) {
- bytes_read=read(fdin, contents, len);
- }
- close(fdin);
- }
- fdout=0;
- if (contents && bytes_read == len) {
- // should this file exist as a link or symlink, or should it
- // be read-only, remove it first
- unlink("midi.props");
- fdout=open("midi.props", O_WRONLY | O_CREAT, 0644);
- if (fdout >= 0) {
- bytes_written=write(fdout, contents, len);
- close(fdout);
- g_free(contents);
- }
- }
- if (fdin < 0 || bytes_read < len) {
- message = gtk_message_dialog_new (GTK_WINDOW(top_window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Cannot read input file!\n");
- gtk_dialog_run (GTK_DIALOG (message));
- gtk_widget_destroy(message);
- } else if (fdout < 0 || bytes_written < len) {
- message = gtk_message_dialog_new (GTK_WINDOW(top_window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Cannot write MIDI settings!\n");
- gtk_dialog_run (GTK_DIALOG (message));
- gtk_widget_destroy(message);
- } else {
- // only show basename in the message
- cp = filename + strlen(filename);
- while (cp >= filename) {
- if (*cp == '/') {
- cp++;
- break;
- }
- cp--;
- }
- message = gtk_message_dialog_new (GTK_WINDOW(top_window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "MIDI import: %ld Bytes read from file %s\n",len,cp);
- gtk_dialog_run (GTK_DIALOG (message));
- gtk_widget_destroy(message);
- }
- g_free(filename);
- }
- gtk_widget_destroy (opfile);
- return TRUE;
-}
-#endif
-
static gboolean protocols_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
configure_protocols(discovery_dialog);
return TRUE;
g_signal_connect (protocols_b, "button-press-event", G_CALLBACK(protocols_cb), NULL);
gtk_grid_attach(GTK_GRID(grid),protocols_b,2,row,1,1);
-#ifdef MIDI
- GtkWidget *midi_b=gtk_button_new_with_label("ImportMIDI");
- g_signal_connect (midi_b, "button-press-event", G_CALLBACK(midi_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),midi_b,3,row,1,1);
-#endif
-
row++;
#ifdef GPIO
*/
#include <gtk/gtk.h>
+#include <glib/gprintf.h>
#include <stdio.h>
#include <string.h>
#include "receiver.h"
#include "vfo.h"
#include "button_text.h"
+#include "actions.h"
#include "gpio.h"
#include "i2c.h"
-static GtkWidget *parent_window=NULL;
-
-static GtkWidget *dialog=NULL;
-
-static GtkWidget *b_af_gain_rx1;
-static GtkWidget *b_af_gain_rx2;
-static GtkWidget *b_agc_gain_rx1;
-static GtkWidget *b_agc_gain_rx2;
-static GtkWidget *b_attenuation;
-static GtkWidget *b_mic_gain;
-static GtkWidget *b_drive;
-static GtkWidget *b_tune_drive;
-static GtkWidget *b_rit_rx1;
-static GtkWidget *b_rit_rx2;
-static GtkWidget *b_xit;
-static GtkWidget *b_cw_speed;
-static GtkWidget *b_cw_frequency;
-static GtkWidget *b_panadapter_high;
-static GtkWidget *b_panadapter_low;
-static GtkWidget *b_squelch;
-static GtkWidget *b_compression;
-
-static GtkWidget *b_top_af_gain_rx1;
-static GtkWidget *b_top_af_gain_rx2;
-static GtkWidget *b_top_agc_gain_rx1;
-static GtkWidget *b_top_agc_gain_rx2;
-static GtkWidget *b_top_attenuation;
-static GtkWidget *b_top_mic_gain;
-static GtkWidget *b_top_drive;
-static GtkWidget *b_top_tune_drive;
-static GtkWidget *b_top_rit_rx1;
-static GtkWidget *b_top_rit_rx2;
-static GtkWidget *b_top_xit;
-static GtkWidget *b_top_cw_speed;
-static GtkWidget *b_top_cw_frequency;
-static GtkWidget *b_top_panadapter_high;
-static GtkWidget *b_top_panadapter_low;
-static GtkWidget *b_top_squelch;
-static GtkWidget *b_top_compression;
-
-enum {
- ENC2,
- ENC2_TOP,
- ENC2_SW,
- ENC3,
- ENC3_TOP,
- ENC3_SW,
- ENC4,
- ENC4_TOP,
- ENC4_SW,
- ENC5,
- ENC5_TOP,
- ENC5_SW,
-};
-
typedef struct _choice {
int id;
int action;
GtkWidget *button;
} CHOICE;
-static int encoder;
+static GtkWidget *parent_window=NULL;
+
+static GtkWidget *dialog=NULL;
static void cleanup() {
if(dialog!=NULL) {
return FALSE;
}
-static void enc_select_cb(GtkWidget *widget,gpointer data) {
+static void encoder_bottom_select_cb(GtkWidget *widget,gpointer data) {
CHOICE *choice=(CHOICE *)data;
- switch(choice->id) {
- case ENC2:
- e2_encoder_action=choice->action;
- break;
- case ENC2_TOP:
- e2_top_encoder_action=choice->action;
- break;
- case ENC3:
- e3_encoder_action=choice->action;
- break;
- case ENC3_TOP:
- e3_top_encoder_action=choice->action;
- break;
- case ENC4:
- e4_encoder_action=choice->action;
- break;
- case ENC4_TOP:
- e4_top_encoder_action=choice->action;
- break;
- case ENC5:
- e5_encoder_action=choice->action;
- break;
- case ENC5_TOP:
- e5_top_encoder_action=choice->action;
- break;
- }
+ encoders[choice->id].bottom_encoder_function=choice->action;
+ gtk_button_set_label(GTK_BUTTON(choice->button),encoder_string[choice->action]);
+}
+
+static void encoder_top_select_cb(GtkWidget *widget,gpointer data) {
+ CHOICE *choice=(CHOICE *)data;
+ encoders[choice->id].top_encoder_function=choice->action;
gtk_button_set_label(GTK_BUTTON(choice->button),encoder_string[choice->action]);
}
-static gboolean enc_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
- int enc=GPOINTER_TO_INT(data);
+static void encoder_switch_select_cb(GtkWidget *widget,gpointer data) {
+ CHOICE *choice=(CHOICE *)data;
+ encoders[choice->id].switch_function=choice->action;
+ gtk_button_set_label(GTK_BUTTON(choice->button),sw_string[choice->action]);
+}
+
+static gboolean encoder_bottom_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
+ int encoder=GPOINTER_TO_INT(data);
int i;
GtkWidget *menu=gtk_menu_new();
for(i=0;i<ENCODER_ACTIONS;i++) {
GtkWidget *menu_item=gtk_menu_item_new_with_label(encoder_string[i]);
CHOICE *choice=g_new0(CHOICE,1);
- choice->id=enc;
+ choice->id=encoder;
choice->action=i;
choice->button=widget;
- g_signal_connect(menu_item,"activate",G_CALLBACK(enc_select_cb),choice);
+ g_signal_connect(menu_item,"activate",G_CALLBACK(encoder_bottom_select_cb),choice);
gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
}
gtk_widget_show_all(menu);
#else
gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,0,gtk_get_current_event_time());
#endif
-
return TRUE;
}
-static void sw_select_cb(GtkWidget *widget,gpointer data) {
- CHOICE *choice=(CHOICE *)data;
- switch(choice->id) {
- case ENC2_SW:
- e2_sw_action=choice->action;
- break;
- case ENC3_SW:
- e3_sw_action=choice->action;
- break;
- case ENC4_SW:
- e4_sw_action=choice->action;
- break;
- case ENC5_SW:
- e5_sw_action=choice->action;
- break;
+static gboolean encoder_top_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
+ int encoder=GPOINTER_TO_INT(data);
+ int i;
+
+ GtkWidget *menu=gtk_menu_new();
+ for(i=0;i<ENCODER_ACTIONS;i++) {
+ GtkWidget *menu_item=gtk_menu_item_new_with_label(encoder_string[i]);
+ CHOICE *choice=g_new0(CHOICE,1);
+ choice->id=encoder;
+ choice->action=i;
+ choice->button=widget;
+ g_signal_connect(menu_item,"activate",G_CALLBACK(encoder_top_select_cb),choice);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
}
- gtk_button_set_label(GTK_BUTTON(choice->button),sw_string[choice->action]);
+ gtk_widget_show_all(menu);
+#if GTK_CHECK_VERSION(3,22,0)
+ gtk_menu_popup_at_pointer(GTK_MENU(menu),(GdkEvent *)event);
+// the following line of code is to work around the problem of the popup menu not having scroll bars.
+ gtk_menu_reposition(GTK_MENU(menu));
+#else
+ gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,0,gtk_get_current_event_time());
+#endif
+ return TRUE;
}
-static gboolean sw_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
- int sw=GPOINTER_TO_INT(data);
+static gboolean encoder_switch_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
+ int encoder=GPOINTER_TO_INT(data);
int i;
GtkWidget *menu=gtk_menu_new();
for(i=0;i<SWITCH_ACTIONS;i++) {
GtkWidget *menu_item=gtk_menu_item_new_with_label(sw_string[i]);
CHOICE *choice=g_new0(CHOICE,1);
- choice->id=sw;
+ choice->id=encoder;
choice->action=i;
choice->button=widget;
- g_signal_connect(menu_item,"activate",G_CALLBACK(sw_select_cb),choice);
+ g_signal_connect(menu_item,"activate",G_CALLBACK(encoder_switch_select_cb),choice);
gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
}
gtk_widget_show_all(menu);
#else
gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,0,gtk_get_current_event_time());
#endif
-
return TRUE;
}
-GtkWidget* getRadioButton(int action) {
- GtkWidget* button;
- switch(action) {
- case ENCODER_AF_GAIN_RX1:
- button=b_af_gain_rx1;
- break;
- case ENCODER_AF_GAIN_RX2:
- button=b_af_gain_rx2;
- break;
- case ENCODER_AGC_GAIN_RX1:
- button=b_agc_gain_rx1;
- break;
- case ENCODER_AGC_GAIN_RX2:
- button=b_agc_gain_rx2;
- break;
- case ENCODER_ATTENUATION:
- button=b_attenuation;
- break;
- case ENCODER_MIC_GAIN:
- button=b_mic_gain;
- break;
- case ENCODER_DRIVE:
- button=b_drive;
- break;
- case ENCODER_TUNE_DRIVE:
- button=b_tune_drive;
- break;
- case ENCODER_RIT_RX1:
- button=b_rit_rx1;
- break;
- case ENCODER_RIT_RX2:
- button=b_rit_rx2;
- break;
- case ENCODER_XIT:
- button=b_xit;
- break;
- case ENCODER_CW_SPEED:
- button=b_cw_speed;
- break;
- case ENCODER_CW_FREQUENCY:
- button=b_cw_frequency;
- break;
- case ENCODER_PANADAPTER_HIGH:
- button=b_panadapter_high;
- break;
- case ENCODER_PANADAPTER_LOW:
- button=b_panadapter_low;
- break;
- case ENCODER_SQUELCH:
- button=b_squelch;
- break;
- case ENCODER_COMP:
- button=b_compression;
- break;
- }
- return button;
-}
-
-GtkWidget* getTopRadioButton(int action) {
- GtkWidget* button;
- switch(action) {
- case ENCODER_AF_GAIN_RX1:
- button=b_top_af_gain_rx1;
- break;
- case ENCODER_AF_GAIN_RX2:
- button=b_top_af_gain_rx2;
- break;
- case ENCODER_AGC_GAIN_RX1:
- button=b_top_agc_gain_rx1;
- break;
- case ENCODER_AGC_GAIN_RX2:
- button=b_top_agc_gain_rx2;
- break;
- case ENCODER_ATTENUATION:
- button=b_top_attenuation;
- break;
- case ENCODER_MIC_GAIN:
- button=b_top_mic_gain;
- break;
- case ENCODER_DRIVE:
- button=b_top_drive;
- break;
-/*
- case ENCODER_TUNE_DRIVE:
- button=b_top_tune_drive;
- break;
-*/
- case ENCODER_RIT_RX1:
- button=b_top_rit_rx1;
- break;
- case ENCODER_RIT_RX2:
- button=b_top_rit_rx2;
- break;
- case ENCODER_XIT:
- button=b_top_xit;
- break;
- case ENCODER_CW_SPEED:
- button=b_top_cw_speed;
- break;
- case ENCODER_CW_FREQUENCY:
- button=b_top_cw_frequency;
- break;
- case ENCODER_PANADAPTER_HIGH:
- button=b_top_panadapter_high;
- break;
- case ENCODER_PANADAPTER_LOW:
- button=b_top_panadapter_low;
- break;
- case ENCODER_SQUELCH:
- button=b_top_squelch;
- break;
- case ENCODER_COMP:
- button=b_top_compression;
- break;
- }
- return button;
-}
-
-static gboolean select_cb (GtkWidget *widget, gpointer data) {
- GtkWidget *button;
- int action;
-
- switch(encoder) {
- case 2:
- action=e2_encoder_action;
- break;
- case 3:
- action=e3_encoder_action;
- break;
- case 4:
- action=e4_encoder_action;
- break;
- case 5:
- action=e5_encoder_action;
- break;
- }
- button=getRadioButton(action);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-}
-
-static gboolean top_select_cb (GtkWidget *widget, gpointer data) {
- GtkWidget *button;
- int action;
-
- switch(encoder) {
- case 2:
- action=e2_top_encoder_action;
- break;
- case 3:
- action=e3_top_encoder_action;
- break;
- case 4:
- action=e4_top_encoder_action;
- break;
- case 5:
- action=e5_top_encoder_action;
- break;
- }
- button=getTopRadioButton(action);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-}
-
-void encoder_select(int pos) {
- int action;
- GtkWidget *button;
- switch(encoder) {
- case 2:
- if(pos>0) {
- e2_encoder_action--;
- if(e2_encoder_action<0) {
- e2_encoder_action=ENCODER_ACTIONS-1;
- }
- } if(pos<0) {
- e2_encoder_action++;
- if(e2_encoder_action>=ENCODER_ACTIONS) {
- e2_encoder_action=0;
- }
- }
- action=e2_encoder_action;
- break;
- case 3:
- if(pos>0) {
- e3_encoder_action--;
- if(e3_encoder_action<0) {
- e3_encoder_action=ENCODER_ACTIONS-1;
- }
- } if(pos<0) {
- e3_encoder_action++;
- if(e3_encoder_action>=ENCODER_ACTIONS) {
- e3_encoder_action=0;
- }
- }
- action=e3_encoder_action;
- break;
- case 4:
- if(pos>0) {
- e4_encoder_action--;
- if(e4_encoder_action<0) {
- e4_encoder_action=ENCODER_ACTIONS-1;
- }
- } if(pos<0) {
- e4_encoder_action++;
- if(e4_encoder_action>=ENCODER_ACTIONS) {
- e4_encoder_action=0;
- }
- }
- action=e4_encoder_action;
- break;
- }
-
- button=getRadioButton(action);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-
-}
-
-void top_encoder_select(int pos) {
- int action;
- GtkWidget *button;
- switch(encoder) {
- case 2:
- if(pos>0) {
- e2_top_encoder_action--;
- if(e2_top_encoder_action<0) {
- e2_top_encoder_action=ENCODER_ACTIONS-1;
- }
- } if(pos<0) {
- e2_top_encoder_action++;
- if(e2_top_encoder_action>=ENCODER_ACTIONS) {
- e2_top_encoder_action=0;
- }
- }
- action=e2_top_encoder_action;
- break;
- case 3:
- if(pos>0) {
- e3_top_encoder_action--;
- if(e3_top_encoder_action<0) {
- e3_top_encoder_action=ENCODER_ACTIONS-1;
- }
- } if(pos<0) {
- e3_top_encoder_action++;
- if(e3_top_encoder_action>=ENCODER_ACTIONS) {
- e3_top_encoder_action=0;
- }
- }
- action=e3_top_encoder_action;
- break;
- case 4:
- if(pos>0) {
- e4_top_encoder_action--;
- if(e4_top_encoder_action<0) {
- e4_top_encoder_action=ENCODER_ACTIONS-1;
- }
- } if(pos<0) {
- e4_top_encoder_action++;
- if(e4_top_encoder_action>=ENCODER_ACTIONS) {
- e4_top_encoder_action=0;
- }
- }
- action=e4_top_encoder_action;
- break;
- case 5:
- if(pos>0) {
- e5_top_encoder_action--;
- if(e5_top_encoder_action<0) {
- e5_top_encoder_action=ENCODER_ACTIONS-1;
- }
- } if(pos<0) {
- e5_top_encoder_action++;
- if(e5_top_encoder_action>=ENCODER_ACTIONS) {
- e5_top_encoder_action=0;
- }
- }
- action=e5_top_encoder_action;
- break;
- }
-
- button=getTopRadioButton(action);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-
-}
-
- static gboolean action_select_cb (GtkWidget *widget, gpointer data) {
- int action=GPOINTER_TO_INT(data);
- switch(encoder) {
- case 2:
- e2_encoder_action=action;
- break;
- case 3:
- e3_encoder_action=action;
- break;
- case 4:
- e4_encoder_action=action;
- break;
- case 5:
- e5_encoder_action=action;
- break;
- }
- }
-
- static gboolean top_action_select_cb (GtkWidget *widget, gpointer data) {
- int action=GPOINTER_TO_INT(data);
- switch(encoder) {
- case 2:
- e2_top_encoder_action=action;
- break;
- case 3:
- e3_top_encoder_action=action;
- break;
- case 4:
- e4_top_encoder_action=action;
- break;
- case 5:
- e5_top_encoder_action=action;
- break;
- }
- }
-
- static gboolean enc2_cb(GtkWidget *widget, gpointer data) {
- int i=gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- e2_encoder_action=i;
- return TRUE;
- }
-
- static gboolean enc2_sw_cb(GtkWidget *widget, gpointer data) {
- int i=gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- e2_sw_action=i;
- return TRUE;
- }
-
- static gboolean enc3_cb(GtkWidget *widget, gpointer data) {
- int i=gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- e3_encoder_action=i;
- return TRUE;
- }
-
- static gboolean enc3_sw_cb(GtkWidget *widget, gpointer data) {
- int i=gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- e3_sw_action=i;
- return TRUE;
- }
-
- static gboolean enc4_cb(GtkWidget *widget, gpointer data) {
- int i=gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- e4_encoder_action=i;
- return TRUE;
- }
-
- static gboolean enc4_sw_cb(GtkWidget *widget, gpointer data) {
- int i=gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- e4_sw_action=i;
- return TRUE;
- }
-
- static gboolean enc2_top_cb(GtkWidget *widget, gpointer data) {
- int i=gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- e2_top_encoder_action=i;
- return TRUE;
- }
-
- static gboolean enc3_top_cb(GtkWidget *widget, gpointer data) {
- int i=gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- e3_top_encoder_action=i;
- return TRUE;
- }
-
- static gboolean enc4_top_cb(GtkWidget *widget, gpointer data) {
- int i=gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- e4_top_encoder_action=i;
- return TRUE;
- }
-
- static gboolean enc5_cb(GtkWidget *widget, gpointer data) {
- int i=gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- e5_encoder_action=i;
- return TRUE;
- }
- static gboolean enc5_sw_cb(GtkWidget *widget, gpointer data) {
- int i=gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- e5_sw_action=i;
- return TRUE;
- }
-
-
- static gboolean enc5_top_cb(GtkWidget *widget, gpointer data) {
- int i=gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- e5_top_encoder_action=i;
- return TRUE;
- }
void encoder_menu(GtkWidget *parent) {
- int row=0;
- int col=0;
+ gint row=0;
+ gint col=0;
+ char label[32];
dialog=gtk_dialog_new();
- gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window));
+ gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent));
//gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE);
char title[32];
- sprintf(title,"piHPSDR - Encoder Actions:");
+ sprintf(title,"piHPSDR - Encoder Actions");
gtk_window_set_title(GTK_WINDOW(dialog),title);
g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL);
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
-
GtkWidget *grid=gtk_grid_new();
- gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE);
+ gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_column_spacing (GTK_GRID(grid),2);
- gtk_grid_set_row_spacing (GTK_GRID(grid),2);
GtkWidget *close_b=gtk_button_new_with_label("Close");
g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
row++;
col=0;
- GtkWidget *label_encoder=gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(label_encoder), "<b>Encoder</b>");
- gtk_grid_attach(GTK_GRID(grid),label_encoder,col,row,1,1);
- col++;
- if(controller==CONTROLLER2_V2) {
- GtkWidget *label_bottom=gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(label_bottom), "<b>Bottom</b>");
- gtk_grid_attach(GTK_GRID(grid),label_bottom,col,row,1,1);
- col++;
- GtkWidget *label_top=gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(label_top), "<b>Top</b>");
- gtk_grid_attach(GTK_GRID(grid),label_top,col,row,1,1);
- col++;
- } else {
- GtkWidget *label_bottom=gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(label_bottom), "<b>Encoder</b>");
- gtk_grid_attach(GTK_GRID(grid),label_bottom,col,row,1,1);
- col++;
- }
- GtkWidget *label_switch=gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(label_switch), "<b>Switch</b>");
- gtk_grid_attach(GTK_GRID(grid),label_switch,col,row,1,1);
- col++;
- row++;
- col=0;
-
- GtkWidget *enc2_title=gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(enc2_title), "<b>ENC2: </b>");
- gtk_grid_attach(GTK_GRID(grid),enc2_title,col,row,1,1);
- col++;
-
- GtkWidget *enc2=gtk_button_new_with_label(encoder_string[e2_encoder_action]);
- gtk_grid_attach(GTK_GRID(grid),enc2,col,row,1,1);
- g_signal_connect(enc2,"button_press_event",G_CALLBACK(enc_cb),GINT_TO_POINTER(ENC2));
- col++;
-
- if(controller==CONTROLLER2_V2) {
- GtkWidget *enc2_top=gtk_button_new_with_label(encoder_string[e2_top_encoder_action]);
- gtk_grid_attach(GTK_GRID(grid),enc2_top,col,row,1,1);
- g_signal_connect(enc2_top,"button_press_event",G_CALLBACK(enc_cb),GINT_TO_POINTER(ENC2_TOP));
- col++;
+ gint max_encoders=MAX_ENCODERS;
+ switch(controller) {
+ case NO_CONTROLLER:
+ max_encoders=0;
+ break;
+ case CONTROLLER1:
+ max_encoders=4;
+ break;
+ case CONTROLLER2_V1:
+ max_encoders=5;
+ break;
+ case CONTROLLER2_V2:
+ max_encoders=5;
+ break;
}
- GtkWidget *enc2_sw=gtk_button_new_with_label(sw_string[e2_sw_action]);
- gtk_grid_attach(GTK_GRID(grid),enc2_sw,col,row,1,1);
- g_signal_connect(enc2_sw,"button_press_event",G_CALLBACK(sw_cb),GINT_TO_POINTER(ENC2_SW));
-
- row++;
- col=0;
-
- GtkWidget *enc3_title=gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(enc3_title), "<b>ENC3: </b>");
- gtk_grid_attach(GTK_GRID(grid),enc3_title,col,row,1,1);
- col++;
-
- GtkWidget *enc3=gtk_button_new_with_label(encoder_string[e3_encoder_action]);
- gtk_grid_attach(GTK_GRID(grid),enc3,col,row,1,1);
- g_signal_connect(enc3,"button_press_event",G_CALLBACK(enc_cb),GINT_TO_POINTER(ENC3));
+ GtkWidget *widget=gtk_label_new("");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
col++;
-
- if(controller==CONTROLLER2_V2) {
- GtkWidget *enc3_top=gtk_button_new_with_label(encoder_string[e3_top_encoder_action]);
- gtk_grid_attach(GTK_GRID(grid),enc3_top,col,row,1,1);
- g_signal_connect(enc3_top,"button_press_event",G_CALLBACK(enc_cb),GINT_TO_POINTER(ENC3_TOP));
- col++;
- }
-
- GtkWidget *enc3_sw=gtk_button_new_with_label(sw_string[e3_sw_action]);
- gtk_grid_attach(GTK_GRID(grid),enc3_sw,col,row,1,1);
- g_signal_connect(enc3_sw,"button_press_event",G_CALLBACK(sw_cb),GINT_TO_POINTER(ENC3_SW));
-
- row++;
- col=0;
- GtkWidget *enc4_title=gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(enc4_title), "<b>ENC4: </b>");
- gtk_grid_attach(GTK_GRID(grid),enc4_title,col,row,1,1);
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), controller==CONTROLLER2_V2?"<b>Bottom Encoder</b>":"<b>Encoder</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
col++;
- GtkWidget *enc4=gtk_button_new_with_label(encoder_string[e4_encoder_action]);
- gtk_grid_attach(GTK_GRID(grid),enc4,col,row,1,1);
- g_signal_connect(enc4,"button_press_event",G_CALLBACK(enc_cb),GINT_TO_POINTER(ENC4));
- col++;
-
if(controller==CONTROLLER2_V2) {
- GtkWidget *enc4_top=gtk_button_new_with_label(encoder_string[e4_top_encoder_action]);
- gtk_grid_attach(GTK_GRID(grid),enc4_top,col,row,1,1);
- g_signal_connect(enc4_top,"button_press_event",G_CALLBACK(enc_cb),GINT_TO_POINTER(ENC4_TOP));
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<b>Top Encoder</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
col++;
}
- GtkWidget *enc4_sw=gtk_button_new_with_label(sw_string[e4_sw_action]);
- gtk_grid_attach(GTK_GRID(grid),enc4_sw,col,row,1,1);
- g_signal_connect(enc4_sw,"button_press_event",G_CALLBACK(sw_cb),GINT_TO_POINTER(ENC4_SW));
+ widget=gtk_label_new(NULL);
+ gtk_label_set_markup (GTK_LABEL(widget), "<b>Switch</b>");
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
row++;
col=0;
- if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
- GtkWidget *enc5_title=gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(enc5_title), "<b>ENC5: </b>");
- gtk_grid_attach(GTK_GRID(grid),enc5_title,col,row,1,1);
+ for(int i=0;i<max_encoders;i++) {
+ widget=gtk_label_new(NULL);
+ g_sprintf(label,"<b>%d</b>",i);
+ gtk_label_set_markup (GTK_LABEL(widget), label);
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
col++;
- GtkWidget *enc5=gtk_button_new_with_label(encoder_string[e5_encoder_action]);
- gtk_grid_attach(GTK_GRID(grid),enc5,col,row,1,1);
- g_signal_connect(enc5,"button_press_event",G_CALLBACK(enc_cb),GINT_TO_POINTER(ENC5));
+ if(i==(max_encoders-1)) {
+ widget=gtk_label_new(NULL);
+ g_sprintf(label,"<b>%s</b>",encoder_string[encoders[i].bottom_encoder_function]);
+ gtk_label_set_markup (GTK_LABEL(widget), label);
+ } else {
+ widget=gtk_button_new_with_label(encoder_string[encoders[i].bottom_encoder_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(encoder_bottom_cb),GINT_TO_POINTER(i));
+ }
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
col++;
-
+
if(controller==CONTROLLER2_V2) {
- GtkWidget *enc5_top=gtk_button_new_with_label(encoder_string[e5_top_encoder_action]);
- gtk_grid_attach(GTK_GRID(grid),enc5_top,col,row,1,1);
- g_signal_connect(enc5_top,"button_press_event",G_CALLBACK(enc_cb),GINT_TO_POINTER(ENC5_TOP));
+ widget=gtk_button_new_with_label(encoder_string[encoders[i].top_encoder_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(encoder_top_cb),GINT_TO_POINTER(i));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
col++;
}
- GtkWidget *enc5_sw=gtk_button_new_with_label(sw_string[e5_sw_action]);
- gtk_grid_attach(GTK_GRID(grid),enc5_sw,col,row,1,1);
- g_signal_connect(enc5_sw,"button_press_event",G_CALLBACK(sw_cb),GINT_TO_POINTER(ENC5_SW));
+ if(i!=(max_encoders-1)) {
+ widget=gtk_button_new_with_label(sw_string[encoders[i].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(encoder_switch_cb),GINT_TO_POINTER(i));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ }
+
+ row++;
+ col=0;
}
gtk_container_add(GTK_CONTAINER(content),grid);
// - band_minus(int id) // Move VFO #id to next lower band
// - ctun_update(int id, int state) // set CTUN state of VFO #id
// - set_split(int state) // Set split mode to state
+// - num_pad(int val) // enter VFO frequency
+// - update_vfo_step(int direction) // cycle throught VFO step sizes
//
void set_frequency(int v,long long f) {
}
}
+void num_pad(int val) {
+ RECEIVER *rx=active_receiver;
+ if(!vfo[rx->id].entering_frequency) {
+ vfo[rx->id].entered_frequency=0;
+ vfo[rx->id].entering_frequency=TRUE;
+ }
+ switch(val) {
+ case -1: // clear
+ vfo[rx->id].entered_frequency=0;
+ vfo[rx->id].entering_frequency=FALSE;
+ break;
+ case -2: // enter
+ if(vfo[rx->id].entered_frequency!=0) {
+ vfo[rx->id].frequency=vfo[rx->id].entered_frequency;
+ if(vfo[rx->id].ctun) {
+ vfo[rx->id].ctun=FALSE;
+ vfo[rx->id].offset=0;
+ vfo[rx->id].ctun_frequency=vfo[rx->id].frequency;
+ }
+ }
+ vfo[rx->id].entering_frequency=FALSE;
+ break;
+ default:
+ vfo[rx->id].entered_frequency=(vfo[rx->id].entered_frequency*10)+val;
+ break;
+ }
+ vfo_update();
+}
+
+void update_vfo_step(int direction) {
+ int i=0;
+ while(steps[i]!=step && steps[i]!=0) {
+ i++;
+ }
+
+ if(steps[i]!=0) {
+ // current step size is in slot #i.
+ if(direction>0) {
+ // move to next slot (if it exists)
+ i++;
+ if(steps[i]!=0) {
+ step=steps[i];
+ }
+ } else {
+ // move to previous slot (if it exists)
+ i--;
+ if(i>=0) {
+ step=steps[i];
+ }
+ }
+ }
+ vfo_update();
+}
+
//
// Functions to be invoked through the GTK idle queue,
// still in use
extern void ctun_update(int id,int state);
extern void band_plus(int id);
extern void band_minus(int id);
+extern void num_pad(int num);
+extern void update_vfo_step(int direction);
/* Copyright (C)
-* 2015 - John Melton, G0ORX/N6LYT
-*
+* 2020 - 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
*
*/
+// Rewrite to use gpiod rather than wiringPi
+// Note that all pin numbers are now the Broadcom GPIO
+
+
#include <gtk/gtk.h>
#include <stdio.h>
#include <fcntl.h>
#include <poll.h>
#include <sched.h>
-#include <wiringPi.h>
-#include <semaphore.h>
+
+#ifdef GPIO
+#include <gpiod.h>
+#include <linux/i2c-dev.h>
+#include <i2c/smbus.h>
+#include <sys/ioctl.h>
+#endif
#include "band.h"
#include "channel.h"
#include "filter.h"
#include "bandstack.h"
#include "toolbar.h"
-#include "gpio.h"
#include "radio.h"
#include "toolbar.h"
#include "main.h"
#include "new_menu.h"
#include "encoder_menu.h"
#include "diversity_menu.h"
+#include "actions.h"
#include "gpio.h"
#include "i2c.h"
#include "ext.h"
#include "sliders.h"
#include "new_protocol.h"
+#include "zoompan.h"
#ifdef LOCALCW
#include "iambic.h"
-#endif
-#include "zoompan.h"
-
-// debounce settle time in ms
-#define DEFAULT_SETTLE_TIME 50
-
-int settle_time=DEFAULT_SETTLE_TIME;
-static gint release_timer=-1;
-
-int controller;
-
-int I2C_INTERRUPT=16;
-
-// uses wiringpi pin numbers
-int ENABLE_VFO_ENCODER;
-int ENABLE_VFO_PULLUP;
-int VFO_ENCODER_A;
-int VFO_ENCODER_B;
-int ENABLE_E2_ENCODER;
-int ENABLE_E2_PULLUP;
-int E2_ENCODER_A;
-int E2_ENCODER_B;
-int ENABLE_E2_TOP_ENCODER;
-int E2_TOP_ENCODER_A;
-int E2_TOP_ENCODER_B;
-int E2_FUNCTION;
-int ENABLE_E3_ENCODER;
-int ENABLE_E3_PULLUP;
-int E3_ENCODER_A;
-int E3_ENCODER_B;
-int ENABLE_E3_TOP_ENCODER;
-int E3_TOP_ENCODER_A;
-int E3_TOP_ENCODER_B;
-int E3_FUNCTION;
-int ENABLE_E4_ENCODER;
-int ENABLE_E4_PULLUP;
-int E4_ENCODER_A;
-int E4_ENCODER_B;
-int ENABLE_E4_TOP_ENCODER;
-int E4_TOP_ENCODER_A;
-int E4_TOP_ENCODER_B;
-int E4_FUNCTION;
-int ENABLE_E5_ENCODER;
-int ENABLE_E5_PULLUP;
-int E5_ENCODER_A;
-int E5_ENCODER_B;
-int ENABLE_E5_TOP_ENCODER;
-int E5_TOP_ENCODER_A;
-int E5_TOP_ENCODER_B;
-int E5_FUNCTION;
-
-int ENABLE_S1_BUTTON;
-int S1_BUTTON;
-int ENABLE_S2_BUTTON;
-int S2_BUTTON;
-int ENABLE_S3_BUTTON;
-int S3_BUTTON;
-int ENABLE_S4_BUTTON;
-int S4_BUTTON;
-int ENABLE_S5_BUTTON;
-int S5_BUTTON;
-int ENABLE_S6_BUTTON;
-int S6_BUTTON;
-int ENABLE_MOX_BUTTON;
-int MOX_BUTTON;
-int ENABLE_FUNCTION_BUTTON;
-int FUNCTION_BUTTON;
-#ifdef LOCALCW
//
-// WiringPi pins #12, 13, 14 are not used
+// Broadcom pins #9, 10, 11 are not used
// by Controller1 and Controller2_V1
-// (and keep #8,9 reserved for I2C extensions)
+// (and keep #2,3 reserved for I2C extensions)
//
-int CWL_BUTTON=13;
-int CWR_BUTTON=14;
-int SIDETONE_GPIO=12;
+int CWL_BUTTON=9;
+int CWR_BUTTON=11;
+int SIDETONE_GPIO=10;
int ENABLE_GPIO_SIDETONE=0;
int ENABLE_CW_BUTTONS=1;
int CW_ACTIVE_LOW=1;
#ifdef PTT
int ENABLE_PTT_GPIO=1;
-int PTT_GPIO=15;
+int PTT_GPIO=14;
int PTT_ACTIVE_LOW=1;
#endif
-int vfoEncoderPos;
-int vfoFunction;
-
-int e2EncoderPos;
-int e2_sw_action;
-int e2_encoder_action;
-int e3EncoderPos;
-int e3_sw_action;
-int e3_encoder_action;
-int e4EncoderPos;
-int e4_sw_action;
-int e4_encoder_action;
-int e5EncoderPos;
-int e5_sw_action;
-int e5_encoder_action;
-
-int e2TopEncoderPos;
-int e2_top_encoder_action;
-int e3TopEncoderPos;
-int e3_top_encoder_action;
-int e4TopEncoderPos;
-int e4_top_encoder_action;
-int e5TopEncoderPos;
-int e5_top_encoder_action;
-
-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 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;
+enum {
+ TOP_ENCODER,
+ BOTTOM_ENCODER
+};
-char *encoder_string[ENCODER_ACTIONS] = {
- "NO ACTION",
- "AF GAIN",
- "AF GAIN RX1",
- "AF GAIN RX2",
- "AGC GAIN",
- "AGC GAIN RX1",
- "AGC GAIN RX2",
- "ATTENUATION/RX GAIN",
- "COMP",
- "CW FREQUENCY",
- "CW SPEED",
- "DIVERSITY GAIN",
- "DIVERSITY GAIN (coarse)",
- "DIVERSITY GAIN (fine)",
- "DIVERSITY PHASE",
- "DIVERSITY PHASE (coarse)",
- "DIVERSITY PHASE (fine)",
- "DRIVE",
- "IF SHIFT",
- "IF SHIFT RX1",
- "IF SHIFT RX2",
- "IF WIDTH",
- "IF WIDTH RX1",
- "IF WIDTH RX2",
- "MIC GAIN",
- "PAN",
- "PANADAPTER HIGH",
- "PANADAPTER LOW",
- "PANADAPTER STEP",
- "RF GAIN",
- "RF GAIN RX1",
- "RF GAIN RX2",
- "RIT",
- "RIT RX1",
- "RIT RX2",
- "SQUELCH",
- "SQUELCH RX1",
- "SQUELCH RX2",
- "TUNE DRIVE",
- "WATERFALL HIGH",
- "WATERFALL LOW",
- "XIT",
- "ZOOM",
+enum {
+ A,
+ B
};
-char *sw_string[SWITCH_ACTIONS] = {
- "",
- "A TO B",
- "A SWAP B",
- "AGC",
- "ANF",
- "B TO A",
- "BAND -",
- "BAND +",
- "BSTACK -",
- "BSTACK +",
- "CTUN",
- "DIV",
- "FILTER -",
- "FILTER +",
- "FUNCTION",
- "LOCK",
- "MENU BAND",
- "MENU BSTACK",
- "MENU DIV",
- "MENU FILTER",
- "MENU FREQUENCY",
- "MENU MEMORY",
- "MENU MODE",
- "MENU PS",
- "MODE -",
- "MODE +",
- "MOX",
- "MUTE",
- "NB",
- "NR",
- "PAN -",
- "PAN +",
- "PS",
- "RIT",
- "RIT CL",
- "SAT",
- "SNB",
- "SPLIT",
- "TUNE",
- "TWO TONE",
- "XIT",
- "XIT CL",
- "ZOOM -",
- "ZOOM +",
+// encoder state table
+#define R_START 0x0
+#define R_CW_FINAL 0x1
+#define R_CW_BEGIN 0x2
+#define R_CW_NEXT 0x3
+#define R_CCW_BEGIN 0x4
+#define R_CCW_FINAL 0x5
+#define R_CCW_NEXT 0x6
+
+#define DIR_NONE 0x0
+// Clockwise step.
+#define DIR_CW 0x10
+// Anti-clockwise step.
+#define DIR_CCW 0x20
+
+guchar encoder_state_table[7][4] = {
+ // R_START
+ {R_START, R_CW_BEGIN, R_CCW_BEGIN, R_START},
+ // R_CW_FINAL
+ {R_CW_NEXT, R_START, R_CW_FINAL, R_START | DIR_CW},
+ // R_CW_BEGIN
+ {R_CW_NEXT, R_CW_BEGIN, R_START, R_START},
+ // R_CW_NEXT
+ {R_CW_NEXT, R_CW_BEGIN, R_CW_FINAL, R_START},
+ // R_CCW_BEGIN
+ {R_CCW_NEXT, R_START, R_CCW_BEGIN, R_START},
+ // R_CCW_FINAL
+ {R_CCW_NEXT, R_CCW_FINAL, R_START, R_START | DIR_CCW},
+ // R_CCW_NEXT
+ {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};
-int *sw_action=NULL;
+#ifdef GPIO
+char *consumer="pihpsdr";
-static int mox_pressed(void *data) {
- if(running) sim_mox_cb(NULL,NULL);
- return 0;
-}
+char *gpio_device="/dev/gpiochip0";
-static int s1_pressed(void *data) {
- if(running) sim_s1_pressed_cb(NULL,NULL);
- return 0;
-}
+static struct gpiod_chip *chip=NULL;
+#endif
-static int s1_released(void *data) {
- if(running) sim_s1_released_cb(NULL,NULL);
- return 0;
-}
+static GMutex encoder_mutex;
+static GThread *monitor_thread_id;
+
+int I2C_INTERRUPT=15;
+
+#define MAX_LINES 32
+int monitor_lines[MAX_LINES];
+int lines=0;
+
+long settle_time=50; // ms
+
+// VFO Encoder is always last
+
+ENCODER encoders_no_controller[MAX_ENCODERS]={
+ {FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+ {FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+ {FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+ {FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+ {FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+ };
+
+ENCODER encoders_controller1[MAX_ENCODERS]={
+ {TRUE,TRUE,20,1,26,1,0,ENCODER_AF_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,25,MENU_BAND,0L},
+ {TRUE,TRUE,16,1,19,1,0,ENCODER_AGC_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,8,MENU_BANDSTACK,0L},
+ {TRUE,TRUE,4,1,21,1,0,ENCODER_DRIVE,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,7,MENU_MODE,0L},
+ {TRUE,TRUE,18,1,17,1,0,ENCODER_VFO,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+ {FALSE,TRUE,0,1,0,0,1,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+ };
+
+ENCODER encoders_controller2_v1[MAX_ENCODERS]={
+ {TRUE,TRUE,20,1,26,1,0,ENCODER_AF_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,22,MENU_BAND,0L},
+ {TRUE,TRUE,4,1,21,1,0,ENCODER_AGC_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,27,MENU_BANDSTACK,0L},
+ {TRUE,TRUE,16,1,19,1,0,ENCODER_IF_WIDTH,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,23,MENU_MODE,0L},
+ {TRUE,TRUE,25,1,8,1,0,ENCODER_RIT,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,24,MENU_FREQUENCY,0L},
+ {TRUE,TRUE,18,1,17,1,0,ENCODER_VFO,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+ };
+
+ENCODER encoders_controller2_v2[MAX_ENCODERS]={
+ {TRUE,TRUE,5,1,6,1,0,ENCODER_RF_GAIN,R_START,TRUE,TRUE,26,1,20,1,0,ENCODER_AF_GAIN,R_START,TRUE,TRUE,22,MENU_BAND,0L},
+ {TRUE,TRUE,9,1,7,1,0,ENCODER_ATTENUATION,R_START,TRUE,TRUE,21,1,4,1,0,ENCODER_AGC_GAIN,R_START,TRUE,TRUE,27,MENU_MODE,0L},
+ {TRUE,TRUE,11,1,10,1,0,ENCODER_IF_WIDTH,R_START,TRUE,TRUE,19,1,16,1,0,ENCODER_IF_SHIFT,R_START,TRUE,TRUE,23,MENU_FILTER,0L},
+ {TRUE,TRUE,13,1,12,1,0,ENCODER_XIT,R_START,TRUE,TRUE,8,1,25,1,0,ENCODER_RIT,R_START,TRUE,TRUE,24,MENU_FREQUENCY,0L},
+ {TRUE,TRUE,18,1,17,1,0,ENCODER_VFO,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+ };
+
+ENCODER *encoders=encoders_no_controller;
+
+SWITCH switches_no_controller[MAX_SWITCHES]={
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L}
+ };
+
+SWITCH switches_controller1[MAX_FUNCTIONS][MAX_SWITCHES]={
+ {{TRUE,TRUE,27,MOX,0L},
+ {TRUE,TRUE,13,MENU_BAND,0L},
+ {TRUE,TRUE,12,MENU_BANDSTACK,0L},
+ {TRUE,TRUE,6,MENU_MODE,0L},
+ {TRUE,TRUE,5,MENU_FILTER,0L},
+ {TRUE,TRUE,24,NR,0L},
+ {TRUE,TRUE,23,AGC,0L},
+ {TRUE,TRUE,22,FUNCTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L}},
+ {{TRUE,TRUE,27,MOX,0L},
+ {TRUE,TRUE,13,LOCK,0L},
+ {TRUE,TRUE,12,CTUN,0L},
+ {TRUE,TRUE,6,A_TO_B,0L},
+ {TRUE,TRUE,5,B_TO_A,0L},
+ {TRUE,TRUE,24,A_SWAP_B,0L},
+ {TRUE,TRUE,23,SPLIT,0L},
+ {TRUE,TRUE,22,FUNCTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L}},
+ {{TRUE,TRUE,27,MOX,0L},
+ {TRUE,TRUE,13,MENU_FREQUENCY,0L},
+ {TRUE,TRUE,12,MENU_MEMORY,0L},
+ {TRUE,TRUE,6,RIT,0L},
+ {TRUE,TRUE,5,RIT_PLUS,0L},
+ {TRUE,TRUE,24,RIT_MINUS,0L},
+ {TRUE,TRUE,23,RIT_CLEAR,0L},
+ {TRUE,TRUE,22,FUNCTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L}},
+ {{TRUE,TRUE,27,MOX,0L},
+ {TRUE,TRUE,13,MENU_FREQUENCY,0L},
+ {TRUE,TRUE,12,MENU_MEMORY,0L},
+ {TRUE,TRUE,6,XIT,0L},
+ {TRUE,TRUE,5,XIT_PLUS,0L},
+ {TRUE,TRUE,24,XIT_MINUS,0L},
+ {TRUE,TRUE,23,XIT_CLEAR,0L},
+ {TRUE,TRUE,22,FUNCTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L}},
+ {{TRUE,TRUE,27,MOX,0L},
+ {TRUE,TRUE,13,MENU_FREQUENCY,0L},
+ {TRUE,TRUE,12,SPLIT,0L},
+ {TRUE,TRUE,6,DUPLEX,0L},
+ {TRUE,TRUE,5,SAT,0L},
+ {TRUE,TRUE,24,RSAT,0L},
+ {TRUE,TRUE,23,NO_ACTION,0L},
+ {TRUE,TRUE,22,FUNCTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L}},
+ {{TRUE,TRUE,27,MOX,0L},
+ {TRUE,TRUE,13,TUNE,0L},
+ {TRUE,TRUE,12,TUNE_FULL,0L},
+ {TRUE,TRUE,6,TUNE_MEMORY,0L},
+ {TRUE,TRUE,5,MENU_BAND,0L},
+ {TRUE,TRUE,24,MENU_MODE,0L},
+ {TRUE,TRUE,23,MENU_FILTER,0L},
+ {TRUE,TRUE,22,FUNCTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L},
+ {FALSE,FALSE,0,NO_ACTION,0L}},
+
+ };
+
+SWITCH switches_controller2_v1[MAX_SWITCHES]={
+ {FALSE,FALSE,0,MOX,0L},
+ {FALSE,FALSE,0,TUNE,0L},
+ {FALSE,FALSE,0,PS,0L},
+ {FALSE,FALSE,0,TWO_TONE,0L},
+ {FALSE,FALSE,0,NR,0L},
+ {FALSE,FALSE,0,A_TO_B,0L},
+ {FALSE,FALSE,0,B_TO_A,0L},
+ {FALSE,FALSE,0,MODE_MINUS,0L},
+ {FALSE,FALSE,0,BAND_MINUS,0L},
+ {FALSE,FALSE,0,MODE_PLUS,0L},
+ {FALSE,FALSE,0,BAND_PLUS,0L},
+ {FALSE,FALSE,0,XIT,0L},
+ {FALSE,FALSE,0,NB,0L},
+ {FALSE,FALSE,0,SNB,0L},
+ {FALSE,FALSE,0,LOCK,0L},
+ {FALSE,FALSE,0,CTUN,0L}
+ };
+
+SWITCH switches_controller2_v2[MAX_SWITCHES]={
+ {FALSE,FALSE,0,MOX,0L},
+ {FALSE,FALSE,0,TUNE,0L},
+ {FALSE,FALSE,0,PS,0L},
+ {FALSE,FALSE,0,TWO_TONE,0L},
+ {FALSE,FALSE,0,NR,0L},
+ {FALSE,FALSE,0,A_TO_B,0L},
+ {FALSE,FALSE,0,B_TO_A,0L},
+ {FALSE,FALSE,0,MODE_MINUS,0L},
+ {FALSE,FALSE,0,BAND_MINUS,0L},
+ {FALSE,FALSE,0,MODE_PLUS,0L},
+ {FALSE,FALSE,0,BAND_PLUS,0L},
+ {FALSE,FALSE,0,XIT,0L},
+ {FALSE,FALSE,0,NB,0L},
+ {FALSE,FALSE,0,SNB,0L},
+ {FALSE,FALSE,0,LOCK,0L},
+ {FALSE,FALSE,0,CTUN,0L}
+ };
+
+SWITCH *switches=switches_controller1[0];
-static int s2_pressed(void *data) {
- if(running) sim_s2_pressed_cb(NULL,NULL);
- return 0;
-}
+static int running=0;
-static int s2_released(void *data) {
- if(running) sim_s2_released_cb(NULL,NULL);
- return 0;
-}
+static GThread *rotary_encoder_thread_id;
-static int s3_pressed(void *data) {
- if(running) sim_s3_pressed_cb(NULL,NULL);
- return 0;
-}
+static uint64_t epochMilli;
-static int s3_released(void *data) {
- if(running) sim_s3_released_cb(NULL,NULL);
- return 0;
-}
+static void initialiseEpoch() {
+ struct timespec ts ;
-static int s4_pressed(void *data) {
- if(running) sim_s4_pressed_cb(NULL,NULL);
- return 0;
+ clock_gettime (CLOCK_MONOTONIC_RAW, &ts) ;
+ epochMilli = (uint64_t)ts.tv_sec * (uint64_t)1000 + (uint64_t)(ts.tv_nsec / 1000000L) ;
}
-static int s4_released(void *data) {
- if(running) sim_s4_released_cb(NULL,NULL);
- return 0;
+static unsigned int millis () {
+ uint64_t now ;
+ struct timespec ts ;
+ clock_gettime (CLOCK_MONOTONIC_RAW, &ts) ;
+ now = (uint64_t)ts.tv_sec * (uint64_t)1000 + (uint64_t)(ts.tv_nsec / 1000000L) ;
+ return (uint32_t)(now - epochMilli) ;
}
-static int s5_pressed(void *data) {
- if(running) sim_s5_pressed_cb(NULL,NULL);
- return 0;
-}
+static gpointer rotary_encoder_thread(gpointer data) {
+ ENCODER_ACTION *a;
+ int i;
-static int s5_released(void *data) {
- if(running) sim_s5_released_cb(NULL,NULL);
- return 0;
+ usleep(250000);
+ g_print("%s\n",__FUNCTION__);
+ while(TRUE) {
+ g_mutex_lock(&encoder_mutex);
+ for(i=0;i<MAX_ENCODERS;i++) {
+ if(encoders[i].bottom_encoder_enabled && encoders[i].bottom_encoder_pos!=0) {
+ //g_print("%s: BOTTOM encoder %d pos=%d\n",__FUNCTION__,i,encoders[i].bottom_encoder_pos);
+ a=g_new(ENCODER_ACTION,1);
+ a->action=encoders[i].bottom_encoder_function;
+ a->mode=RELATIVE;
+ a->val=encoders[i].bottom_encoder_pos;
+ g_idle_add(encoder_action,a);
+ encoders[i].bottom_encoder_pos=0;
+ }
+ if(encoders[i].top_encoder_enabled && encoders[i].top_encoder_pos!=0) {
+ //g_print("%s: TOP encoder %d pos=%d\n",__FUNCTION__,i,encoders[i].top_encoder_pos);
+ a=g_new(ENCODER_ACTION,1);
+ a->action=encoders[i].top_encoder_function;
+ a->mode=RELATIVE;
+ a->val=encoders[i].top_encoder_pos;
+ g_idle_add(encoder_action,a);
+ encoders[i].top_encoder_pos=0;
+ }
+ }
+ g_mutex_unlock(&encoder_mutex);
+ usleep(100000); // sleep for 100ms
+ }
}
-static int s6_pressed(void *data) {
- if(running) sim_s6_pressed_cb(NULL,NULL);
+int process_function_switch(void *data) {
+ function++;
+ if(function>=MAX_FUNCTIONS) {
+ function=0;
+ }
+ switches=switches_controller1[function];
+ update_toolbar_labels();
return 0;
}
-static int s6_released(void *data) {
- if(running) sim_s6_released_cb(NULL,NULL);
- return 0;
-}
+#ifdef GPIO
+static unsigned long switch_debounce;
+
+static void process_encoder(int e,int l,int addr,int val) {
+ guchar pinstate;
+ //g_print("%s: encoder=%d level=%d addr=0x%02X val=%d\n",__FUNCTION__,e,l,addr,val);
+ g_mutex_lock(&encoder_mutex);
+ switch(l) {
+ case BOTTOM_ENCODER:
+ switch(addr) {
+ case A:
+ encoders[e].bottom_encoder_a_value=val;
+ pinstate=(encoders[e].bottom_encoder_b_value<<1) | encoders[e].bottom_encoder_a_value;
+ encoders[e].bottom_encoder_state=encoder_state_table[encoders[e].bottom_encoder_state&0xf][pinstate];
+ //g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].bottom_encoder_state);
+ switch(encoders[e].bottom_encoder_state&0x30) {
+ case DIR_NONE:
+ break;
+ case DIR_CW:
+ encoders[e].bottom_encoder_pos++;
+ break;
+ case DIR_CCW:
+ encoders[e].bottom_encoder_pos--;
+ break;
+ default:
+ break;
+ }
-static int function_pressed(void *data) {
- if(running) sim_function_cb(NULL,NULL);
- return 0;
+ //g_print("%s: %s BOTTOM pos=%d\n",__FUNCTION__,encoder_string[encoders[e].bottom_encoder_function],encoders[e].bottom_encoder_pos);
+ break;
+ case B:
+ encoders[e].bottom_encoder_b_value=val;
+ pinstate=(encoders[e].bottom_encoder_b_value<<1) | encoders[e].bottom_encoder_a_value;
+ encoders[e].bottom_encoder_state=encoder_state_table[encoders[e].bottom_encoder_state&0xf][pinstate];
+ //g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].bottom_encoder_state);
+ switch(encoders[e].bottom_encoder_state&0x30) {
+ case DIR_NONE:
+ break;
+ case DIR_CW:
+ encoders[e].bottom_encoder_pos++;
+ break;
+ case DIR_CCW:
+ encoders[e].bottom_encoder_pos--;
+ break;
+ default:
+ break;
+ }
+
+ //g_print("%s: %s BOTTOM pos=%d\n",__FUNCTION__,encoder_string[encoders[e].bottom_encoder_function],encoders[e].bottom_encoder_pos);
+
+ break;
+ }
+ break;
+ case TOP_ENCODER:
+ switch(addr) {
+ case A:
+ encoders[e].top_encoder_a_value=val;
+ pinstate=(encoders[e].top_encoder_b_value<<1) | encoders[e].top_encoder_a_value;
+ encoders[e].top_encoder_state=encoder_state_table[encoders[e].top_encoder_state&0xf][pinstate];
+ //g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].top_encoder_state);
+ switch(encoders[e].top_encoder_state&0x30) {
+ case DIR_NONE:
+ break;
+ case DIR_CW:
+ encoders[e].top_encoder_pos++;
+ break;
+ case DIR_CCW:
+ encoders[e].top_encoder_pos--;
+ break;
+ default:
+ break;
+ }
+ //g_print("%s: %s TOP pos=%d\n",__FUNCTION__,encoder_string[encoders[e].top_encoder_function],encoders[e].top_encoder_pos);
+ break;
+ case B:
+ encoders[e].top_encoder_b_value=val;
+ pinstate=(encoders[e].top_encoder_b_value<<1) | encoders[e].top_encoder_a_value;
+ encoders[e].top_encoder_state=encoder_state_table[encoders[e].top_encoder_state&0xf][pinstate];
+ //g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].top_encoder_state);
+ switch(encoders[e].top_encoder_state&0x30) {
+ case DIR_NONE:
+ break;
+ case DIR_CW:
+ encoders[e].top_encoder_pos++;
+ break;
+ case DIR_CCW:
+ encoders[e].top_encoder_pos--;
+ break;
+ default:
+ break;
+ }
+ //g_print("%s: %s TOP pos=%d\n",__FUNCTION__,encoder_string[encoders[e].top_encoder_function],encoders[e].top_encoder_pos);
+
+ break;
+ }
+ break;
+ }
+ g_mutex_unlock(&encoder_mutex);
}
-static int vfo_function_pressed(void *data) {
- RECEIVER *rx;
- if(receivers==2) {
- if(active_receiver==receiver[0]) {
- rx=receiver[1];
- } else {
- rx=receiver[0];
+static void process_edge(int offset,int value) {
+ gint i;
+ gint t;
+ gboolean found;
+
+ //g_print("%s: offset=%d value=%d\n",__FUNCTION__,offset,value);
+ found=FALSE;
+#ifdef LOCALCW
+ if(ENABLE_CW_BUTTONS) {
+ if(offset==CWL_BUTTON) {
+ keyer_event(1, CW_ACTIVE_LOW ? (value==PRESSED) : value);
+ found=TRUE;
+ } else if(offset==CWR_BUTTON) {
+ keyer_event(1, CW_ACTIVE_LOW ? (value==PRESSED) : value);
+ found=TRUE;
+ }
+ }
+ if(found) return;
+#endif
+ // check encoders
+ for(i=0;i<MAX_ENCODERS;i++) {
+ if(encoders[i].bottom_encoder_enabled && encoders[i].bottom_encoder_address_a==offset) {
+ //g_print("%s: found %d encoder %d bottom A\n",__FUNCTION__,offset,i);
+ process_encoder(i,BOTTOM_ENCODER,A,value);
+ found=TRUE;
+ break;
+ } else if(encoders[i].bottom_encoder_enabled && encoders[i].bottom_encoder_address_b==offset) {
+ //g_print("%s: found %d encoder %d bottom B\n",__FUNCTION__,offset,i);
+ process_encoder(i,BOTTOM_ENCODER,B,value);
+ found=TRUE;
+ break;
+ } else if(encoders[i].top_encoder_enabled && encoders[i].top_encoder_address_a==offset) {
+ //g_print("%s: found %d encoder %d top A\n",__FUNCTION__,offset,i);
+ process_encoder(i,TOP_ENCODER,A,value);
+ found=TRUE;
+ break;
+ } else if(encoders[i].top_encoder_enabled && encoders[i].top_encoder_address_b==offset) {
+ //g_print("%s: found %d encoder %d top B\n",__FUNCTION__,offset,i);
+ process_encoder(i,TOP_ENCODER,B,value);
+ found=TRUE;
+ break;
+ } else if(encoders[i].switch_enabled && encoders[i].switch_address==offset) {
+ //g_print("%s: found %d encoder %d switch\n",__FUNCTION__,offset,i);
+ SWITCH_ACTION *a=g_new(SWITCH_ACTION,1);
+ a->action=encoders[i].switch_function;
+ a->state=value;
+ g_idle_add(switch_action,a);
+ found=TRUE;
+ break;
}
- 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;
-}
+ if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
+ if(I2C_INTERRUPT==offset) {
+ if(value==PRESSED) {
+ i2c_interrupt();
+ }
+ found=TRUE;
+ }
+ }
-#ifdef PTT
-static int ptt_pressed(void *data) {
-g_print("ptt_pressed\n");
- if(can_transmit) g_idle_add(ext_mox_update,GINT_TO_POINTER(1));
- return 0;
-}
+ if(!found) {
+ for(i=0;i<MAX_SWITCHES;i++) {
+ if(switches[i].switch_enabled && switches[i].switch_address==offset) {
+ t=millis();
+ //g_print("%s: found %d switch %d value=%d t=%d\n",__FUNCTION__,offset,i,value,t);
+ found=TRUE;
+ if(t<switches[i].switch_debounce) {
+ return;
+ }
+g_print("%s: switches=%p function=%d (%s)\n",__FUNCTION__,switches,switches[i].switch_function,sw_string[switches[i].switch_function]);
+ switches[i].switch_debounce=t+settle_time;
+ SWITCH_ACTION *a=g_new(SWITCH_ACTION,1);
+ a->action=switches[i].switch_function;
+ a->state=value;
+ g_idle_add(switch_action,a);
+ break;
+ }
+ }
+ }
-static int ptt_released(void *data) {
-g_print("ptt_released\n");
- if(can_transmit) g_idle_add(ext_mox_update,GINT_TO_POINTER(0));
- return 0;
+
+ if(!found) {
+ g_print("%s: could not find %d\n",__FUNCTION__,offset);
+ }
}
-#endif
-static int e_function_pressed(void *data) {
- int action=GPOINTER_TO_INT(data);
-g_print("e_function_pressed: %d\n",action);
- switch(action) {
- case TUNE:
- if(can_transmit) g_idle_add(ext_tune_update,NULL);
- break;
- case MOX:
- if(can_transmit) g_idle_add(ext_mox_update,NULL);
- break;
- case PS:
-#ifdef PURESIGNAL
- if(can_transmit) g_idle_add(ext_ps_update,NULL);
-#endif
- break;
- case TWO_TONE:
- if(can_transmit) g_idle_add(ext_two_tone,NULL);
- break;
- case NR:
- g_idle_add(ext_nr_update,NULL);
- break;
- case NB:
- g_idle_add(ext_nb_update,NULL);
- break;
- case SNB:
- g_idle_add(ext_snb_update,NULL);
- break;
- case RIT:
- g_idle_add(ext_rit_update,NULL);
- break;
- case RIT_CLEAR:
- g_idle_add(ext_rit_clear,NULL);
- break;
- case XIT:
- if(can_transmit) g_idle_add(ext_xit_update,NULL);
- break;
- case XIT_CLEAR:
- if(can_transmit) g_idle_add(ext_xit_clear,NULL);
+static int interrupt_cb(int event_type, unsigned int line, const struct timespec *timeout, void* data) {
+ //g_print("%s: event=%d line=%d\n",__FUNCTION__,event_type,line);
+ switch(event_type) {
+ case GPIOD_CTXLESS_EVENT_CB_TIMEOUT:
+ // timeout - ignore
+ //g_print("%s: Ignore timeout\n",__FUNCTION__);
break;
- case BAND_PLUS:
- g_idle_add(ext_band_plus,NULL);
+ case GPIOD_CTXLESS_EVENT_CB_RISING_EDGE:
+ //g_print("%s: Ignore RISING EDGE\n",__FUNCTION__);
+ process_edge(line,RELEASED);
break;
- case BAND_MINUS:
- g_idle_add(ext_band_minus,NULL);
- break;
- case BANDSTACK_PLUS:
- g_idle_add(ext_bandstack_plus,NULL);
- break;
- case BANDSTACK_MINUS:
- g_idle_add(ext_bandstack_minus,NULL);
- break;
- case MODE_PLUS:
- g_idle_add(ext_mode_plus,NULL);
- break;
- case MODE_MINUS:
- g_idle_add(ext_mode_minus,NULL);
- break;
- case FILTER_PLUS:
- g_idle_add(ext_filter_plus,NULL);
- break;
- case FILTER_MINUS:
- g_idle_add(ext_filter_minus,NULL);
- break;
- case A_TO_B:
- g_idle_add(ext_vfo_a_to_b,NULL);
- break;
- case B_TO_A:
- g_idle_add(ext_vfo_b_to_a,NULL);
- break;
- case A_SWAP_B:
- g_idle_add(ext_vfo_a_swap_b,NULL);
- break;
- case LOCK:
- g_idle_add(ext_lock_update,NULL);
- break;
- case CTUN:
- g_idle_add(ext_ctun_update,NULL);
- break;
- case AGC:
- g_idle_add(ext_agc_update,NULL);
- break;
- case SPLIT:
- if(can_transmit) g_idle_add(ext_split_toggle,NULL);
- break;
- case DIVERSITY:
- g_idle_add(ext_diversity_update,GINT_TO_POINTER(0));
- break;
- case SAT:
- if(can_transmit) g_idle_add(ext_sat_update,NULL);
- break;
- case MENU_BAND:
- g_idle_add(ext_band_update,NULL);
- break;
- case MENU_BANDSTACK:
- g_idle_add(ext_bandstack_update,NULL);
- break;
- case MENU_MODE:
- g_idle_add(ext_mode_update,NULL);
- break;
- case MENU_FILTER:
- g_idle_add(ext_filter_update,NULL);
- break;
- case MENU_FREQUENCY:
- g_idle_add(ext_frequency_update,NULL);
- break;
- case MENU_MEMORY:
- g_idle_add(ext_memory_update,NULL);
- break;
- case MENU_DIVERSITY:
- g_idle_add(ext_diversity_update,GINT_TO_POINTER(1));
- break;
-#ifdef PURESIGNAL
- case MENU_PS:
- g_idle_add(ext_start_ps,NULL);
+ case GPIOD_CTXLESS_EVENT_CB_FALLING_EDGE:
+ //g_print("%s: Process FALLING EDGE\n",__FUNCTION__);
+ process_edge(line,PRESSED);
break;
+ }
+ return GPIOD_CTXLESS_EVENT_CB_RET_OK;
+}
#endif
- case FUNCTION:
- g_idle_add(ext_function_update,NULL);
- break;
- case MUTE:
- g_idle_add(ext_mute_update,NULL);
- break;
- case PAN_MINUS:
- g_idle_add(ext_pan_update,GINT_TO_POINTER(-100));
+
+void gpio_set_defaults(int ctrlr) {
+ int i;
+ g_print("%s: %d\n",__FUNCTION__,ctrlr);
+ switch(ctrlr) {
+ case NO_CONTROLLER:
+ encoders=encoders_no_controller;
+ switches=switches_controller1[0];
break;
- case PAN_PLUS:
- g_idle_add(ext_pan_update,GINT_TO_POINTER(100));
+ case CONTROLLER1:
+ encoders=encoders_controller1;
+ switches=switches_controller1[0];
break;
- case ZOOM_MINUS:
- g_idle_add(ext_zoom_update,GINT_TO_POINTER(-1));
+ case CONTROLLER2_V1:
+ encoders=encoders_controller2_v1;
+ switches=switches_controller2_v1;
break;
- case ZOOM_PLUS:
- g_idle_add(ext_zoom_update,GINT_TO_POINTER(1));
+ case CONTROLLER2_V2:
+ encoders=encoders_controller2_v2;
+ switches=switches_controller2_v2;
break;
}
- return 0;
}
-static unsigned long e2debounce=0;
+void gpio_restore_state() {
+ char* value;
+ char name[80];
-static void e2FunctionAlert() {
- int level=digitalRead(E2_FUNCTION);
- if(level==0) {
- if(running) g_idle_add(e_function_pressed,GINT_TO_POINTER(e2_sw_action));
- }
-}
+ loadProperties("gpio.props");
+
+ controller=NO_CONTROLLER;
+ value=getProperty("controller");
+ if(value) controller=atoi(value);
+ gpio_set_defaults(controller);
-static unsigned long e3debounce=0;
+ for(int i=0;i<MAX_ENCODERS;i++) {
+ sprintf(name,"encoders[%d].bottom_encoder_enabled",i);
+ value=getProperty(name);
+ if(value) encoders[i].bottom_encoder_enabled=atoi(value);
+ sprintf(name,"encoders[%d].bottom_encoder_pullup",i);
+ value=getProperty(name);
+ if(value) encoders[i].bottom_encoder_pullup=atoi(value);
+ sprintf(name,"encoders[%d].bottom_encoder_address_a",i);
+ value=getProperty(name);
+ if(value) encoders[i].bottom_encoder_address_a=atoi(value);
+ sprintf(name,"encoders[%d].bottom_encoder_address_b",i);
+ value=getProperty(name);
+ if(value) encoders[i].bottom_encoder_address_b=atoi(value);
+ sprintf(name,"encoders[%d].bottom_encoder_address_b",i);
+ value=getProperty(name);
+ sprintf(name,"encoders[%d].top_encoder_enabled",i);
+ value=getProperty(name);
+ if(value) encoders[i].top_encoder_enabled=atoi(value);
+ sprintf(name,"encoders[%d].top_encoder_pullup",i);
+ value=getProperty(name);
+ if(value) encoders[i].top_encoder_pullup=atoi(value);
+ sprintf(name,"encoders[%d].top_encoder_address_a",i);
+ value=getProperty(name);
+ if(value) encoders[i].top_encoder_address_a=atoi(value);
+ sprintf(name,"encoders[%d].top_encoder_address_b",i);
+ value=getProperty(name);
+ if(value) encoders[i].top_encoder_address_b=atoi(value);
+ sprintf(name,"encoders[%d].switch_enabled",i);
+ value=getProperty(name);
+ if(value) encoders[i].switch_enabled=atoi(value);
+ sprintf(name,"encoders[%d].switch_pullup",i);
+ value=getProperty(name);
+ if(value) encoders[i].switch_pullup=atoi(value);
+ sprintf(name,"encoders[%d].switch_address",i);
+ value=getProperty(name);
+ if(value) encoders[i].switch_address=atoi(value);
+ }
-static void e3FunctionAlert() {
- int level=digitalRead(E3_FUNCTION);
- if(level==0) {
- if(running) g_idle_add(e_function_pressed,GINT_TO_POINTER(e3_sw_action));
+ for(int f=0;f<MAX_FUNCTIONS;f++) {
+ for(int i=0;i<MAX_SWITCHES;i++) {
+ sprintf(name,"switches[%d,%d].switch_enabled",f,i);
+ value=getProperty(name);
+ if(value) switches_controller1[f][i].switch_enabled=atoi(value);
+ sprintf(name,"switches[%d,%d].switch_pullup",f,i);
+ value=getProperty(name);
+ if(value) switches_controller1[f][i].switch_pullup=atoi(value);
+ sprintf(name,"switches[%d,%d].switch_address",f,i);
+ value=getProperty(name);
+ if(value) switches_controller1[f][i].switch_address=atoi(value);
}
-}
-
-static unsigned long e4debounce=0;
+ }
-static void e4FunctionAlert() {
- int level=digitalRead(E4_FUNCTION);
- if(level==0) {
- if(running) g_idle_add(e_function_pressed,GINT_TO_POINTER(e4_sw_action));
+ if(controller!=CONTROLLER1) {
+ for(int i=0;i<MAX_SWITCHES;i++) {
+ sprintf(name,"switches[%d].switch_enabled",i);
+ value=getProperty(name);
+ if(value) switches[i].switch_enabled=atoi(value);
+ sprintf(name,"switches[%d].switch_pullup",i);
+ value=getProperty(name);
+ if(value) switches[i].switch_pullup=atoi(value);
+ sprintf(name,"switches[%d].switch_address",i);
+ value=getProperty(name);
+ if(value) switches[i].switch_address=atoi(value);
}
-}
-
-static unsigned long e5debounce=0;
+ }
-static void e5FunctionAlert() {
- int level=digitalRead(E5_FUNCTION);
- if(level==0) {
- if(running) g_idle_add(e_function_pressed,GINT_TO_POINTER(e5_sw_action));
- }
}
-static int function_level=1;
-static unsigned long function_debounce=0;
+void gpio_save_state() {
+ char value[80];
+ char name[80];
-static void functionAlert() {
- int t=millis();
- if(millis()<function_debounce) {
- return;
- }
- int level=digitalRead(FUNCTION_BUTTON);
- if(level!=function_level) {
- if(level==0) {
- if(running) g_idle_add(function_pressed,NULL);
- }
- function_level=level;
- function_debounce=t+settle_time;
- }
-}
+ clearProperties();
+ sprintf(value,"%d",controller);
+ setProperty("controller",value);
-static int s1_level=1;
-static unsigned long s1_debounce=0;
+ for(int i=0;i<MAX_ENCODERS;i++) {
+ sprintf(name,"encoders[%d].bottom_encoder_enabled",i);
+ sprintf(value,"%d",encoders[i].bottom_encoder_enabled);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].bottom_encoder_pullup",i);
+ sprintf(value,"%d",encoders[i].bottom_encoder_pullup);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].bottom_encoder_address_a",i);
+ sprintf(value,"%d",encoders[i].bottom_encoder_address_a);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].bottom_encoder_address_b",i);
+ sprintf(value,"%d",encoders[i].bottom_encoder_address_b);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].bottom_encoder_address_b",i);
+ sprintf(value,"%d",encoders[i].bottom_encoder_address_b);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].top_encoder_enabled",i);
+ sprintf(value,"%d",encoders[i].top_encoder_enabled);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].top_encoder_pullup",i);
+ sprintf(value,"%d",encoders[i].top_encoder_pullup);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].top_encoder_address_a",i);
+ sprintf(value,"%d",encoders[i].top_encoder_address_a);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].top_encoder_address_b",i);
+ sprintf(value,"%d",encoders[i].top_encoder_address_b);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].top_encoder_address_b",i);
+ sprintf(value,"%d",encoders[i].top_encoder_address_b);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].switch_enabled",i);
+ sprintf(value,"%d",encoders[i].switch_enabled);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].switch_pullup",i);
+ sprintf(value,"%d",encoders[i].switch_pullup);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].switch_address",i);
+ sprintf(value,"%d",encoders[i].switch_address);
+ setProperty(name,value);
+ }
-static void s1Alert() {
- int t=millis();
- if(millis()<s1_debounce) {
- return;
+ for(int f=0;f<MAX_FUNCTIONS;f++) {
+ for(int i=0;i<MAX_SWITCHES;i++) {
+ sprintf(name,"switches[%d,%d].switch_enabled",f,i);
+ sprintf(value,"%d",switches_controller1[f][i].switch_enabled);
+ setProperty(name,value);
+ sprintf(name,"switches[%d,%d].switch_pullup",f,i);
+ sprintf(value,"%d",switches_controller1[f][i].switch_pullup);
+ setProperty(name,value);
+ sprintf(name,"switches[%d,%d].switch_address",f,i);
+ sprintf(value,"%d",switches_controller1[f][i].switch_address);
+ setProperty(name,value);
}
- int level=digitalRead(S1_BUTTON);
- if(level!=s1_level) {
- if(level==0) {
- if(running) g_idle_add(s1_pressed,NULL);
- } else {
- if(running) g_idle_add(s1_released,NULL);
- }
- s1_level=level;
- s1_debounce=t+settle_time;
- }
-}
-
-static int s2_level=1;
-static unsigned long s2_debounce=0;
+ }
-static void s2Alert() {
- int t=millis();
- if(millis()<s2_debounce) {
- return;
- }
- int level=digitalRead(S2_BUTTON);
- if(level!=s2_level) {
- if(level==0) {
- if(running) g_idle_add(s2_pressed,NULL);
- } else {
- if(running) g_idle_add(s2_released,NULL);
- }
- s2_level=level;
- s2_debounce=t+settle_time;
+ if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
+ for(int i=0;i<MAX_SWITCHES;i++) {
+ sprintf(name,"switches[%d].switch_enabled",i);
+ sprintf(value,"%d",switches[i].switch_enabled);
+ setProperty(name,value);
+ sprintf(name,"switches[%d].switch_pullup",i);
+ sprintf(value,"%d",switches[i].switch_pullup);
+ setProperty(name,value);
+ sprintf(name,"switches[%d].switch_address",i);
+ sprintf(value,"%d",switches[i].switch_address);
+ setProperty(name,value);
}
-}
-
-static int s3_level=1;
-static unsigned long s3_debounce=0;
+ }
-static void s3Alert() {
- int t=millis();
- if(millis()<s3_debounce) {
- return;
- }
- int level=digitalRead(S3_BUTTON);
- if(level!=s3_level) {
- if(level==0) {
- if(running) g_idle_add(s3_pressed,NULL);
- } else {
- if(running) g_idle_add(s3_released,NULL);
- }
- s3_level=level;
- s3_debounce=t+settle_time;
- }
+ saveProperties("gpio.props");
}
-static int s4_level=1;
-static unsigned long s4_debounce=0;
-
-static void s4Alert() {
- int t=millis();
- if(millis()<s4_debounce) {
- return;
- }
- int level=digitalRead(S4_BUTTON);
- if(level!=s4_level) {
- if(level==0) {
- if(running) g_idle_add(s4_pressed,NULL);
- } else {
- if(running) g_idle_add(s4_released,NULL);
- }
- s4_level=level;
- s4_debounce=t+settle_time;
+void gpio_restore_actions() {
+ char name[80];
+ char *value;
+ if(controller!=NO_CONTROLLER) {
+ for(int i=0;i<MAX_ENCODERS;i++) {
+ sprintf(name,"encoders[%d].bottom_encoder_function",i);
+ value=getProperty(name);
+ if(value) encoders[i].bottom_encoder_function=atoi(value);
+ sprintf(name,"encoders[%d].top_encoder_function",i);
+ value=getProperty(name);
+ if(value) encoders[i].top_encoder_function=atoi(value);
+ sprintf(name,"encoders[%d].switch_function",i);
+ value=getProperty(name);
+ if(value) encoders[i].switch_function=atoi(value);
}
-}
-
-static int s5_level=1;
-static unsigned long s5_debounce=0;
+ }
-static void s5Alert() {
- int t=millis();
- if(millis()<s5_debounce) {
- return;
+ for(int f=0;f<MAX_FUNCTIONS;f++) {
+ for(int i=0;i<MAX_SWITCHES;i++) {
+ sprintf(name,"switches[%d,%d].switch_function",f,i);
+ value=getProperty(name);
+ if(value) switches_controller1[f][i].switch_function=atoi(value);
}
- int level=digitalRead(S5_BUTTON);
- if(level!=s5_level) {
- if(level==0) {
- if(running) g_idle_add(s5_pressed,NULL);
- } else {
- if(running) g_idle_add(s5_released,NULL);
- }
- s5_level=level;
- s5_debounce=t+settle_time;
+ }
+ if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
+ for(int i=0;i<MAX_SWITCHES;i++) {
+ sprintf(name,"switches[%d].switch_function",i);
+ value=getProperty(name);
+ if(value) switches[i].switch_function=atoi(value);
}
+ }
}
-static int s6_level=1;
-static unsigned long s6_debounce=0;
-
-static void s6Alert() {
- int t=millis();
- if(millis()<s6_debounce) {
- return;
- }
- int level=digitalRead(S6_BUTTON);
- if(level!=s6_level) {
- if(level==0) {
- if(running) g_idle_add(s6_pressed,NULL);
- } else {
- if(running) g_idle_add(s6_released,NULL);
- }
- s6_level=level;
- s6_debounce=t+settle_time;
+void gpio_save_actions() {
+ char value[80];
+ char name[80];
+ if(controller!=NO_CONTROLLER) {
+ for(int i=0;i<MAX_ENCODERS;i++) {
+ sprintf(name,"encoders[%d].bottom_encoder_function",i);
+ sprintf(value,"%d",encoders[i].bottom_encoder_function);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].top_encoder_function",i);
+ sprintf(value,"%d",encoders[i].top_encoder_function);
+ setProperty(name,value);
+ sprintf(name,"encoders[%d].switch_function",i);
+ sprintf(value,"%d",encoders[i].switch_function);
+ setProperty(name,value);
}
-}
-
-static int mox_level=1;
-static unsigned long mox_debounce=0;
+ }
-static void moxAlert() {
- int t=millis();
- if(millis()<mox_debounce) {
- return;
+ for(int f=0;f<MAX_FUNCTIONS;f++) {
+ for(int i=0;i<MAX_SWITCHES;i++) {
+ sprintf(name,"switches[%d,%d].switch_function",f,i);
+ sprintf(value,"%d",switches_controller1[f][i].switch_function);
+ setProperty(name,value);
}
- int level=digitalRead(MOX_BUTTON);
- if(level!=mox_level) {
- if(level==0) {
- if(running) g_idle_add(mox_pressed,NULL);
- }
- mox_level=level;
- mox_debounce=t+settle_time;
+ }
+ if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
+ for(int i=0;i<MAX_SWITCHES;i++) {
+ sprintf(name,"switches[%d].switch_function",i);
+ sprintf(value,"%d",switches[i].switch_function);
+ setProperty(name,value);
}
+ }
}
+#ifdef GPIO
+static gpointer monitor_thread(gpointer arg) {
+ struct timespec t;
+ // thread to monitor gpio events
+ g_print("%s: start event monitor lines=%d\n",__FUNCTION__,lines);
+ g_print("%s:",__FUNCTION__);
+ for(int i=0;i<lines;i++) {
+ g_print(" %d",monitor_lines[i]);
+ }
+ g_print("\n");
+ t.tv_sec=60;
+ t.tv_nsec=0;
+
+ int ret=gpiod_ctxless_event_monitor_multiple(
+ gpio_device, GPIOD_CTXLESS_EVENT_BOTH_EDGES,
+ monitor_lines, lines, FALSE,
+ consumer, &t, NULL, interrupt_cb,NULL);
+ if (ret<0) {
+ g_print("%s: ctxless event monitor failed: %s\n",__FUNCTION__,g_strerror(errno));
+ }
-#ifdef VFO_HAS_FUNCTION
-static unsigned long vfo_debounce=0;
-
-static void vfoFunctionAlert() {
- 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;
- }
+ g_print("%s: exit\n",__FUNCTION__);
+ return NULL;
}
-#endif
-static void vfoEncoderInt() {
- static int vfoA=1;
- int levelA=digitalRead(VFO_ENCODER_A);
- int levelB=digitalRead(VFO_ENCODER_B);
+static int setup_line(struct gpiod_chip *chip, int offset, gboolean pullup) {
+ int ret;
+ struct gpiod_line_request_config config;
- if(levelA!=vfoA) {
- if(levelA==levelB) ++vfoEncoderPos;
- if(levelA!=levelB) --vfoEncoderPos;
- vfoA=levelA;
+ g_print("%s: %d\n",__FUNCTION__,offset);
+ struct gpiod_line *line=gpiod_chip_get_line(chip, offset);
+ if (!line) {
+ g_print("%s: get line %d failed: %s\n",__FUNCTION__,offset,g_strerror(errno));
+ return -1;
}
-}
-static void e2EncoderInt() {
- static int e2CurrentA=1;
- int levelA=digitalRead(E2_ENCODER_A);
- int levelB=digitalRead(E2_ENCODER_B);
-
- if(levelA!=e2CurrentA) {
- if(levelA==levelB) ++e2EncoderPos;
- if(levelA!=levelB) --e2EncoderPos;
- e2CurrentA=levelA;
+ config.consumer=consumer;
+ config.request_type=GPIOD_LINE_REQUEST_DIRECTION_INPUT | GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES;
+#ifdef OLD_GPIOD
+ config.flags=pullup?GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW:0;
+#else
+ config.flags=pullup?GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP:GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN;
+#endif
+ ret=gpiod_line_request(line,&config,1);
+ if (ret<0) {
+ g_print("%s: line %d gpiod_line_request failed: %s\n",__FUNCTION__,offset,g_strerror(errno));
+ return ret;
}
-}
-static void e2TopEncoderInt() {
- static int e2TopCurrentA=1;
- int levelA=digitalRead(E2_TOP_ENCODER_A);
- int levelB=digitalRead(E2_TOP_ENCODER_B);
+ gpiod_line_release(line);
- if(levelA!=e2TopCurrentA) {
- if(levelA==levelB) ++e2TopEncoderPos;
- if(levelA!=levelB) --e2TopEncoderPos;
- e2TopCurrentA=levelA;
- }
+ monitor_lines[lines]=offset;
+ lines++;
+ return 0;
}
-static void e3EncoderInt() {
- static int e3CurrentA=1;
- int levelA=digitalRead(E3_ENCODER_A);
- int levelB=digitalRead(E3_ENCODER_B);
+static int setup_output_line(struct gpiod_chip *chip, int offset, int _initial_value) {
+ int ret;
+ struct gpiod_line_request_config config;
- if(levelA!=e3CurrentA) {
- if(levelA==levelB) ++e3EncoderPos;
- if(levelA!=levelB) --e3EncoderPos;
- e3CurrentA=levelA;
+ g_print("%s: %d\n",__FUNCTION__,offset);
+ struct gpiod_line *line=gpiod_chip_get_line(chip, offset);
+ if (!line) {
+ g_print("%s: get line %d failed: %s\n",__FUNCTION__,offset,g_strerror(errno));
+ return -1;
}
-}
-
-static void e3TopEncoderInt() {
- static int e3TopCurrentA=1;
- int levelA=digitalRead(E3_TOP_ENCODER_A);
- int levelB=digitalRead(E3_TOP_ENCODER_B);
-
- if(levelA!=e3TopCurrentA) {
- if(levelA==levelB) ++e3TopEncoderPos;
- if(levelA!=levelB) --e3TopEncoderPos;
- e3TopCurrentA=levelA;
+ config.consumer=consumer;
+ config.request_type=GPIOD_LINE_REQUEST_DIRECTION_OUTPUT;
+ ret=gpiod_line_request(line,&config,1);
+ if (ret<0) {
+ g_print("%s: line %d gpiod_line_request failed: %s\n",__FUNCTION__,offset,g_strerror(errno));
+ return ret;
}
-}
-
-static void e4EncoderInt() {
- static int e4CurrentA=1;
- int levelA=digitalRead(E4_ENCODER_A);
- int levelB=digitalRead(E4_ENCODER_B);
- if(levelA!=e4CurrentA) {
- if(levelA==levelB) ++e4EncoderPos;
- if(levelA!=levelB) --e4EncoderPos;
- e4CurrentA=levelA;
- }
-}
+ // write initial value
+
-static void e4TopEncoderInt() {
- static int e4TopCurrentA=1;
- int levelA=digitalRead(E4_TOP_ENCODER_A);
- int levelB=digitalRead(E4_TOP_ENCODER_B);
+ gpiod_line_release(line);
- if(levelA!=e4TopCurrentA) {
- if(levelA==levelB) ++e4TopEncoderPos;
- if(levelA!=levelB) --e4TopEncoderPos;
- e4TopCurrentA=levelA;
- }
+ return 0;
}
+#endif
-static void e5EncoderInt() {
- static int e5CurrentA=1;
- int levelA=digitalRead(E5_ENCODER_A);
- int levelB=digitalRead(E5_ENCODER_B);
+int gpio_init() {
+ int ret=0;
+#ifdef GPIO
+ initialiseEpoch();
+ switch_debounce=millis();
- if(levelA!=e5CurrentA) {
- if(levelA==levelB) ++e5EncoderPos;
- if(levelA!=levelB) --e5EncoderPos;
- e5CurrentA=levelA;
- }
-}
+ g_mutex_init(&encoder_mutex);
+
+ gpio_set_defaults(controller);
-static void e5TopEncoderInt() {
- static int e5TopCurrentA=1;
- int levelA=digitalRead(E5_TOP_ENCODER_A);
- int levelB=digitalRead(E5_TOP_ENCODER_B);
+ chip=NULL;
- if(levelA!=e5TopCurrentA) {
- if(levelA==levelB) ++e5TopEncoderPos;
- if(levelA!=levelB) --e5TopEncoderPos;
- e5TopCurrentA=levelA;
+//g_print("%s: open gpio 0\n",__FUNCTION__);
+ chip=gpiod_chip_open_by_number(0);
+ if(chip==NULL) {
+ g_print("%s: open chip failed: %s\n",__FUNCTION__,g_strerror(errno));
+ ret=-1;
+ goto err;
}
-}
-
-static void pI2CInterrupt() {
- int level=digitalRead(I2C_INTERRUPT);
- if(level==0) {
- i2c_interrupt();
+ // setup encoders
+ g_print("%s: setup encoders\n",__FUNCTION__);
+ for(int i=0;i<MAX_ENCODERS;i++) {
+ if(encoders[i].bottom_encoder_enabled) {
+ if(setup_line(chip,encoders[i].bottom_encoder_address_a,encoders[i].bottom_encoder_pullup)<0) {
+ continue;
+ }
+ if(setup_line(chip,encoders[i].bottom_encoder_address_b,encoders[i].bottom_encoder_pullup)<0) {
+ continue;
+ }
}
-}
-#ifdef PTT
-static int ptt_level=1;
-static unsigned long ptt_debounce=0;
+ if(encoders[i].top_encoder_enabled) {
+ if(setup_line(chip,encoders[i].top_encoder_address_a,encoders[i].top_encoder_pullup)<0) {
+ continue;
+ }
+ if(setup_line(chip,encoders[i].top_encoder_address_b,encoders[i].top_encoder_pullup)<0) {
+ continue;
+ }
+ }
-static void pttAlert() {
- int t=millis();
- if(millis()<ptt_debounce) {
- return;
+ if(encoders[i].switch_enabled) {
+ if(setup_line(chip,encoders[i].switch_address,encoders[i].switch_pullup)<0) {
+ continue;
+ }
}
- int level=digitalRead(PTT_GPIO);
- if(level!=ptt_level) {
- if(level==0) {
- if(running) g_idle_add(ptt_pressed,NULL);
- } else {
- if(running) g_idle_add(ptt_released,NULL);
+ }
+
+ // setup switches
+ g_print("%s: setup switches\n",__FUNCTION__);
+ for(int i=0;i<MAX_SWITCHES;i++) {
+ if(switches[i].switch_enabled) {
+ if(setup_line(chip,switches[i].switch_address,switches[i].switch_pullup)<0) {
+ continue;
}
- ptt_level=level;
- ptt_debounce=t+settle_time;
}
-}
-#endif
+ }
-void gpio_set_defaults(int ctrlr) {
-g_print("gpio_set_defaults: %d\n",ctrlr);
- if(sw_action!=NULL) {
- g_free(sw_action);
- sw_action=NULL;
- }
- switch(ctrlr) {
- case NO_CONTROLLER:
- ENABLE_VFO_ENCODER=0;
- ENABLE_E2_ENCODER=0;
- ENABLE_E3_ENCODER=0;
- ENABLE_E4_ENCODER=0;
- ENABLE_S1_BUTTON=0;
- ENABLE_S2_BUTTON=0;
- ENABLE_S3_BUTTON=0;
- ENABLE_S4_BUTTON=0;
- ENABLE_S5_BUTTON=0;
- ENABLE_S6_BUTTON=0;
- ENABLE_MOX_BUTTON=0;
- ENABLE_FUNCTION_BUTTON=0;
- ENABLE_E5_ENCODER=0;
- ENABLE_E2_TOP_ENCODER=0;
- ENABLE_E3_TOP_ENCODER=0;
- ENABLE_E4_TOP_ENCODER=0;
- ENABLE_E5_TOP_ENCODER=0;
- break;
- case CONTROLLER1:
- sw_action=g_new(int,CONTROLLER1_SWITCHES);
- ENABLE_VFO_ENCODER=1;
- ENABLE_VFO_PULLUP=1;
- VFO_ENCODER_A=1;
- VFO_ENCODER_B=0;
- ENABLE_E2_ENCODER=1;
- ENABLE_E2_PULLUP=0;
- E2_ENCODER_A=28;
- E2_ENCODER_B=25;
- E2_FUNCTION=6;
- ENABLE_E3_ENCODER=1;
- ENABLE_E3_PULLUP=0;
- E3_ENCODER_A=27;
- E3_ENCODER_B=24;
- E3_FUNCTION=10;
- ENABLE_E4_ENCODER=1;
- ENABLE_E4_PULLUP=0;
- E4_ENCODER_A=7;
- E4_ENCODER_B=29;
- E4_FUNCTION=11;
- ENABLE_S1_BUTTON=1;
- S1_BUTTON=23;
- ENABLE_S2_BUTTON=1;
- S2_BUTTON=26;
- ENABLE_S3_BUTTON=1;
- S3_BUTTON=22;
- ENABLE_S4_BUTTON=1;
- S4_BUTTON=21;
- ENABLE_S5_BUTTON=1;
- S5_BUTTON=5;
- ENABLE_S6_BUTTON=1;
- S6_BUTTON=4;
- ENABLE_MOX_BUTTON=1;
- MOX_BUTTON=2;
- ENABLE_FUNCTION_BUTTON=1;
- FUNCTION_BUTTON=3;
- ENABLE_E5_ENCODER=0;
- ENABLE_E2_TOP_ENCODER=0;
- ENABLE_E3_TOP_ENCODER=0;
- ENABLE_E4_TOP_ENCODER=0;
- ENABLE_E5_TOP_ENCODER=0;
- e2_sw_action=MENU_BAND;
- e2_encoder_action=ENCODER_AF_GAIN;
- e3_sw_action=MENU_BANDSTACK;
- e3_encoder_action=ENCODER_AGC_GAIN;
- e4_sw_action=MENU_MODE;
- e4_encoder_action=ENCODER_DRIVE;
- e2_top_encoder_action=ENCODER_NO_ACTION;
- e3_top_encoder_action=ENCODER_NO_ACTION;
- e4_top_encoder_action=ENCODER_NO_ACTION;
- e5_encoder_action=ENCODER_NO_ACTION;
- e5_top_encoder_action=ENCODER_NO_ACTION;
- break;
- case CONTROLLER2_V1:
- // uses wiringpi pin numbers
- ENABLE_VFO_ENCODER=1;
- ENABLE_VFO_PULLUP=1;
- VFO_ENCODER_A=1;
- VFO_ENCODER_B=0;
- ENABLE_E2_ENCODER=1;
- ENABLE_E2_PULLUP=1;
- E2_ENCODER_A=28;
- E2_ENCODER_B=25;
- E2_FUNCTION=3;
- ENABLE_E3_ENCODER=1;
- ENABLE_E3_PULLUP=1;
- E3_ENCODER_A=7;
- E3_ENCODER_B=29;
- E3_FUNCTION=2;
- ENABLE_E4_ENCODER=1;
- ENABLE_E4_PULLUP=1;
- E4_ENCODER_A=27;
- E4_ENCODER_B=24;
- E4_FUNCTION=4;
- ENABLE_E5_ENCODER=1;
- ENABLE_E5_PULLUP=1;
- E5_ENCODER_A=6;
- E5_ENCODER_B=10;
- E5_FUNCTION=5;
- ENABLE_S1_BUTTON=0;
- ENABLE_S2_BUTTON=0;
- ENABLE_S3_BUTTON=0;
- ENABLE_S4_BUTTON=0;
- ENABLE_S5_BUTTON=0;
- ENABLE_S6_BUTTON=0;
- ENABLE_E2_TOP_ENCODER=0;
- ENABLE_E3_TOP_ENCODER=0;
- ENABLE_E4_TOP_ENCODER=0;
- ENABLE_E5_TOP_ENCODER=0;
- sw_action=g_new(int,CONTROLLER2_SWITCHES);
- sw_action[0]=MOX;
- sw_action[1]=TUNE;
- sw_action[2]=PS;
- sw_action[3]=TWO_TONE;
- sw_action[4]=NR;
- sw_action[5]=A_TO_B;
- sw_action[6]=B_TO_A;
- sw_action[7]=MODE_MINUS;
- sw_action[8]=BAND_MINUS;
- sw_action[9]=MODE_PLUS;
- sw_action[10]=BAND_PLUS;
- sw_action[11]=XIT;
- sw_action[12]=NB;
- sw_action[13]=SNB;
- sw_action[14]=LOCK;
- sw_action[15]=CTUN;
- e2_sw_action=MENU_BAND;
- e2_encoder_action=ENCODER_AF_GAIN;
- e3_sw_action=MENU_BANDSTACK;
- e3_encoder_action=ENCODER_AGC_GAIN;
- e4_sw_action=MENU_MODE;
- e4_encoder_action=ENCODER_IF_WIDTH;
- e5_sw_action=MENU_FREQUENCY;
- e5_encoder_action=ENCODER_RIT;
- e2_top_encoder_action=ENCODER_NO_ACTION;
- e3_top_encoder_action=ENCODER_NO_ACTION;
- e4_top_encoder_action=ENCODER_NO_ACTION;
- e5_top_encoder_action=ENCODER_NO_ACTION;
- break;
- case CONTROLLER2_V2:
- // uses wiringpi pin numbers
- ENABLE_VFO_ENCODER=1;
- ENABLE_VFO_PULLUP=0;
- VFO_ENCODER_A=1;
- VFO_ENCODER_B=0;
- ENABLE_E2_ENCODER=1;
- ENABLE_E2_PULLUP=1;
- E2_ENCODER_A=21;
- E2_ENCODER_B=22;
- ENABLE_E2_TOP_ENCODER=1;
- E2_TOP_ENCODER_A=25;
- E2_TOP_ENCODER_B=28;
- E2_FUNCTION=3;
- ENABLE_E3_ENCODER=1;
- ENABLE_E3_PULLUP=1;
- E3_ENCODER_A=13;
- E3_ENCODER_B=11;
- ENABLE_E3_TOP_ENCODER=1;
- E3_TOP_ENCODER_A=29;
- E3_TOP_ENCODER_B=7;
- E3_FUNCTION=2;
- ENABLE_E4_ENCODER=1;
- ENABLE_E4_PULLUP=1;
- E4_ENCODER_A=14;
- E4_ENCODER_B=12;
- ENABLE_E4_TOP_ENCODER=1;
- E4_TOP_ENCODER_A=24;
- E4_TOP_ENCODER_B=27;
- E4_FUNCTION=4;
- ENABLE_E5_ENCODER=1;
- ENABLE_E5_PULLUP=1;
- E5_ENCODER_A=23;
- E5_ENCODER_B=26;
- ENABLE_E5_TOP_ENCODER=1;
- E5_TOP_ENCODER_A=10;
- E5_TOP_ENCODER_B=6;
- E5_FUNCTION=5;
- ENABLE_S1_BUTTON=0;
- ENABLE_S2_BUTTON=0;
- ENABLE_S3_BUTTON=0;
- ENABLE_S4_BUTTON=0;
- ENABLE_S5_BUTTON=0;
- ENABLE_S6_BUTTON=0;
- sw_action=g_new(int,CONTROLLER2_SWITCHES);
- sw_action[0]=MOX;
- sw_action[1]=TUNE;
- sw_action[2]=PS;
- sw_action[3]=TWO_TONE;
- sw_action[4]=NR;
- sw_action[5]=A_TO_B;
- sw_action[6]=B_TO_A;
- sw_action[7]=MODE_MINUS;
- sw_action[8]=BAND_MINUS;
- sw_action[9]=MODE_PLUS;
- sw_action[10]=BAND_PLUS;
- sw_action[11]=XIT;
- sw_action[12]=NB;
- sw_action[13]=SNB;
- sw_action[14]=LOCK;
- sw_action[15]=CTUN;
- e2_sw_action=MENU_BAND;
- e2_top_encoder_action=ENCODER_AF_GAIN;
- e2_encoder_action=ENCODER_RF_GAIN;
- e3_sw_action=MENU_MODE;
- e3_top_encoder_action=ENCODER_AGC_GAIN;
- e3_encoder_action=ENCODER_ATTENUATION;
- e4_sw_action=MENU_FILTER;
- e4_top_encoder_action=ENCODER_IF_SHIFT;
- e4_encoder_action=ENCODER_IF_WIDTH;
- e5_sw_action=MENU_FREQUENCY;
- e5_top_encoder_action=ENCODER_RIT;
- e5_encoder_action=ENCODER_XIT;
- break;
- default:
- break;
- }
-}
-
-void gpio_restore_actions() {
- char* value;
- char name[80];
- int i;
-
- if(sw_action!=NULL) {
- g_free(sw_action);
- sw_action=NULL;
- }
-
- gpio_set_defaults(controller);
-
- value=getProperty("settle_time");
- if(value) settle_time=atoi(value);
-
- value=getProperty("e2_encoder_action");
- if(value) e2_encoder_action=atoi(value);
- value=getProperty("e2_sw_action");
- if(value) e2_sw_action=atoi(value);
- value=getProperty("e3_encoder_action");
- if(value) e3_encoder_action=atoi(value);
- value=getProperty("e3_sw_action");
- if(value) e3_sw_action=atoi(value);
- value=getProperty("e4_encoder_action");
- if(value) e4_encoder_action=atoi(value);
- value=getProperty("e4_sw_action");
- if(value) e4_sw_action=atoi(value);
- value=getProperty("e2_top_encoder_action");
- if(value) e2_top_encoder_action=atoi(value);
- value=getProperty("e3_top_encoder_action");
- if(value) e3_top_encoder_action=atoi(value);
- value=getProperty("e4_top_encoder_action");
- if(value) e4_top_encoder_action=atoi(value);
- value=getProperty("e5_encoder_action");
- if(value) e5_encoder_action=atoi(value);
- value=getProperty("e5_top_encoder_action");
- if(value) e5_top_encoder_action=atoi(value);
- value=getProperty("e5_sw_action");
- if(value) e5_sw_action=atoi(value);
-
- int switches=0;
- switch(controller) {
- case CONTROLLER1:
- //switches=CONTROLLER1_SWITCHES;
- switches=0;
- break;
- case CONTROLLER2_V1:
- case CONTROLLER2_V2:
- switches=CONTROLLER2_SWITCHES;
- break;
- default:
- switches=0;
- break;
- }
-
- for(i=0;i<switches;i++) {
- sprintf(name,"sw_action[%d]",i);
- value=getProperty(name);
- if(value) sw_action[i]=atoi(value);
- }
-}
-
-void gpio_restore_state() {
- char* value;
- char name[80];
-
- loadProperties("gpio.props");
- value=getProperty("controller");
- if(value) controller=atoi(value);
- 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_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("E2_TOP_ENCODER_A");
- if(value) E2_TOP_ENCODER_A=atoi(value);
- value=getProperty("E2_TOP_ENCODER_B");
- if(value) E2_TOP_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);
- value=getProperty("E3_TOP_ENCODER_A");
- if(value) E3_TOP_ENCODER_A=atoi(value);
- value=getProperty("E3_TOP_ENCODER_B");
- if(value) E3_TOP_ENCODER_B=atoi(value);
- 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);
- value=getProperty("E4_TOP_ENCODER_A");
- if(value) E4_TOP_ENCODER_A=atoi(value);
- value=getProperty("E4_TOP_ENCODER_B");
- if(value) E4_TOP_ENCODER_B=atoi(value);
- value=getProperty("ENABLE_E5_ENCODER");
- if(value) ENABLE_E5_ENCODER=atoi(value);
- value=getProperty("ENABLE_E5_PULLUP");
- if(value) ENABLE_E5_PULLUP=atoi(value);
- value=getProperty("E5_ENCODER_A");
- if(value) E5_ENCODER_A=atoi(value);
- value=getProperty("E5_ENCODER_B");
- if(value) E5_ENCODER_B=atoi(value);
- value=getProperty("E5_TOP_ENCODER_A");
- if(value) E5_TOP_ENCODER_A=atoi(value);
- value=getProperty("E5_TOP_ENCODER_B");
- if(value) E5_TOP_ENCODER_B=atoi(value);
- 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);
-
- value=getProperty("E2_FUNCTION");
- if(value) E2_FUNCTION=atoi(value);
- value=getProperty("E3_FUNCTION");
- if(value) E3_FUNCTION=atoi(value);
- value=getProperty("E4_FUNCTION");
- if(value) E4_FUNCTION=atoi(value);
- value=getProperty("E5_FUNCTION");
- if(value) E5_FUNCTION=atoi(value);
-
-#ifdef LOCALCW
- value=getProperty("ENABLE_CW_BUTTONS");
- if(value) ENABLE_CW_BUTTONS=atoi(value);
- value=getProperty("CW_ACTIVE_LOW");
- if(value) CW_ACTIVE_LOW=atoi(value);
- value=getProperty("CWL_BUTTON");
- if(value) CWL_BUTTON=atoi(value);
- value=getProperty("CWR_BUTTON");
- if(value) CWR_BUTTON=atoi(value);
- value=getProperty("SIDETONE_GPIO");
- if(value) SIDETONE_GPIO=atoi(value);
- value=getProperty("ENABLE_GPIO_SIDETONE");
- if(value) ENABLE_GPIO_SIDETONE=atoi(value);
-#endif
-
-#ifdef PTT
- switch(controller) {
- case NO_CONTROLLER:
- PTT_GPIO=12;
- break;
- case CONTROLLER1:
- PTT_GPIO=12;
- break;
- case CONTROLLER2_V1:
- PTT_GPIO=15;
- break;
- case CONTROLLER2_V2:
- PTT_GPIO=15;
- break;
- }
- value=getProperty("ENABLE_PTT_GPIO");
- if(value) ENABLE_PTT_GPIO=atoi(value);
- value=getProperty("PTT_GPIO");
- if(value) PTT_GPIO=atoi(value);
- value=getProperty("PTT_ACTIVE_LOW");
- if(value) PTT_ACTIVE_LOW=atoi(value);
-#endif
-
- if(controller!=CONTROLLER1) {
- value=getProperty("i2c_device");
- if(value) {
- i2c_device=g_new(char,strlen(value)+1);
- strcpy(i2c_device,value);
- }
- for(int i=0;i<16;i++) {
- sprintf(name,"i2c_sw[%d]",i);
- value=getProperty(name);
- if(value) i2c_sw[i]=atoi(value);
+ if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
+ i2c_init();
+ g_print("%s: setup i2c interrupt %d\n",__FUNCTION__,I2C_INTERRUPT);
+ if((ret=setup_line(chip,I2C_INTERRUPT,TRUE))<0) {
+ goto err;
}
-
}
#ifdef LOCALCW
- if(controller==CONTROLLER2_V2) {
- //
- // In Controller2 V2, no 'free' GPIO pins
- // are available, so one cannot use any of
- // of these for CW in the standard setup
- //
- ENABLE_CW_BUTTONS=0;
- ENABLE_GPIO_SIDETONE=0;
- }
-#endif
-
-
-}
-
-void gpio_save_actions() {
- int i;
- char name[80];
- char value[80];
-
- sprintf(value,"%d",settle_time);
- setProperty("settle_time",value);
- sprintf(value,"%d",e2_sw_action);
- setProperty("e2_sw_action",value);
- sprintf(value,"%d",e2_encoder_action);
- setProperty("e2_encoder_action",value);
- sprintf(value,"%d",e3_sw_action);
- setProperty("e3_sw_action",value);
- sprintf(value,"%d",e3_encoder_action);
- setProperty("e3_encoder_action",value);
- sprintf(value,"%d",e4_sw_action);
- setProperty("e4_sw_action",value);
- sprintf(value,"%d",e4_encoder_action);
- setProperty("e4_encoder_action",value);
- sprintf(value,"%d",e5_sw_action);
- setProperty("e5_sw_action",value);
- sprintf(value,"%d",e5_encoder_action);
- setProperty("e5_encoder_action",value);
- sprintf(value,"%d",e2_top_encoder_action);
- setProperty("e2_top_encoder_action",value);
- sprintf(value,"%d",e3_top_encoder_action);
- setProperty("e3_top_encoder_action",value);
- sprintf(value,"%d",e4_top_encoder_action);
- setProperty("e4_top_encoder_action",value);
- sprintf(value,"%d",e5_top_encoder_action);
- setProperty("e5_top_encoder_action",value);
- int switches=0;
- switch(controller) {
- case CONTROLLER1:
- //switches=CONTROLLER1_SWITCHES;
- switches=0;
- break;
- case CONTROLLER2_V1:
- case CONTROLLER2_V2:
- switches=CONTROLLER2_SWITCHES;
- break;
- default:
- switches=0;
- break;
- }
- if(sw_action!=NULL) {
- for(i=0;i<switches;i++) {
- sprintf(name,"sw_action[%d]",i);
- sprintf(value,"%d",sw_action[i]);
- setProperty(name,value);
- }
- }
-
-}
-
-void gpio_save_state() {
- char value[80];
- char name[80];
-
- clearProperties();
- sprintf(value,"%d",controller);
- setProperty("controller",value);
- 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_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",E2_TOP_ENCODER_A);
- setProperty("E2_TOP_ENCODER_A",value);
- sprintf(value,"%d",E2_TOP_ENCODER_B);
- setProperty("E2_TOP_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);
- sprintf(value,"%d",E3_TOP_ENCODER_A);
- setProperty("E3_TOP_ENCODER_A",value);
- sprintf(value,"%d",E3_TOP_ENCODER_B);
- setProperty("E3_TOP_ENCODER_B",value);
- 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);
- sprintf(value,"%d",E4_TOP_ENCODER_A);
- setProperty("E4_TOP_ENCODER_A",value);
- sprintf(value,"%d",E4_TOP_ENCODER_B);
- setProperty("E4_TOP_ENCODER_B",value);
- sprintf(value,"%d",ENABLE_E5_ENCODER);
- setProperty("ENABLE_E5_ENCODER",value);
- sprintf(value,"%d",ENABLE_E5_PULLUP);
- setProperty("ENABLE_E5_PULLUP",value);
- sprintf(value,"%d",E5_ENCODER_A);
- setProperty("E5_ENCODER_A",value);
- sprintf(value,"%d",E5_ENCODER_B);
- setProperty("E5_ENCODER_B",value);
- sprintf(value,"%d",E5_TOP_ENCODER_A);
- setProperty("E5_TOP_ENCODER_A",value);
- sprintf(value,"%d",E5_TOP_ENCODER_B);
- setProperty("E5_TOP_ENCODER_B",value);
- 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);
-
- sprintf(value,"%d",E2_FUNCTION);
- setProperty("E2_FUNCTION",value);
- sprintf(value,"%d",E3_FUNCTION);
- setProperty("E3_FUNCTION",value);
- sprintf(value,"%d",E4_FUNCTION);
- setProperty("E4_FUNCTION",value);
- sprintf(value,"%d",E5_FUNCTION);
- setProperty("E5_FUNCTION",value);
-
- if(controller!=CONTROLLER1) {
- setProperty("i2c_device",i2c_device);
- sprintf(value,"%ud",i2c_address_1);
- setProperty("i2c_address_1",value);
- for(int i=0;i<16;i++) {
- sprintf(name,"i2c_sw[%d]",i);
- sprintf(value,"%ud",i2c_sw[i]);
- setProperty(name,value);
+ g_print("%s: ENABLE_CW_BUTTONS=%d CWL_BUTTON=%d CWR_BUTTON=%d\n", __FUNCTION__, ENABLE_CW_BUTTONS, CWL_BUTTON, CWR_BUTTON);
+ if(ENABLE_CW_BUTTONS) {
+ if((ret=setup_line(chip,CWL_BUTTON,CW_ACTIVE_LOW==1))<0) {
+ goto err;
}
-
- }
-
-#ifdef LOCALCW
- sprintf(value,"%d",ENABLE_CW_BUTTONS);
- setProperty("ENABLE_CW_BUTTONS",value);
- sprintf(value,"%d",CW_ACTIVE_LOW);
- setProperty("CW_ACTIVE_LOW",value);
- sprintf(value,"%d",CWL_BUTTON);
- setProperty("CWL_BUTTON",value);
- sprintf(value,"%d",CWR_BUTTON);
- setProperty("CWR_BUTTON",value);
- sprintf(value,"%d",SIDETONE_GPIO);
- setProperty("SIDETONE_GPIO",value);
- sprintf(value,"%d",ENABLE_GPIO_SIDETONE);
- setProperty("ENABLE_GPIO_SIDETONE",value);
-#endif
-
-#ifdef PTT
- sprintf(value,"%d",ENABLE_PTT_GPIO);
- setProperty("ENABLE_PTT_GPIO",value);
- sprintf(value,"%d",PTT_GPIO);
- setProperty("PTT_GPIO",value);
- sprintf(value,"%d",PTT_ACTIVE_LOW);
- setProperty("PTT_ACTIVE_LOW",value);
-#endif
- saveProperties("gpio.props");
-
-}
-
-static void setup_pin(int pin, int up_down, void(*pAlert)(void)) {
- int rc;
-g_print("setup_pin: pin=%d up_down=%d\n",pin,up_down);
- pinMode(pin,GPIO);
- pinMode(pin,INPUT);
- pullUpDnControl(pin,up_down);
- usleep(10000);
- rc=wiringPiISR(pin,INT_EDGE_BOTH,pAlert);
- if(rc<0) {
- fprintf(stderr,"wirngPiISR returned %d\n",rc);
- }
-}
-
-
-static void setup_encoder_pin(int pin, int up_down, void(*pAlert)(void)) {
- int rc;
- pinMode(pin,GPIO);
- pinMode(pin,INPUT);
- pullUpDnControl(pin,up_down);
- usleep(10000);
- if(pAlert!=NULL) {
- rc=wiringPiISR(pin,INT_EDGE_BOTH,pAlert);
- if(rc<0) {
- fprintf(stderr,"wirngPiISR returned %d\n",rc);
+ monitor_lines[lines]=CWL_BUTTON;
+ lines++;
+ if((ret=setup_line(chip,CWR_BUTTON,CW_ACTIVE_LOW==1))<0) {
+ goto err;
}
- }
-}
-
-#ifdef LOCALCW
-
-//
-// We generate interrupts only on falling edge
-//
+ monitor_lines[lines]=CWR_BUTTON;
+ lines++;
-static void setup_cw_pin(int pin, void(*pAlert)(void)) {
- int rc;
- pinMode(pin,INPUT);
- pullUpDnControl(pin,PUD_UP);
- usleep(10000);
- rc=wiringPiISR(pin,INT_EDGE_BOTH,pAlert);
- if(rc<0) {
- fprintf(stderr,"wirngPiISR returned %d\n",rc);
}
-}
-
-static void cwAlert_left() {
- int level;
- if (cw_keyer_internal != 0) return; // as quickly as possible
- level=digitalRead(CWL_BUTTON);
- //fprintf(stderr,"cwl button : level=%d \n",level);
- //the second parameter of keyer_event ("state") is TRUE on key-down
- keyer_event(1, CW_ACTIVE_LOW ? (level==0) : level);
-}
-
-static void cwAlert_right() {
- int level;
- if (cw_keyer_internal != 0) return; // as quickly as possible
- level=digitalRead(CWR_BUTTON);
- //fprintf(stderr,"cwr button : level=%d \n",level);
- keyer_event(0, CW_ACTIVE_LOW ? (level==0) : level);
-}
-
+ if (ENABLE_GPIO_SIDETONE) {
//
-// The following functions are an interface for
-// other parts to access CW gpio functions
-// (query left and right paddle, set sidetone output)
+// use this pin as an output pin and
+// set its value to LOW
//
-int gpio_left_cw_key() {
- int val=digitalRead(CWL_BUTTON);
- return CW_ACTIVE_LOW? (val==0) : val;
-}
-
-int gpio_right_cw_key() {
- int val=digitalRead(CWR_BUTTON);
- return CW_ACTIVE_LOW? (val==0) : val;
-}
-
-int gpio_cw_sidetone_enabled() {
- return ENABLE_GPIO_SIDETONE;
-}
-
-void gpio_cw_sidetone_set(int level) {
- if (ENABLE_GPIO_SIDETONE) {
- digitalWrite(SIDETONE_GPIO, level);
+ if((ret=setup_output_line(chip,SIDETONE_GPIO,0))<0) {
+ goto err;
+ }
}
-}
#endif
-int gpio_init() {
-
- fprintf(stderr,"gpio_wiringpi: gpio_init\n");
-
- gpio_restore_state();
-
- wiringPiSetup(); // use WiringPi pin numbers
-
- if(ENABLE_VFO_ENCODER) {
-#ifdef VFO_HAS_FUNCTION
- setup_pin(VFO_FUNCTION, PUD_UP, &vfoFunctionAlert);
- vfoFunction=0;
+ if(controller!=NO_CONTROLLER
+#ifdef LOCALCW
+ || ENABLE_CW_BUTTONS
#endif
- setup_encoder_pin(VFO_ENCODER_A,ENABLE_VFO_PULLUP?PUD_UP:PUD_DOWN,&vfoEncoderInt);
- setup_encoder_pin(VFO_ENCODER_B,ENABLE_VFO_PULLUP?PUD_UP:PUD_DOWN,NULL);
- vfoEncoderPos=0;
- }
-
- if(ENABLE_E2_ENCODER) {
- setup_pin(E2_FUNCTION, PUD_UP, &e2FunctionAlert);
-
- setup_encoder_pin(E2_ENCODER_A,ENABLE_E2_PULLUP?PUD_UP:PUD_OFF,&e2EncoderInt);
- setup_encoder_pin(E2_ENCODER_B,ENABLE_E2_PULLUP?PUD_UP:PUD_OFF,NULL);
- e2EncoderPos=0;
-
-
- if(controller==CONTROLLER2_V2) {
- setup_encoder_pin(E2_TOP_ENCODER_A,ENABLE_E2_PULLUP?PUD_UP:PUD_OFF,&e2TopEncoderInt);
- setup_encoder_pin(E2_TOP_ENCODER_B,ENABLE_E2_PULLUP?PUD_UP:PUD_OFF,NULL);
- e2TopEncoderPos=0;
+ ) {
+ monitor_thread_id = g_thread_new( "gpiod monitor", monitor_thread, NULL);
+ if(!monitor_thread_id ) {
+ g_print("%s: g_thread_new failed for monitor_thread\n",__FUNCTION__);
}
- }
-
- if(ENABLE_E3_ENCODER) {
- setup_pin(E3_FUNCTION, PUD_UP, &e3FunctionAlert);
-
- setup_encoder_pin(E3_ENCODER_A,ENABLE_E3_PULLUP?PUD_UP:PUD_OFF,&e3EncoderInt);
- setup_encoder_pin(E3_ENCODER_B,ENABLE_E3_PULLUP?PUD_UP:PUD_OFF,NULL);
- e3EncoderPos=0;
-
- if(controller==CONTROLLER2_V2) {
- setup_encoder_pin(E3_TOP_ENCODER_A,ENABLE_E3_PULLUP?PUD_UP:PUD_OFF,&e3TopEncoderInt);
- setup_encoder_pin(E3_TOP_ENCODER_B,ENABLE_E3_PULLUP?PUD_UP:PUD_OFF,NULL);
- e3TopEncoderPos=0;
- }
- }
-
-
- if(ENABLE_E4_ENCODER) {
- setup_pin(E4_FUNCTION, PUD_UP, &e4FunctionAlert);
-
- setup_encoder_pin(E4_ENCODER_A,ENABLE_E4_PULLUP?PUD_UP:PUD_OFF,&e4EncoderInt);
- setup_encoder_pin(E4_ENCODER_B,ENABLE_E4_PULLUP?PUD_UP:PUD_OFF,NULL);
- e4EncoderPos=0;
-
- if(controller==CONTROLLER2_V2) {
- setup_encoder_pin(E4_TOP_ENCODER_A,ENABLE_E4_PULLUP?PUD_UP:PUD_OFF,&e4TopEncoderInt);
- setup_encoder_pin(E4_TOP_ENCODER_B,ENABLE_E4_PULLUP?PUD_UP:PUD_OFF,NULL);
- e4TopEncoderPos=0;
- }
- }
-
- if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
- if(ENABLE_E5_ENCODER) {
- setup_pin(E5_FUNCTION, PUD_UP, &e5FunctionAlert);
-
- setup_encoder_pin(E5_ENCODER_A,ENABLE_E5_PULLUP?PUD_UP:PUD_OFF,&e5EncoderInt);
- setup_encoder_pin(E5_ENCODER_B,ENABLE_E5_PULLUP?PUD_UP:PUD_OFF,NULL);
- e5EncoderPos=0;
- if(controller==CONTROLLER2_V2) {
- setup_encoder_pin(E5_TOP_ENCODER_A,ENABLE_E5_PULLUP?PUD_UP:PUD_OFF,&e5TopEncoderInt);
- setup_encoder_pin(E5_TOP_ENCODER_B,ENABLE_E5_PULLUP?PUD_UP:PUD_OFF,NULL);
- e5TopEncoderPos=0;
+ if(controller!=NO_CONTROLLER) {
+ rotary_encoder_thread_id = g_thread_new( "encoders", rotary_encoder_thread, NULL);
+ if(!rotary_encoder_thread_id ) {
+ g_print("%s: g_thread_new failed on rotary_encoder_thread\n",__FUNCTION__);
+ exit( -1 );
}
+ g_print("%s: rotary_encoder_thread: id=%p\n",__FUNCTION__,rotary_encoder_thread_id);
}
}
- if(controller==CONTROLLER1){
- if(ENABLE_FUNCTION_BUTTON) {
- setup_pin(FUNCTION_BUTTON, PUD_UP, &functionAlert);
- }
-
- 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);
- }
- }
-
- rotary_encoder_thread_id = g_thread_new( "encoders", 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);
-
- if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
- // setup i2c
- i2c_init();
-
- // setup interrupt pin
- fprintf(stderr,"setup i2c interrupt: pin=%d\n",I2C_INTERRUPT);
- pinMode(I2C_INTERRUPT,INPUT);
- pullUpDnControl(I2C_INTERRUPT,PUD_UP);
- usleep(10000);
- wiringPiISR(I2C_INTERRUPT,INT_EDGE_BOTH,pI2CInterrupt);
- }
-
-#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_cw_pin(CWL_BUTTON, cwAlert_left);
- setup_cw_pin(CWR_BUTTON, cwAlert_right);
- }
- if (ENABLE_GPIO_SIDETONE) {
-//
-// use this pin as an output pin and
-// set its value to LOW
-//
- pinMode(SIDETONE_GPIO, OUTPUT);
- digitalWrite(SIDETONE_GPIO, 0);
- }
#endif
+ return 0;
-#ifdef PTT
- if(ENABLE_PTT_GPIO) {
-g_print("PTT Enabled: setup pin %d active_low=%d\n",PTT_GPIO,PTT_ACTIVE_LOW);
- setup_pin(PTT_GPIO,PTT_ACTIVE_LOW?PUD_UP:PUD_DOWN,pttAlert);
+err:
+g_print("%s: err\n",__FUNCTION__);
+#ifdef GPIO
+ if(chip!=NULL) {
+ gpiod_chip_close(chip);
+ chip=NULL;
}
#endif
-
- return 0;
+ return ret;
}
void gpio_close() {
- running=0;
+#ifdef GPIO
+ if(chip!=NULL) gpiod_chip_close(chip);
+#endif
}
-int vfo_encoder_get_pos() {
- int pos=vfoEncoderPos;
-
- if(vfo_encoder_divisor>1) {
- if(pos<0 && pos>-vfo_encoder_divisor) {
- pos=0;
- } else if(pos>0 && pos<vfo_encoder_divisor) {
- pos=0;
+#ifdef LOCALCW
+void gpio_cw_sidetone_set(int level) {
+ int rc;
+#ifdef GPIO
+ if (ENABLE_GPIO_SIDETONE) {
+ if((rc=gpiod_ctxless_set_value_ext(gpio_device,SIDETONE_GPIO,level,FALSE,consumer,NULL,NULL,0))<0) {
+ g_print("%s: err=%d\n",__FUNCTION__,rc);
}
- pos=pos/vfo_encoder_divisor;
- vfoEncoderPos=vfoEncoderPos-(pos*vfo_encoder_divisor);
- } else {
- vfoEncoderPos=0;
}
- return pos;
-}
-
-int e2_encoder_get_pos() {
- int pos=e2EncoderPos;
- e2EncoderPos=0;
- return pos;
-}
-
-int e3_encoder_get_pos() {
- int pos=e3EncoderPos;
- e3EncoderPos=0;
- return pos;
-}
-
-int e4_encoder_get_pos() {
- int pos=e4EncoderPos;
- e4EncoderPos=0;
- return pos;
-}
-
-int e5_encoder_get_pos() {
- int pos=e5EncoderPos;
- e5EncoderPos=0;
- return pos;
-}
-
-int e4_function_get_state() {
- return e4_sw_action;
-}
-
-int e2_top_encoder_get_pos() {
- int pos=e2TopEncoderPos;
- e2TopEncoderPos=0;
- return pos;
-}
-
-int e3_top_encoder_get_pos() {
- int pos=e3TopEncoderPos;
- e3TopEncoderPos=0;
- return pos;
-}
-
-int e4_top_encoder_get_pos() {
- int pos=e4TopEncoderPos;
- e4TopEncoderPos=0;
- return pos;
-}
-
-int e5_top_encoder_get_pos() {
- int pos=e5TopEncoderPos;
- e5TopEncoderPos=0;
- return pos;
-}
-
-int function_get_state() {
- return function_state;
-}
-
-int band_get_state() {
- return band_state;
-}
-
-int bandstack_get_state() {
- return bandstack_state;
-}
-
-int mode_get_state() {
- return mode_state;
-}
-
-int filter_get_state() {
- return filter_state;
-}
-
-int noise_get_state() {
- return noise_state;
-}
-
-int agc_get_state() {
- return agc_state;
-}
-
-int mox_get_state() {
- return mox_state;
-}
-
-int lock_get_state() {
- return lock_state;
-}
-
-
-static int vfo_encoder_changed(void *data) {
- if(!locked) {
- int pos=GPOINTER_TO_INT(data);
- vfo_step(pos);
- }
- //free(data);
- return 0;
-}
-
-static void encoder_changed(int action,int pos) {
- double value;
- int mode;
- int id;
- FILTER * band_filters=filters[vfo[active_receiver->id].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(active_receiver->id,value);
- break;
- case ENCODER_AF_GAIN_RX1:
- value=receiver[0]->volume;
- value+=(double)pos/100.0;
- if(value<0.0) {
- value=0.0;
- } else if(value>1.0) {
- value=1.0;
- }
- set_af_gain(0,value);
- break;
- case ENCODER_AF_GAIN_RX2:
- value=receiver[1]->volume;
- value+=(double)pos/100.0;
- if(value<0.0) {
- value=0.0;
- } else if(value>1.0) {
- value=1.0;
- }
- set_af_gain(1,value);
- break;
- case ENCODER_RF_GAIN:
- value=active_receiver->rf_gain;
- value+=(double)pos;
- if(value<0.0) {
- value=0.0;
- } else if(value>100.0) {
- value=100.0;
- }
- set_rf_gain(active_receiver->id,value);
- break;
- case ENCODER_RF_GAIN_RX1:
- value=receiver[0]->rf_gain;
- value+=(double)pos;
- if(value<0.0) {
- value=0.0;
- } else if(value>100.0) {
- value=100.0;
- }
- set_rf_gain(0,value);
- break;
- case ENCODER_RF_GAIN_RX2:
- value=receiver[1]->rf_gain;
- value+=(double)pos;
- if(value<0.0) {
- value=0.0;
- } else if(value>71.0) {
- value=71.0;
- }
- set_rf_gain(1,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(active_receiver->id,value);
- break;
- case ENCODER_AGC_GAIN_RX1:
- value=receiver[0]->agc_gain;
- value+=(double)pos;
- if(value<-20.0) {
- value=-20.0;
- } else if(value>120.0) {
- value=120.0;
- }
- set_agc_gain(0,value);
- break;
- case ENCODER_AGC_GAIN_RX2:
- value=receiver[1]->agc_gain;
- value+=(double)pos;
- if(value<-20.0) {
- value=-20.0;
- } else if(value>120.0) {
- value=120.0;
- }
- set_agc_gain(1,value);
- break;
- case ENCODER_IF_WIDTH:
- filter_width_changed(active_receiver->id,pos);
- break;
- case ENCODER_IF_WIDTH_RX1:
- filter_width_changed(0,pos);
- break;
- case ENCODER_IF_WIDTH_RX2:
- filter_width_changed(1,pos);
- break;
- case ENCODER_IF_SHIFT:
- filter_shift_changed(active_receiver->id,pos);
- break;
- case ENCODER_IF_SHIFT_RX1:
- filter_shift_changed(0,pos);
- break;
- case ENCODER_IF_SHIFT_RX2:
- filter_shift_changed(1,pos);
- break;
- case ENCODER_ATTENUATION:
- value=(double)adc_attenuation[active_receiver->adc];
- value+=(double)pos;
- if(have_rx_gain) {
- if(value<-12.0) {
- value=-12.0;
- } else if(value>48.0) {
- value=48.0;
- }
- } else {
- 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;
- value+=(double)pos;
- if(value<-12.0) {
- value=-12.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>drive_max) {
- value=drive_max;
- }
- set_drive(value);
- break;
- case ENCODER_RIT:
- vfo_rit(active_receiver->id,pos);
- break;
- case ENCODER_RIT_RX1:
- vfo_rit(receiver[0]->id,pos);
- break;
- case ENCODER_RIT_RX2:
- vfo_rit(receiver[1]->id,pos);
- break;
- case ENCODER_XIT:
- value=(double)transmitter->xit;
- value+=(double)(pos*rit_increment);
- if(value<-10000.0) {
- value=-10000.0;
- } else if(value>10000.0) {
- value=10000.0;
- }
- transmitter->xit=(int)value;
- if(protocol==NEW_PROTOCOL) {
- schedule_high_priority();
- }
- g_idle_add(ext_vfo_update,NULL);
- 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;
- g_idle_add(ext_vfo_update,NULL);
- 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;
- g_idle_add(ext_vfo_update,NULL);
- 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_PANADAPTER_STEP:
- value=(double)active_receiver->panadapter_step;
- value+=(double)pos;
- active_receiver->panadapter_step=(int)value;
- break;
- case ENCODER_WATERFALL_HIGH:
- value=(double)active_receiver->waterfall_high;
- value+=(double)pos;
- active_receiver->waterfall_high=(int)value;
- break;
- case ENCODER_WATERFALL_LOW:
- value=(double)active_receiver->waterfall_low;
- value+=(double)pos;
- active_receiver->waterfall_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_SQUELCH_RX1:
- value=receiver[0]->squelch;
- value+=(double)pos;
- if(value<0.0) {
- value=0.0;
- } else if(value>100.0) {
- value=100.0;
- }
- receiver[0]->squelch=value;
- set_squelch(receiver[0]);
- break;
- case ENCODER_SQUELCH_RX2:
- value=receiver[1]->squelch;
- value+=(double)pos;
- if(value<0.0) {
- value=0.0;
- } else if(value>100.0) {
- value=100.0;
- }
- receiver[1]->squelch=value;
- set_squelch(receiver[1]);
- 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;
- case ENCODER_DIVERSITY_GAIN:
- update_diversity_gain((double)pos * 0.5);
- break;
- case ENCODER_DIVERSITY_GAIN_COARSE:
- update_diversity_gain((double)pos * 2.5);
- break;
- case ENCODER_DIVERSITY_GAIN_FINE:
- update_diversity_gain((double)pos * 0.1);
- break;
- case ENCODER_DIVERSITY_PHASE:
- update_diversity_phase((double)pos* 0.5);
- break;
- case ENCODER_DIVERSITY_PHASE_COARSE:
- update_diversity_phase((double)pos*2.5);
- break;
- case ENCODER_DIVERSITY_PHASE_FINE:
- update_diversity_phase((double)pos*0.1);
- break;
- case ENCODER_ZOOM:
- update_zoom((double)pos);
- break;
- case ENCODER_PAN:
- update_pan((double)pos*100);
- break;
- }
-}
-
-static int e2_encoder_changed(void *data) {
- int pos=GPOINTER_TO_INT(data);
- if(active_menu==E2_MENU) {
- encoder_select(pos);
- } else {
- encoder_changed(e2_encoder_action,pos);
- }
- return 0;
-}
-
-static int e3_encoder_changed(void *data) {
- int pos=GPOINTER_TO_INT(data);
- if(active_menu==E3_MENU) {
- encoder_select(pos);
- } else {
- encoder_changed(e3_encoder_action,pos);
- }
- return 0;
-}
-
-static int e4_encoder_changed(void *data) {
- int pos=GPOINTER_TO_INT(data);
- if(active_menu==E4_MENU) {
- encoder_select(pos);
- } else {
- encoder_changed(e4_encoder_action,pos);
- }
- return 0;
-}
-
-static int e5_encoder_changed(void *data) {
- int pos=GPOINTER_TO_INT(data);
- if(active_menu==E5_MENU) {
- encoder_select(pos);
- } else {
- encoder_changed(e5_encoder_action,pos);
- }
- return 0;
+#endif
}
-
-static int e2_top_encoder_changed(void *data) {
- int pos=GPOINTER_TO_INT(data);
- if(active_menu==E2_MENU) {
- encoder_select(pos);
- } else {
- encoder_changed(e2_top_encoder_action,pos);
- }
+int gpio_left_cw_key() {
return 0;
}
-static int e3_top_encoder_changed(void *data) {
- int pos=GPOINTER_TO_INT(data);
- if(active_menu==E3_MENU) {
- encoder_select(pos);
- } else {
- encoder_changed(e3_top_encoder_action,pos);
- }
+int gpio_right_cw_key() {
return 0;
}
-static int e4_top_encoder_changed(void *data) {
- int pos=GPOINTER_TO_INT(data);
- if(active_menu==E4_MENU) {
- encoder_select(pos);
- } else {
- encoder_changed(e4_top_encoder_action,pos);
- }
- return 0;
-}
-
-static int e5_top_encoder_changed(void *data) {
- int pos=GPOINTER_TO_INT(data);
- if(active_menu==E5_MENU) {
- encoder_select(pos);
- } else {
- encoder_changed(e5_top_encoder_action,pos);
- }
- return 0;
+int gpio_cw_sidetone_enabled() {
+ return ENABLE_GPIO_SIDETONE;
}
-static gpointer rotary_encoder_thread(gpointer data) {
- int pos;
-
- sleep(2);
-
- running=1;
- while(1) {
-
- pos=vfo_encoder_get_pos();
- if(pos!=0) {
- g_idle_add(vfo_encoder_changed,GINT_TO_POINTER(pos));
- }
-
- pos=e2_encoder_get_pos();
- if(pos!=0) {
- g_idle_add(e2_encoder_changed,GINT_TO_POINTER(pos));
- }
-
- pos=e3_encoder_get_pos();
- if(pos!=0) {
- g_idle_add(e3_encoder_changed,GINT_TO_POINTER(pos));
- }
-
- pos=e4_encoder_get_pos();
- if(pos!=0) {
- g_idle_add(e4_encoder_changed,GINT_TO_POINTER(pos));
- }
-
- if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
- pos=e5_encoder_get_pos();
- if(pos!=0) {
- g_idle_add(e5_encoder_changed,GINT_TO_POINTER(pos));
- }
- }
-
-
- if(controller==CONTROLLER2_V2) {
- pos=e2_top_encoder_get_pos();
- if(pos!=0) {
- g_idle_add(e2_top_encoder_changed,GINT_TO_POINTER(pos));
- }
-
- pos=e3_top_encoder_get_pos();
- if(pos!=0) {
- g_idle_add(e3_top_encoder_changed,GINT_TO_POINTER(pos));
- }
-
- pos=e4_top_encoder_get_pos();
- if(pos!=0) {
- g_idle_add(e4_top_encoder_changed,GINT_TO_POINTER(pos));
- }
-
- pos=e5_top_encoder_get_pos();
- if(pos!=0) {
- g_idle_add(e5_top_encoder_changed,GINT_TO_POINTER(pos));
- }
- }
-
-#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
- if(running==0) {
- fprintf(stderr,"gpio_thread: quitting (running==0)\n");
- g_thread_exit(NULL);
- }
- usleep(100000);
-
- }
- return NULL;
-}
#ifndef _GPIO_H
#define _GPIO_H
-enum {
- NO_CONTROLLER=0,
- CONTROLLER1,
- CONTROLLER2_V1,
- CONTROLLER2_V2,
-};
-
-extern int controller;
-
-enum {
- ENCODER_NO_ACTION=0,
- ENCODER_AF_GAIN,
- ENCODER_AF_GAIN_RX1,
- ENCODER_AF_GAIN_RX2,
- ENCODER_AGC_GAIN,
- ENCODER_AGC_GAIN_RX1,
- ENCODER_AGC_GAIN_RX2,
- ENCODER_ATTENUATION,
- ENCODER_COMP,
- ENCODER_CW_FREQUENCY,
- ENCODER_CW_SPEED,
- ENCODER_DIVERSITY_GAIN,
- ENCODER_DIVERSITY_GAIN_COARSE,
- ENCODER_DIVERSITY_GAIN_FINE,
- ENCODER_DIVERSITY_PHASE,
- ENCODER_DIVERSITY_PHASE_COARSE,
- ENCODER_DIVERSITY_PHASE_FINE,
- ENCODER_DRIVE,
- ENCODER_IF_SHIFT,
- ENCODER_IF_SHIFT_RX1,
- ENCODER_IF_SHIFT_RX2,
- ENCODER_IF_WIDTH,
- ENCODER_IF_WIDTH_RX1,
- ENCODER_IF_WIDTH_RX2,
- ENCODER_MIC_GAIN,
- ENCODER_PAN,
- ENCODER_PANADAPTER_HIGH,
- ENCODER_PANADAPTER_LOW,
- ENCODER_PANADAPTER_STEP,
- ENCODER_RF_GAIN,
- ENCODER_RF_GAIN_RX1,
- ENCODER_RF_GAIN_RX2,
- ENCODER_RIT,
- ENCODER_RIT_RX1,
- ENCODER_RIT_RX2,
- ENCODER_SQUELCH,
- ENCODER_SQUELCH_RX1,
- ENCODER_SQUELCH_RX2,
- ENCODER_TUNE_DRIVE,
- ENCODER_WATERFALL_HIGH,
- ENCODER_WATERFALL_LOW,
- ENCODER_XIT,
- ENCODER_ZOOM,
- ENCODER_ACTIONS
-};
-
-extern char *encoder_string[ENCODER_ACTIONS];
-
-enum {
- NO_ACTION=0,
- A_TO_B,
- A_SWAP_B,
- AGC,
- ANF,
- B_TO_A,
- BAND_MINUS,
- BAND_PLUS,
- BANDSTACK_MINUS,
- BANDSTACK_PLUS,
- CTUN,
- DIVERSITY,
- FILTER_MINUS,
- FILTER_PLUS,
- FUNCTION,
- LOCK,
- MENU_BAND,
- MENU_BANDSTACK,
- MENU_DIVERSITY,
- MENU_FILTER,
- MENU_FREQUENCY,
- MENU_MEMORY,
- MENU_MODE,
- MENU_PS,
- MODE_MINUS,
- MODE_PLUS,
- MOX,
- MUTE,
- NB,
- NR,
- PAN_MINUS,
- PAN_PLUS,
- PS,
- RIT,
- RIT_CLEAR,
- SAT,
- SNB,
- SPLIT,
- TUNE,
- TWO_TONE,
- XIT,
- XIT_CLEAR,
- ZOOM_MINUS,
- ZOOM_PLUS,
- SWITCH_ACTIONS
-};
-
-extern char *sw_string[SWITCH_ACTIONS];
-
-
-enum {
- CONTROLLER1_SW1=0,
- CONTROLLER1_SW2,
- CONTROLLER1_SW3,
- CONTROLLER1_SW4,
- CONTROLLER1_SW5,
- CONTROLLER1_SW6,
- CONTROLLER1_SW7,
- CONTROLLER1_SW8,
- CONTROLLER1_SWITCHES
-};
-
-enum {
- CONTROLLER2_SW2=0,
- CONTROLLER2_SW3,
- CONTROLLER2_SW4,
- CONTROLLER2_SW5,
- CONTROLLER2_SW6,
- CONTROLLER2_SW7,
- CONTROLLER2_SW8,
- CONTROLLER2_SW9,
- CONTROLLER2_SW10,
- CONTROLLER2_SW11,
- CONTROLLER2_SW12,
- CONTROLLER2_SW13,
- CONTROLLER2_SW14,
- CONTROLLER2_SW15,
- CONTROLLER2_SW16,
- CONTROLLER2_SW17,
- CONTROLLER2_SWITCHES
-};
+#define MAX_ENCODERS 5
+#define MAX_SWITCHES 16
+#define MAX_FUNCTIONS 6
+
+typedef struct _encoder {
+ gboolean bottom_encoder_enabled;
+ gboolean bottom_encoder_pullup;
+ gint bottom_encoder_address_a;
+ gint bottom_encoder_a_value;
+ gint bottom_encoder_address_b;
+ gint bottom_encoder_b_value;
+ gint bottom_encoder_pos;
+ gint bottom_encoder_function;
+ guchar bottom_encoder_state;
+ gint top_encoder_enabled;
+ gboolean top_encoder_pullup;
+ gint top_encoder_address_a;
+ gint top_encoder_a_value;
+ gint top_encoder_address_b;
+ gint top_encoder_b_value;
+ gint top_encoder_pos;
+ gint top_encoder_function;
+ guchar top_encoder_state;
+ gboolean switch_enabled;
+ gboolean switch_pullup;
+ gint switch_address;
+ gint switch_function;
+ gulong switch_debounce;
+} ENCODER;
+
+extern ENCODER *encoders;
+
+typedef struct _switch {
+ gboolean switch_enabled;
+ gboolean switch_pullup;
+ gint switch_address;
+ gint switch_function;
+ gulong switch_debounce;
+} SWITCH;
+
+extern SWITCH switches_no_controller[MAX_SWITCHES];
+extern SWITCH switches_controller1[MAX_FUNCTIONS][MAX_SWITCHES];
+extern SWITCH switches_controller2_v1[MAX_SWITCHES];
+extern SWITCH switches_controller2_v2[MAX_SWITCHES];
+
+extern SWITCH *switches;
extern int *sw_action;
-extern int settle_time;
-
+extern long settle_time;
-extern int e2_encoder_action;
-extern int e3_encoder_action;
-extern int e4_encoder_action;
-extern int e5_encoder_action;
-
-extern int e2_top_encoder_action;
-extern int e3_top_encoder_action;
-extern int e4_top_encoder_action;
-extern int e5_top_encoder_action;
-
-extern int e2_sw_action;
-extern int e3_sw_action;
-extern int e4_sw_action;
-extern int e5_sw_action;
-
-// uses wiringpi pin numbers
-extern int ENABLE_VFO_ENCODER;
-extern int ENABLE_VFO_PULLUP;
-extern int VFO_ENCODER_A;
-extern int VFO_ENCODER_B;
-extern int ENABLE_E2_ENCODER;
-extern int ENABLE_E2_PULLUP;
-extern int E2_ENCODER_A;
-extern int E2_ENCODER_B;
-extern int E2_TOP_ENCODER_A;
-extern int E2_TOP_ENCODER_B;
-extern int E2_FUNCTION;
-extern int ENABLE_E3_ENCODER;
-extern int ENABLE_E3_PULLUP;
-extern int E3_ENCODER_A;
-extern int E3_ENCODER_B;
-extern int E3_TOP_ENCODER_A;
-extern int E3_TOP_ENCODER_B;
-extern int E3_FUNCTION;
-extern int ENABLE_E4_ENCODER;
-extern int ENABLE_E4_PULLUP;
-extern int E4_ENCODER_A;
-extern int E4_ENCODER_B;
-extern int E4_TOP_ENCODER_A;
-extern int E4_TOP_ENCODER_B;
-extern int E4_FUNCTION;
-extern int ENABLE_E5_ENCODER;
-extern int ENABLE_E5_PULLUP;
-extern int E5_ENCODER_A;
-extern int E5_ENCODER_B;
-extern int E5_TOP_ENCODER_A;
-extern int E5_TOP_ENCODER_B;
-extern int E5_FUNCTION;
-
-extern int ENABLE_S1_BUTTON;
-extern int S1_BUTTON;
-extern int ENABLE_S2_BUTTON;
-extern int S2_BUTTON;
-extern int ENABLE_S3_BUTTON;
-extern int S3_BUTTON;
-extern int ENABLE_S4_BUTTON;
-extern int S4_BUTTON;
-extern int ENABLE_S5_BUTTON;
-extern int S5_BUTTON;
-extern int ENABLE_S6_BUTTON;
-extern int S6_BUTTON;
+extern int process_function_switch(void *data);
+extern void gpio_set_defaults(int ctrlr);
+extern void gpio_restore_actions();
+extern void gpio_restore_state();
+extern void gpio_save_state();
+extern void gpio_save_actions();
+extern int gpio_init();
+extern void gpio_close();
-extern int ENABLE_MOX_BUTTON;
-extern int MOX_BUTTON;
-extern int ENABLE_FUNCTION_BUTTON;
-extern int FUNCTION_BUTTON;
#ifdef LOCALCW
extern int CWL_BUTTON;
extern int CWR_BUTTON;
extern int gpio_cw_sidetone_enabled();
#endif
-#ifdef PTT
-extern int ENABLE_PTT_GPIO;
-extern int PTT_GPIO;
-extern int PTT_ACTIVE_LOW;
-#endif
-
-extern void gpio_set_defaults(int ctrlr);
-extern void gpio_restore_actions();
-extern void gpio_restore_state();
-extern void gpio_save_state();
-extern void gpio_save_actions();
-extern int gpio_init();
-extern void gpio_close();
-extern int vfo_encoder_get_pos();
-extern int af_encoder_get_pos();
-extern int af_function_get_state();
-extern int rf_encoder_get_pos();
-extern int rf_function_get_state();
-extern int function_get_state();
-extern int band_get_state();
-extern int mode_get_state();
-extern int filter_get_state();
-extern int noise_get_state();
-extern int mox_get_state();
-
#endif
+#ifdef GPIO
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
-//#include <i2c/smbus.h>
+#include <i2c/smbus.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <gtk/gtk.h>
-//#include "i2c.h"
-#include "wiringPiI2C.h"
+#include "i2c.h"
+#include "actions.h"
#include "gpio.h"
#include "band.h"
#include "band_menu.h"
#define SW_17 0X0100
unsigned int i2c_sw[16]=
- { SW_2,SW_3,SW_4,SW_5,SW_6,SW_7,SW_8,SW_9,
- SW_10,SW_11,SW_12,SW_13,SW_14,SW_15,SW_16,SW_17 };
+ { SW_2,SW_3,SW_4,SW_5,SW_6,SW_14,SW_15,SW_13,
+ SW_12,SW_11,SW_10,SW_9,SW_7,SW_8,SW_16,SW_17 };
-static int write_byte_data(unsigned char addr,unsigned char reg, unsigned char data) {
+static int write_byte_data(unsigned char reg, unsigned char data) {
int rc;
- rc=wiringPiI2CWriteReg8(fd,reg,data);
+ if(i2c_smbus_write_byte_data(fd,reg,data&0xFF)<0) {
+ g_print("%s: write REG_GCONF config failed: addr=%02X %s\n",__FUNCTION__,i2c_address_1,g_strerror(errno));
+ }
- return 0;
+ return rc;
}
-static unsigned char read_byte_data(unsigned char addr,unsigned char reg) {
- int rc;
-
- rc=wiringPiI2CReadReg8(fd,reg);
+static unsigned char read_byte_data(unsigned char reg) {
+ __s32 data;
- return rc;
+ data=i2c_smbus_read_byte_data(fd,reg);
+ return data&0xFF;
}
-static unsigned int read_word_data(unsigned char addr,unsigned char reg) {
- int rc;
-
- rc=wiringPiI2CReadReg16(fd,reg);
+static unsigned int read_word_data(unsigned char reg) {
+ __s32 data;
- return rc;
+ data=i2c_smbus_read_word_data(fd,reg);
+ return data&0xFFFF;
}
unsigned int ints;
do {
- flags=read_word_data(i2c_address_1,0x0E);
+ flags=read_word_data(0x0E);
if(flags) {
- ints=read_word_data(i2c_address_1,0x10);
-//g_print("i2c_interrupt: flags=%04X ints=%04X\n",flags,ints);
+ ints=read_word_data(0x10);
+g_print("%s: flags=%04X ints=%04X\n",__FUNCTION__,flags,ints);
if(ints) {
int i;
for(i=0;i<16;i++) {
if(i2c_sw[i]==ints) break;
}
if(i<16) {
-//g_print("i1c_interrupt: sw=%d action=%d\n",i,sw_action[i]);
- switch(sw_action[i]) {
- case TUNE:
- if(can_transmit) {
- int tune=getTune();
- if(tune==0) tune=1; else tune=0;
- g_idle_add(ext_tune_update,GINT_TO_POINTER(tune));
- }
- break;
- case MOX:
- if(can_transmit) {
- int mox=getMox();
- if(mox==0) mox=1; else mox=0;
- g_idle_add(ext_mox_update,GINT_TO_POINTER(mox));
- }
- break;
- case PS:
-#ifdef PURESIGNAL
- if(can_transmit) g_idle_add(ext_ps_update,NULL);
-#endif
- break;
- case TWO_TONE:
- if(can_transmit) g_idle_add(ext_two_tone,NULL);
- break;
- case NR:
- g_idle_add(ext_nr_update,NULL);
- break;
- case NB:
- g_idle_add(ext_nb_update,NULL);
- break;
- case SNB:
- g_idle_add(ext_snb_update,NULL);
- break;
- case RIT:
- g_idle_add(ext_rit_update,NULL);
- break;
- case RIT_CLEAR:
- g_idle_add(ext_rit_clear,NULL);
- break;
- case XIT:
- if(can_transmit) g_idle_add(ext_xit_update,NULL);
- break;
- case XIT_CLEAR:
- if(can_transmit) g_idle_add(ext_xit_clear,NULL);
- break;
- case BAND_PLUS:
- g_idle_add(ext_band_plus,NULL);
- break;
- case BAND_MINUS:
- g_idle_add(ext_band_minus,NULL);
- break;
- case BANDSTACK_PLUS:
- g_idle_add(ext_bandstack_plus,NULL);
- break;
- case BANDSTACK_MINUS:
- g_idle_add(ext_bandstack_minus,NULL);
- break;
- case MODE_PLUS:
- g_idle_add(ext_mode_plus,NULL);
- break;
- case MODE_MINUS:
- g_idle_add(ext_mode_minus,NULL);
- break;
- case FILTER_PLUS:
- g_idle_add(ext_filter_plus,NULL);
- break;
- case FILTER_MINUS:
- g_idle_add(ext_filter_minus,NULL);
- break;
- case A_TO_B:
- g_idle_add(ext_vfo_a_to_b,NULL);
- break;
- case B_TO_A:
- g_idle_add(ext_vfo_b_to_a,NULL);
- break;
- case A_SWAP_B:
- g_idle_add(ext_vfo_a_swap_b,NULL);
- break;
- case LOCK:
- g_idle_add(ext_lock_update,NULL);
- break;
- case CTUN:
- g_idle_add(ext_ctun_update,NULL);
- break;
- case AGC:
- g_idle_add(ext_agc_update,NULL);
- break;
- case SPLIT:
- if(can_transmit) g_idle_add(ext_split_toggle,NULL);
- break;
- case DIVERSITY:
- g_idle_add(ext_diversity_update,GINT_TO_POINTER(0));
- break;
- case SAT:
- if(can_transmit) g_idle_add(ext_sat_update,NULL);
- break;
- case MENU_BAND:
- g_idle_add(ext_band_update,NULL);
- break;
- case MENU_BANDSTACK:
- g_idle_add(ext_bandstack_update,NULL);
- break;
- case MENU_MODE:
- g_idle_add(ext_mode_update,NULL);
- break;
- case MENU_FILTER:
- g_idle_add(ext_filter_update,NULL);
- break;
- case MENU_FREQUENCY:
- g_idle_add(ext_frequency_update,NULL);
- break;
- case MENU_MEMORY:
- g_idle_add(ext_memory_update,NULL);
- break;
- case MENU_DIVERSITY:
- g_idle_add(ext_diversity_update,GINT_TO_POINTER(1));
- break;
- case MENU_PS:
-#ifdef PURESIGNAL
- g_idle_add(ext_start_ps,NULL);
-#endif
- break;
- case FUNCTION:
- g_idle_add(ext_function_update,NULL);
- break;
- case MUTE:
- g_idle_add(ext_mute_update,NULL);
- break;
- case PAN_MINUS:
- g_idle_add(ext_pan_update,GINT_TO_POINTER(-100));
- break;
- case PAN_PLUS:
- g_idle_add(ext_pan_update,GINT_TO_POINTER(100));
- break;
- case ZOOM_MINUS:
- g_idle_add(ext_zoom_update,GINT_TO_POINTER(-1));
- break;
- case ZOOM_PLUS:
- g_idle_add(ext_zoom_update,GINT_TO_POINTER(1));
- break;
- }
+g_print("%s: switches=%p sw=%d action=%d\n",__FUNCTION__,switches,i,switches[i].switch_function);
+ SWITCH_ACTION *a=g_new(SWITCH_ACTION,1);
+ a->action=switches[i].switch_function;
+ a->state=PRESSED;
+ g_idle_add(switch_action,a);
}
}
}
int flags, ints;
-fprintf(stderr,"i2c_init: %s\n",i2c_device);
-
- fd=wiringPiI2CSetupInterface(i2c_device, i2c_address_1);
+ g_print("%s: open i2c device %s\n",__FUNCTION__,i2c_device);
+ fd=open(i2c_device, O_RDWR);
if(fd<0) {
- g_print("i2c_init failed: fd=%d\n",fd);
+ g_print("%s: open i2c device %s failed: %s\n",__FUNCTION__,i2c_device,g_strerror(errno));
+ return;
+ }
+ g_print("%s: open i2c device %s fd=%d\n",__FUNCTION__,i2c_device,fd);
+
+ if (ioctl(fd, I2C_SLAVE, i2c_address_1) < 0) {
+ g_print("%s: ioctl i2c slave %d failed: %s\n",__FUNCTION__,i2c_address_1,g_strerror(errno));
return;
}
// setup i2c
- if(write_byte_data(i2c_address_1,0x0A,0x44)<0) return;
- if(write_byte_data(i2c_address_1,0x0B,0x44)<0) return;
+ if(write_byte_data(0x0A,0x44)<0) return;
+ if(write_byte_data(0x0B,0x44)<0) return;
// disable interrupt
- if(write_byte_data(i2c_address_1,0x04,0x00)<0) return;
- if(write_byte_data(i2c_address_1,0x05,0x00)<0) return;
+ if(write_byte_data(0x04,0x00)<0) return;
+ if(write_byte_data(0x05,0x00)<0) return;
// clear defaults
- if(write_byte_data(i2c_address_1,0x06,0x00)<0) return;
- if(write_byte_data(i2c_address_1,0x07,0x00)<0) return;
+ if(write_byte_data(0x06,0x00)<0) return;
+ if(write_byte_data(0x07,0x00)<0) return;
// OLAT
- if(write_byte_data(i2c_address_1,0x14,0x00)<0) return;
- if(write_byte_data(i2c_address_1,0x15,0x00)<0) return;
+ if(write_byte_data(0x14,0x00)<0) return;
+ if(write_byte_data(0x15,0x00)<0) return;
// set GPIOA for pullups
- if(write_byte_data(i2c_address_1,0x0C,0xFF)<0) return;
- if(write_byte_data(i2c_address_1,0x0D,0xFF)<0) return;
+ if(write_byte_data(0x0C,0xFF)<0) return;
+ if(write_byte_data(0x0D,0xFF)<0) return;
// reverse polarity
- if(write_byte_data(i2c_address_1,0x02,0xFF)<0) return;
- if(write_byte_data(i2c_address_1,0x03,0xFF)<0) return;
+ if(write_byte_data(0x02,0xFF)<0) return;
+ if(write_byte_data(0x03,0xFF)<0) return;
// set GPIOA/B for input
- if(write_byte_data(i2c_address_1,0x00,0xFF)<0) return;
- if(write_byte_data(i2c_address_1,0x01,0xFF)<0) return;
+ if(write_byte_data(0x00,0xFF)<0) return;
+ if(write_byte_data(0x01,0xFF)<0) return;
// INTCON
- if(write_byte_data(i2c_address_1,0x08,0x00)<0) return;
- if(write_byte_data(i2c_address_1,0x09,0x00)<0) return;
+ if(write_byte_data(0x08,0x00)<0) return;
+ if(write_byte_data(0x09,0x00)<0) return;
// setup for an MCP23017 interrupt
- if(write_byte_data(i2c_address_1,0x04,0xFF)<0) return;
- if(write_byte_data(i2c_address_1,0x05,0xFF)<0) return;
+ if(write_byte_data(0x04,0xFF)<0) return;
+ if(write_byte_data(0x05,0xFF)<0) return;
// flush any interrupts
int count=0;
do {
- flags=read_word_data(i2c_address_1,0x0E);
+ flags=read_word_data(0x0E);
if(flags) {
- ints=read_word_data(i2c_address_1,0x10);
+ ints=read_word_data(0x10);
fprintf(stderr,"flush interrupt: flags=%04X ints=%04X\n",flags,ints);
count++;
if(count==10) {
} while(flags!=0);
}
+#endif
**************************************************************************************************************
*/
+#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/mman.h>
-#ifdef GPIO
+#ifdef LOCALCW
#include "gpio.h"
#endif
#include "radio.h"
struct timespec *__rem);
#endif
-#ifndef GPIO
-//
-// Dummy functions if compiled without GPIO
-//
-int gpio_cw_sidetone_enabled() { return 0; }
-void gpio_cw_sidetone_set(int level) {}
-#endif
-
static void keyer_straight_key(int state) {
//
// Interface for simple key-down action e.g. from a MIDI message
*
*/
+#include <gtk/gtk.h>
+#include "discovered.h"
+#include "receiver.h"
+#include "transmitter.h"
+#include "receiver.h"
+#include "adc.h"
+#include "dac.h"
+#include "radio.h"
#include "midi.h"
+#include "midi_menu.h"
+#include "alsa_midi.h"
#ifdef __APPLE__
#include <CoreAudio/HostTime.h>
#include <CoreAudio/CoreAudio.h>
+MIDI_DEVICE midi_devices[MAX_MIDI_DEVICES];
+int n_midi_devices;
+int running;
+
//
// MIDI callback function
// called by MacOSX when data from the specified MIDI device arrives.
CMD_PITCH,
} command;
+static gboolean configure=FALSE;
+
static void ReadMIDIdevice(const MIDIPacketList *pktlist, void *refCon, void *connRefCon) {
int i,j,byte,chan,arg1,arg2;
MIDIPacket *packet = (MIDIPacket *)pktlist->packet;
// messages with velocity == 0 when releasing
// a push-button.
if (arg2 == 0) {
- NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+ if(configure) {
+ NewMidiConfigureEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+ } else {
+ NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+ }
} else {
- NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 1);
+ if(configure) {
+ NewMidiConfigureEvent(MIDI_EVENT_NOTE, chan, arg1, 1);
+ } else {
+ NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 1);
+ }
}
break;
case CMD_NOTEOFF:
- NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+ if(configure) {
+ NewMidiConfigureEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+ } else {
+ NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+ }
break;
case CMD_CTRL:
- NewMidiEvent(MIDI_EVENT_CTRL, chan, arg1, arg2);
+ if(configure) {
+ NewMidiConfigureEvent(MIDI_EVENT_CTRL, chan, arg1, arg2);
+ } else {
+ NewMidiEvent(MIDI_EVENT_CTRL, chan, arg1, arg2);
+ }
break;
case CMD_PITCH:
- NewMidiEvent(MIDI_EVENT_PITCH, chan, 0, arg1+128*arg2);
+ if(configure) {
+ NewMidiConfigureEvent(MIDI_EVENT_PITCH, chan, 0, arg1+128*arg2);
+ } else {
+ NewMidiEvent(MIDI_EVENT_PITCH, chan, 0, arg1+128*arg2);
+ }
break;
}
state=STATE_SKIP;
} // j-loop through the list of packets
}
+//
+// store the ports and clients locally such that we
+// can properly close a MIDI connection.
+// This can be local static data, no one outside this file
+// needs it.
+//
+static MIDIPortRef myMIDIports[MAX_MIDI_DEVICES];
+static MIDIClientRef myClients[MAX_MIDI_DEVICES];
-void register_midi_device(char *myname) {
- unsigned long nDevices;
- int i;
- CFStringRef pname;
- char name[100];
- int FoundMIDIref=-1;
- int mylen=strlen(myname);
+void close_midi_device(index) {
+ fprintf(stderr,"%s index=%d\n",__FUNCTION__, index);
+ if (index < 0 || index > n_midi_devices) return;
+ //
+ // This should release the resources associated with the pending connection
+ //
+ MIDIPortDisconnectSource(myMIDIports[index], MIDIGetSource(index));
+ midi_devices[index].active=0;
+}
+void register_midi_device(int index) {
+ OSStatus osret;
+ g_print("%s: index=%d\n",__FUNCTION__,index);
//
-// Go through the list of MIDI devices and
-// look whether the one we are looking for is there
+// Register a callback routine for the device
//
+ if (index < 0 || index > MAX_MIDI_DEVICES) return;
+
+ myClients[index]=0;
+ myMIDIports[index] = 0;
+ //Create client and port, and connect
+ osret=MIDIClientCreate(CFSTR("piHPSDR"),NULL,NULL, &myClients[index]);
+ if (osret !=0) {
+ g_print("%s: MIDIClientCreate failed with ret=%d\n", __FUNCTION__, (int) osret);
+ return;
+ }
+ osret=MIDIInputPortCreate(myClients[index], CFSTR("FromMIDI"), ReadMIDIdevice, NULL, &myMIDIports[index]);
+ if (osret !=0) {
+ g_print("%s: MIDIInputPortCreate failed with ret=%d\n", __FUNCTION__, (int) osret);
+ return;
+ }
+ osret=MIDIPortConnectSource(myMIDIports[index] ,MIDIGetSource(index), NULL);
+ if (osret != 0) {
+ g_print("%s: MIDIPortConnectSource failed with ret=%d\n", __FUNCTION__, (int) osret);
+ return;
+ }
+ //
+ // Now we have successfully opened the device.
+ //
+ midi_devices[index].active=1;
+ return;
+}
+
+void get_midi_devices() {
+ int n;
+ int i;
+ CFStringRef pname; // MacOS name of the device
+ char name[100]; // C name of the device
+ OSStatus osret;
+ static int first=1;
+
+ if (first) {
+ //
+ // perhaps not necessary in C, but good programming practise:
+ // initialize the table upon the first call
+ //
+ first=0;
+ for (i=0; i<MAX_MIDI_DEVICES; i++) {
+ midi_devices[i].name=NULL;
+ midi_devices[i].active=0;
+ }
+ }
- nDevices=MIDIGetNumberOfSources();
- for (i=0; i<nDevices; i++) {
- MIDIEndpointRef dev = MIDIGetSource(i);
- if (dev != 0) {
- MIDIObjectGetStringProperty(dev, kMIDIPropertyName, &pname);
- CFStringGetCString(pname, name, sizeof(name), 0);
- CFRelease(pname);
+//
+// This is called at startup (via midi_restore) and each time
+// the MIDI menu is opened. So we have to take care that this
+// function is essentially a no-op if the device list has not
+// changed.
+// If the device list has changed because of hot-plugging etc.
+// close any MIDI device which changed position and mark
+// it as inactive. Note that upon a hot-plug, MIDI devices that were
+// there before may change its position in the device list and will then
+// be closed.
+//
+ n=MIDIGetNumberOfSources();
+ n_midi_devices=0;
+ for (i=0; i<n; i++) {
+ MIDIEndpointRef dev = MIDIGetSource(i);
+ if (dev != 0) {
+ osret=MIDIObjectGetStringProperty(dev, kMIDIPropertyName, &pname);
+ if (osret !=0) break; // in this case pname is invalid
+ CFStringGetCString(pname, name, sizeof(name), 0);
+ CFRelease(pname);
//
// Some users have reported that MacOS reports a string of length zero
// for some MIDI devices. In this case, we replace the name by
- // "NoPort"
+ // "NoPort<n>"
//
- if (strlen(name) == 0) strcpy(name,"NoPort");
- if (!strncmp(name, myname, mylen)) {
- FoundMIDIref=i;
- fprintf(stderr,"MIDI: registering device >%s<\n", name);
- } else {
- fprintf(stderr,"MIDI: looking for >%s< so >%s< does not match\n", myname,name);
- }
- }
+ if (strlen(name) == 0) sprintf(name,"NoPort%d",n_midi_devices);
+ g_print("%s: %s\n",__FUNCTION__,name);
+ if (midi_devices[n_midi_devices].name != NULL) {
+ if (strncmp(name, midi_devices[n_midi_devices].name,sizeof(name))) {
+ //
+ // This slot was occupied and the names do not match:
+ // Close device (if active), insert new name
+ //
+ if (midi_devices[n_midi_devices].active) {
+ close_midi_device(n_midi_devices);
+ }
+ g_free(midi_devices[n_midi_devices].name);
+ midi_devices[n_midi_devices].name=g_new(gchar,strlen(name)+1);
+ strcpy(midi_devices[n_midi_devices].name, name);
+ } else {
+ //
+ // This slot was occupied and the names match: do nothing!
+ // If there was no hot-plug or hot-unplug, we should always
+ // arrive here!
+ //
+ }
+ } else {
+ //
+ // This slot was unoccupied. Insert name and mark inactive
+ //
+ midi_devices[n_midi_devices].name=g_new(gchar,strlen(name)+1);
+ strcpy(midi_devices[n_midi_devices].name, name);
+ midi_devices[n_midi_devices].active=0;
+ }
+ n_midi_devices++;
+ }
+ //
+ // If there are more devices than we have slots in our Table
+ // just stop processing.
+ //
+ if (n_midi_devices >= MAX_MIDI_DEVICES) break;
}
-
-//
-// If we found "our" device, register a callback routine
-//
-
- if (FoundMIDIref >= 0) {
- MIDIClientRef client = 0;
- MIDIPortRef myMIDIport = 0;
- //Create client
- MIDIClientCreate(CFSTR("piHPSDR"),NULL,NULL, &client);
- MIDIInputPortCreate(client, CFSTR("FromMIDI"), ReadMIDIdevice, NULL, &myMIDIport);
- MIDIPortConnectSource(myMIDIport,MIDIGetSource(FoundMIDIref), NULL);
+ g_print("%s: number of devices=%d\n",__FUNCTION__,n_midi_devices);
+ //
+ // Get rid of all devices lingering around above the high-water mark
+ // (this happens in the case of hot-unplugging)
+ //
+ for (i=n_midi_devices; i<MAX_MIDI_DEVICES; i++) {
+ if (midi_devices[i].active) {
+ close_midi_device(i);
+ }
+ if (midi_devices[i].name != NULL) {
+ g_free(midi_devices[i].name);
+ midi_devices[i].name=NULL;
+ }
}
}
+
+void configure_midi_device(gboolean state) {
+ configure=state;
+}
+
#endif
#include <sys/utsname.h>
extern struct utsname unameData;
+enum {
+ NO_CONTROLLER,
+ CONTROLLER1,
+ CONTROLLER2_V1,
+ CONTROLLER2_V2
+};
+
+extern gint controller;
+
extern gint display_width;
extern gint display_height;
extern gint full_screen;
MIDI_ACTION_ANF, // ANF: toggel ANF on/off
MIDI_ACTION_ATT, // ATT: Step attenuator or Programmable attenuator
MIDI_ACTION_VFO_B2A, // B2A: VFO B -> A
+ MIDI_ACTION_BAND_10, // BAND10
+ MIDI_ACTION_BAND_12, // BAND12
+ MIDI_ACTION_BAND_1240, // BAND1240
+ MIDI_ACTION_BAND_144, // BAND144
+ MIDI_ACTION_BAND_15, // BAND15
+ MIDI_ACTION_BAND_160, // BAND160
+ MIDI_ACTION_BAND_17, // BAND17
+ MIDI_ACTION_BAND_20, // BAND20
+ MIDI_ACTION_BAND_220, // BAND220
+ MIDI_ACTION_BAND_2300, // BAND2300
+ MIDI_ACTION_BAND_30, // BAND30
+ MIDI_ACTION_BAND_3400, // BAND3400
+ MIDI_ACTION_BAND_40, // BAND40
+ MIDI_ACTION_BAND_430, // BAND430
+ MIDI_ACTION_BAND_6, // BAND6
+ MIDI_ACTION_BAND_60, // BAND60
+ MIDI_ACTION_BAND_70, // BAND70
+ MIDI_ACTION_BAND_80, // BAND80
+ MIDI_ACTION_BAND_902, // BAND902
+ MIDI_ACTION_BAND_AIR, // BANDAIR
MIDI_ACTION_BAND_DOWN, // BANDDOWN: cycle through bands downwards
+ MIDI_ACTION_BAND_GEN, // BANDGEN
MIDI_ACTION_BAND_UP, // BANDUP: cycle through bands upwards
+ MIDI_ACTION_BAND_WWV, // BANDWWVUP: cycle through bands upwards
MIDI_ACTION_COMPRESS, // COMPRESS: TX compressor value
MIDI_ACTION_CTUN, // CTUN: toggle CTUN on/off
MIDI_ACTION_VFO, // CURRVFO: change VFO frequency
- MIDI_ACTION_CWKEY, // CWKEY: Unconditional CW key-down/up (outside keyer)
- MIDI_ACTION_CWL, // CWL: Left paddle pressed (use with ONOFF)
- MIDI_ACTION_CWR, // CWR: Right paddle pressed (use with ONOFF)
+ MIDI_ACTION_CWKEYER, // CW(Keyer): Unconditional CW key-down/up (outside keyer)
+ MIDI_ACTION_CWLEFT, // CWLEFT: Left paddle pressed (use with ONOFF)
+ MIDI_ACTION_CWRIGHT, // CWRIGHT: Right paddle pressed (use with ONOFF)
MIDI_ACTION_CWSPEED, // CWSPEED: Set speed of (iambic) CW keyer
MIDI_ACTION_DIV_COARSEGAIN, // DIVCOARSEGAIN: change DIVERSITY gain in large increments
- MIDI_ACTION_DIV_COARSEPHASE, // DIVPHASE: change DIVERSITY phase in large increments
+ MIDI_ACTION_DIV_COARSEPHASE, // DIVCOARSEPHASE: change DIVERSITY phase in large increments
MIDI_ACTION_DIV_FINEGAIN, // DIVFINEGAIN: change DIVERSITY gain in small increments
MIDI_ACTION_DIV_FINEPHASE, // DIVFINEPHASE: change DIVERSITY phase in small increments
MIDI_ACTION_DIV_GAIN, // DIVGAIN: change DIVERSITY gain in medium increments
MIDI_ACTION_FILTER_DOWN, // FILTERDOWN: cycle through filters downwards
MIDI_ACTION_FILTER_UP, // FILTERUP: cycle through filters upwards
MIDI_ACTION_LOCK, // LOCK: lock VFOs, disable frequency changes
+ MIDI_ACTION_MEM_RECALL_M0, // RECALLM0: load current freq/mode/filter from memory slot #0
+ MIDI_ACTION_MEM_RECALL_M1, // RECALLM1: load current freq/mode/filter from memory slot #1
+ MIDI_ACTION_MEM_RECALL_M2, // RECALLM2: load current freq/mode/filter from memory slot #2
+ MIDI_ACTION_MEM_RECALL_M3, // RECALLM3: load current freq/mode/filter from memory slot #3
+ MIDI_ACTION_MEM_RECALL_M4, // RECALLM4: load current freq/mode/filter from memory slot #4
+ MIDI_ACTION_MENU_FILTER, // MENU_FILTER
+ MIDI_ACTION_MENU_MODE, // MENU_MODE
MIDI_ACTION_MIC_VOLUME, // MICGAIN: MIC gain
MIDI_ACTION_MODE_DOWN, // MODEDOWN: cycle through modes downwards
MIDI_ACTION_MODE_UP, // MODEUP: cycle through modes upwards
MIDI_ACTION_MUTE, // MUTE: toggle mute on/off
MIDI_ACTION_NB, // NOISEBLANKER: cycle through NoiseBlanker states (none, NB, NB2)
MIDI_ACTION_NR, // NOISEREDUCTION: cycle through NoiseReduction states (none, NR, NR2)
+ MIDI_ACTION_NUMPAD_0, // NUMPAD0
+ MIDI_ACTION_NUMPAD_1, // NUMPAD1
+ MIDI_ACTION_NUMPAD_2, // NUMPAD2
+ MIDI_ACTION_NUMPAD_3, // NUMPAD3
+ MIDI_ACTION_NUMPAD_4, // NUMPAD4
+ MIDI_ACTION_NUMPAD_5, // NUMPAD5
+ MIDI_ACTION_NUMPAD_6, // NUMPAD6
+ MIDI_ACTION_NUMPAD_7, // NUMPAD7
+ MIDI_ACTION_NUMPAD_8, // NUMPAD8
+ MIDI_ACTION_NUMPAD_9, // NUMPAD9
+ MIDI_ACTION_NUMPAD_CL, // NUMPADCL
+ MIDI_ACTION_NUMPAD_ENTER, // NUMPADENTER
MIDI_ACTION_PAN, // PAN: change panning of panadater/waterfall when zoomed
MIDI_ACTION_PAN_HIGH, // PANHIGH: "high" value of current panadapter
MIDI_ACTION_PAN_LOW, // PANLOW: "low" value of current panadapter
MIDI_ACTION_PRE, // PREAMP: preamp on/off
- MIDI_ACTION_PTTONOFF, // PTT: set PTT state to "on" or "off"
+ MIDI_ACTION_PTTKEYER, // PTT(Keyer): set PTT state to "on" or "off"
MIDI_ACTION_PS, // PURESIGNAL: toggle PURESIGNAL on/off
- MIDI_ACTION_MEM_RECALL_M0, // RECALLM0: load current freq/mode/filter from memory slot #0
- MIDI_ACTION_MEM_RECALL_M1, // RECALLM1: load current freq/mode/filter from memory slot #1
- MIDI_ACTION_MEM_RECALL_M2, // RECALLM2: load current freq/mode/filter from memory slot #2
- MIDI_ACTION_MEM_RECALL_M3, // RECALLM3: load current freq/mode/filter from memory slot #3
- MIDI_ACTION_MEM_RECALL_M4, // RECALLM4: load current freq/mode/filter from memory slot #4
MIDI_ACTION_RF_GAIN, // RFGAIN: receiver RF gain
MIDI_ACTION_TX_DRIVE, // RFPOWER: adjust TX RF output power
MIDI_ACTION_RIT_CLEAR, // RITCLEAR: clear RIT and XIT value
MIDI_ACTION_ZOOM, // ZOOM: change zoom factor
MIDI_ACTION_ZOOM_UP, // ZOOMUP: change zoom factor
MIDI_ACTION_ZOOM_DOWN, // ZOOMDOWN: change zoom factor
+ MIDI_ACTION_LAST, // flag for end of list
};
//
//
enum MIDItype {
- MIDI_TYPE_NONE=0,
- MIDI_TYPE_KEY, // Button (press event)
- MIDI_TYPE_KNOB, // Knob (value between 0 and 100)
- MIDI_TYPE_WHEEL // Wheel (direction and speed)
+ MIDI_TYPE_NONE =0,
+ MIDI_TYPE_KEY =1, // Button (press event)
+ MIDI_TYPE_KNOB =2, // Knob (value between 0 and 100)
+ MIDI_TYPE_WHEEL=4 // Wheel (direction and speed)
};
+extern gchar *midi_types[];
+extern gchar *midi_events[];
+
//
// MIDIevent encodes the actual MIDI event "seen" in Layer-1 and
// passed to Layer-2. MIDI_NOTE events end up as MIDI_KEY and
MIDI_EVENT_PITCH
};
+typedef struct _action_table {
+ enum MIDIaction action;
+ const char *str;
+ enum MIDItype type;
+ int onoff;
+} ACTION_TABLE;
+
+extern ACTION_TABLE ActionTable[];
+
//
// Data structure for Layer-2
//
struct desc *next; // Next defined action for a controller/key with that note value (NULL for end of list)
};
-struct cmdtable{
- struct desc *desc[128]; // description for Note On/Off and ControllerChange
- struct desc *pitch; // description for PitchChanges
-};
+extern struct desc *MidiCommandsTable[129];
+
+extern int midi_debug;
//
// Layer-1 entry point, called once for all the MIDI devices
// that have been defined. This is called upon startup by
// Layer-2 through the function MIDIstartup.
//
-void register_midi_device(char *name);
+void register_midi_device(int index);
+void close_midi_device(int index);
+void configure_midi_device(gboolean state);
//
// Layer-2 entry point (called by Layer1)
// for each device description that was successfully read.
void NewMidiEvent(enum MIDIevent event, int channel, int note, int val);
-void MIDIstartup();
+int MIDIstartup(char *filename);
+void MidiAddCommand(int note, struct desc *desc);
+void MidiReleaseCommands();
//
// Layer-3 entry point (called by Layer2). In Layer-3, all the pihpsdr
*/
#include <gtk/gtk.h>
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "MacOS.h" // emulate clock_gettime on old MacOS systems
#endif
+#include "receiver.h"
+#include "discovered.h"
+#include "adc.h"
+#include "dac.h"
+#include "transmitter.h"
+#include "radio.h"
+#include "main.h"
#include "midi.h"
+#include "alsa_midi.h"
-static double midi_startup_time;
-static int midi_wait_startup=0;
-
-struct cmdtable MidiCommandsTable;
+struct desc *MidiCommandsTable[129];
void NewMidiEvent(enum MIDIevent event, int channel, int note, int val) {
//now=ts.tv_sec + 1E-9*ts.tv_nsec;
//g_print("%s:%12.3f:EVENT=%d CHAN=%d NOTE=%d VAL=%d\n",__FUNCTION__,now,event,channel,note,val);
- //
- // the midi_wait_startup/midi_startup_time mechanism takes care that in the first
- // second after registering a MIDI device, all incoming MIDI messages are just discarded.
- // This has been introduced since sometimes "old" MIDI messages are lingering around in the
- // the system and get delivered immediately after registering the MIDI device.
- // The midi_wait_startup variable takes care that we do not check the clock again and again
- // after the first second.
- //
- if (midi_wait_startup) {
- clock_gettime(CLOCK_MONOTONIC, &ts);
- now=ts.tv_sec + 1E-9*ts.tv_nsec;
- if (now < midi_startup_time + 1.0) return;
- midi_wait_startup=0;
- }
if (event == MIDI_EVENT_PITCH) {
- desc=MidiCommandsTable.pitch;
+ desc=MidiCommandsTable[128];
} else {
- desc=MidiCommandsTable.desc[note];
+ desc=MidiCommandsTable[note];
}
-//fprintf(stderr,"MIDI:init DESC=%p\n",desc);
+//g_print("MIDI:init DESC=%p\n",desc);
while (desc) {
-//fprintf(stderr,"DESC=%p next=%p CHAN=%d EVENT=%d\n", desc,desc->next,desc->channel,desc->event);
+//g_print("DESC=%p next=%p CHAN=%d EVENT=%d\n", desc,desc->next,desc->channel,desc->event);
if ((desc->channel == channel || desc->channel == -1) && (desc->event == event)) {
// Found matching entry
switch (desc->event) {
if (delta < desc->delay) break;
last_wheel_tp = tp;
}
- // translate value to direction
+ // translate value to direction/speed
new=0;
- if ((val >= desc->vfl1) && (val <= desc->vfl2)) new=-100;
- if ((val >= desc-> fl1) && (val <= desc-> fl2)) new=-10;
+ if ((val >= desc->vfl1) && (val <= desc->vfl2)) new=-16;
+ if ((val >= desc-> fl1) && (val <= desc-> fl2)) new=-4;
if ((val >= desc->lft1) && (val <= desc->lft2)) new=-1;
if ((val >= desc->rgt1) && (val <= desc->rgt2)) new= 1;
- if ((val >= desc-> fr1) && (val <= desc-> fr2)) new= 10;
- if ((val >= desc->vfr1) && (val <= desc->vfr2)) new= 100;
-// fprintf(stderr,"WHEEL: val=%d new=%d thrs=%d/%d, %d/%d, %d/%d, %d/%d, %d/%d, %d/%d\n",
-// val, new, desc->vfl1, desc->vfl2, desc->fl1, desc->fl2, desc->lft1, desc->lft2,
-// desc->rgt1, desc->rgt2, desc->fr1, desc->fr2, desc->vfr1, desc->vfr2);
+ if ((val >= desc-> fr1) && (val <= desc-> fr2)) new= 4;
+ if ((val >= desc->vfr1) && (val <= desc->vfr2)) new= 16;
+// g_print("WHEEL: val=%d new=%d thrs=%d/%d, %d/%d, %d/%d, %d/%d, %d/%d, %d/%d\n",
+// val, new, desc->vfl1, desc->vfl2, desc->fl1, desc->fl2, desc->lft1, desc->lft2,
+// desc->rgt1, desc->rgt2, desc->fr1, desc->fr2, desc->vfr1, desc->vfr2);
if (new != 0) DoTheMidi(desc->action, desc->type, new);
last_wheel_action=desc->action;
}
}
if (!desc) {
// Nothing found. This is nothing to worry about, but log the key to stderr
- if (event == MIDI_EVENT_PITCH) fprintf(stderr, "Unassigned PitchBend Value=%d\n", val);
- if (event == MIDI_EVENT_NOTE ) fprintf(stderr, "Unassigned Key Note=%d Val=%d\n", note, val);
- if (event == MIDI_EVENT_CTRL ) fprintf(stderr, "Unassigned Controller Ctl=%d Val=%d\n", note, val);
+ if (event == MIDI_EVENT_PITCH) g_print("Unassigned PitchBend Value=%d\n", val);
+ if (event == MIDI_EVENT_NOTE ) g_print("Unassigned Key Note=%d Val=%d\n", note, val);
+ if (event == MIDI_EVENT_CTRL ) g_print("Unassigned Controller Ctl=%d Val=%d\n", note, val);
}
}
+gchar *midi_types[] = {"NONE","KEY","KNOB/SLIDER","*INVALID*","WHEEL"};
+gchar *midi_events[] = {"NONE","NOTE","CTRL","PITCH"};
+
/*
* This data structre connects names as used in the midi.props file with
* our MIDIaction enum values.
- * Take care that no key word is contained in another one!
- * Example: use "CURRVFO" not "VFO" otherwise there is possibly
- * a match for "VFO" when the key word is "VFOA".
+ *
+ * At some places in the code, it is assumes that ActionTable[i].action == i
+ * so keep the entries strictly in the order the enum is defined, and
+ * add one entry with ACTION_NONE at the end.
*/
-static struct {
- enum MIDIaction action; // the MIDI action
- const char *str; // the key word in the midi.props file
- int onoff; // =1 if action both on press + release
-} ActionTable[] = {
- { MIDI_ACTION_VFO_A2B, "A2B", 0},
- { MIDI_ACTION_AF_GAIN, "AFGAIN", 0},
- { MIDI_ACTION_AGCATTACK, "AGCATTACK", 0},
- { MIDI_ACTION_AGC, "AGCVAL", 0},
- { MIDI_ACTION_ANF, "ANF", 0},
- { MIDI_ACTION_ATT, "ATT", 0},
- { MIDI_ACTION_VFO_B2A, "B2A", 0},
- { MIDI_ACTION_BAND_DOWN, "BANDDOWN", 0},
- { MIDI_ACTION_BAND_UP, "BANDUP", 0},
- { MIDI_ACTION_COMPRESS, "COMPRESS", 0},
- { MIDI_ACTION_CTUN, "CTUN", 0},
- { MIDI_ACTION_VFO, "CURRVFO", 0},
- { MIDI_ACTION_CWKEY, "CWKEY", 1},
- { MIDI_ACTION_CWL, "CWL", 1},
- { MIDI_ACTION_CWR, "CWR", 1},
- { MIDI_ACTION_CWSPEED, "CWSPEED", 0},
- { MIDI_ACTION_DIV_COARSEGAIN, "DIVCOARSEGAIN", 0},
- { MIDI_ACTION_DIV_COARSEPHASE, "DIVCOARSEPHASE", 0},
- { MIDI_ACTION_DIV_FINEGAIN, "DIVFINEGAIN", 0},
- { MIDI_ACTION_DIV_FINEPHASE, "DIVFINEPHASE", 0},
- { MIDI_ACTION_DIV_GAIN, "DIVGAIN", 0},
- { MIDI_ACTION_DIV_PHASE, "DIVPHASE", 0},
- { MIDI_ACTION_DIV_TOGGLE, "DIVTOGGLE", 0},
- { MIDI_ACTION_DUP, "DUP", 0},
- { MIDI_ACTION_FILTER_DOWN, "FILTERDOWN", 0},
- { MIDI_ACTION_FILTER_UP, "FILTERUP", 0},
- { MIDI_ACTION_LOCK, "LOCK", 0},
- { MIDI_ACTION_MIC_VOLUME, "MICGAIN", 0},
- { MIDI_ACTION_MODE_DOWN, "MODEDOWN", 0},
- { MIDI_ACTION_MODE_UP, "MODEUP", 0},
- { MIDI_ACTION_MOX, "MOX", 0},
- { MIDI_ACTION_MUTE, "MUTE", 0},
- { MIDI_ACTION_NB, "NOISEBLANKER", 0},
- { MIDI_ACTION_NR, "NOISEREDUCTION", 0},
- { MIDI_ACTION_PAN, "PAN", 0},
- { MIDI_ACTION_PAN_HIGH, "PANHIGH", 0},
- { MIDI_ACTION_PAN_LOW, "PANLOW", 0},
- { MIDI_ACTION_PRE, "PREAMP", 0},
- { MIDI_ACTION_PTTONOFF, "PTT", 1},
- { MIDI_ACTION_PS, "PURESIGNAL", 0},
- { MIDI_ACTION_MEM_RECALL_M0, "RECALLM0", 0},
- { MIDI_ACTION_MEM_RECALL_M1, "RECALLM1", 0},
- { MIDI_ACTION_MEM_RECALL_M2, "RECALLM2", 0},
- { MIDI_ACTION_MEM_RECALL_M3, "RECALLM3", 0},
- { MIDI_ACTION_MEM_RECALL_M4, "RECALLM4", 0},
- { MIDI_ACTION_RF_GAIN, "RFGAIN", 0},
- { MIDI_ACTION_TX_DRIVE, "RFPOWER", 0},
- { MIDI_ACTION_RIT_CLEAR, "RITCLEAR", 0},
- { MIDI_ACTION_RIT_STEP, "RITSTEP", 0},
- { MIDI_ACTION_RIT_TOGGLE, "RITTOGGLE", 0},
- { MIDI_ACTION_RIT_VAL, "RITVAL", 0},
- { MIDI_ACTION_SAT, "SAT", 0},
- { MIDI_ACTION_SNB, "SNB", 0},
- { MIDI_ACTION_SPLIT, "SPLIT", 0},
- { MIDI_ACTION_MEM_STORE_M0, "STOREM0", 0},
- { MIDI_ACTION_MEM_STORE_M1, "STOREM1", 0},
- { MIDI_ACTION_MEM_STORE_M2, "STOREM2", 0},
- { MIDI_ACTION_MEM_STORE_M3, "STOREM3", 0},
- { MIDI_ACTION_MEM_STORE_M4, "STOREM4", 0},
- { MIDI_ACTION_SWAP_RX, "SWAPRX", 0},
- { MIDI_ACTION_SWAP_VFO, "SWAPVFO", 0},
- { MIDI_ACTION_TUNE, "TUNE", 0},
- { MIDI_ACTION_VFOA, "VFOA", 0},
- { MIDI_ACTION_VFOB, "VFOB", 0},
- { MIDI_ACTION_VFO_STEP_UP, "VFOSTEPUP", 0},
- { MIDI_ACTION_VFO_STEP_DOWN, "VFOSTEPDOWN", 0},
- { MIDI_ACTION_VOX, "VOX", 0},
- { MIDI_ACTION_VOXLEVEL, "VOXLEVEL", 0},
- { MIDI_ACTION_XIT_CLEAR, "XITCLEAR", 0},
- { MIDI_ACTION_XIT_VAL, "XITVAL", 0},
- { MIDI_ACTION_ZOOM, "ZOOM", 0},
- { MIDI_ACTION_ZOOM_UP, "ZOOMUP", 0},
- { MIDI_ACTION_ZOOM_DOWN, "ZOOMDOWN", 0},
- { MIDI_ACTION_NONE, "NONE", 0}
+ACTION_TABLE ActionTable[] = {
+ { MIDI_ACTION_NONE, "NONE", MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_VFO_A2B, "A2B", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_AF_GAIN, "AFGAIN", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_AGCATTACK, "AGCATTACK", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_AGC, "AGCVAL", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_ANF, "ANF", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_ATT, "ATT", MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_VFO_B2A, "B2A", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_10, "BAND10", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_12, "BAND12", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_1240, "BAND1240", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_144, "BAND144", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_15, "BAND15", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_160, "BAND160", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_17, "BAND17", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_20, "BAND20", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_220, "BAND220", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_2300, "BAND2300", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_30, "BAND30", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_3400, "BAND3400", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_40, "BAND40", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_430, "BAND430", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_6, "BAND6", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_60, "BAND60", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_70, "BAND70", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_80, "BAND80", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_902, "BAND902", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_AIR, "BANDAIR", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_DOWN, "BANDDOWN", MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_BAND_GEN, "BANDGEN", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_BAND_UP, "BANDUP", MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_BAND_WWV, "BANDWWV", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_COMPRESS, "COMPRESS", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_CTUN, "CTUN", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_VFO, "CURRVFO", MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_CWKEYER, "CW(Keyer)", MIDI_TYPE_KEY, 1},
+ { MIDI_ACTION_CWLEFT, "CWLEFT", MIDI_TYPE_KEY, 1},
+ { MIDI_ACTION_CWRIGHT, "CWRIGHT", MIDI_TYPE_KEY, 1},
+ { MIDI_ACTION_CWSPEED, "CWSPEED", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_DIV_COARSEGAIN, "DIVCOARSEGAIN", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_DIV_COARSEPHASE, "DIVCOARSEPHASE", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_DIV_FINEGAIN, "DIVFINEGAIN", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_DIV_FINEPHASE, "DIVFINEPHASE", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_DIV_GAIN, "DIVGAIN", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_DIV_PHASE, "DIVPHASE", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_DIV_TOGGLE, "DIVTOGGLE", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_DUP, "DUP", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_FILTER_DOWN, "FILTERDOWN", MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_FILTER_UP, "FILTERUP", MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_LOCK, "LOCK", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MEM_RECALL_M0, "RECALLM0", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MEM_RECALL_M1, "RECALLM1", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MEM_RECALL_M2, "RECALLM2", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MEM_RECALL_M3, "RECALLM3", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MEM_RECALL_M4, "RECALLM4", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MENU_FILTER, "MENU_FILTER", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MENU_MODE, "MENU_MODE", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MIC_VOLUME, "MICGAIN", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_MODE_DOWN, "MODEDOWN", MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_MODE_UP, "MODEUP", MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_MOX, "MOX", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MUTE, "MUTE", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NB, "NOISEBLANKER", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NR, "NOISEREDUCTION", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NUMPAD_0, "NUMPAD0", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NUMPAD_1, "NUMPAD1", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NUMPAD_2, "NUMPAD2", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NUMPAD_3, "NUMPAD3", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NUMPAD_4, "NUMPAD4", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NUMPAD_5, "NUMPAD5", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NUMPAD_6, "NUMPAD6", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NUMPAD_7, "NUMPAD7", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NUMPAD_8, "NUMPAD8", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NUMPAD_9, "NUMPAD9", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NUMPAD_CL, "NUMPADCL", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_NUMPAD_ENTER, "NUMPADENTER", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_PAN, "PAN", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_PAN_HIGH, "PANHIGH", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_PAN_LOW, "PANLOW", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_PRE, "PREAMP", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_PTTKEYER, "PTT(Keyer)", MIDI_TYPE_KEY, 1},
+ { MIDI_ACTION_PS, "PURESIGNAL", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_RF_GAIN, "RFGAIN", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_TX_DRIVE, "RFPOWER", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_RIT_CLEAR, "RITCLEAR", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_RIT_STEP, "RITSTEP", MIDI_TYPE_KEY|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_RIT_TOGGLE, "RITTOGGLE", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_RIT_VAL, "RITVAL", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_SAT, "SAT", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_SNB, "SNB", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_SPLIT, "SPLIT", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MEM_STORE_M0, "STOREM0", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MEM_STORE_M1, "STOREM1", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MEM_STORE_M2, "STOREM2", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MEM_STORE_M3, "STOREM3", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_MEM_STORE_M4, "STOREM4", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_SWAP_RX, "SWAPRX", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_SWAP_VFO, "SWAPVFO", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_TUNE, "TUNE", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_VFOA, "VFOA", MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_VFOB, "VFOB", MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_VFO_STEP_UP, "VFOSTEPUP", MIDI_TYPE_KEY|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_VFO_STEP_DOWN, "VFOSTEPDOWN", MIDI_TYPE_KEY|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_VOX, "VOX", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_VOXLEVEL, "VOXLEVEL", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_XIT_CLEAR, "XITCLEAR", MIDI_TYPE_KEY, 0},
+ { MIDI_ACTION_XIT_VAL, "XITVAL", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_ZOOM, "ZOOM", MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_ZOOM_UP, "ZOOMUP", MIDI_TYPE_KEY|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_ZOOM_DOWN, "ZOOMDOWN", MIDI_TYPE_KEY|MIDI_TYPE_WHEEL, 0},
+ { MIDI_ACTION_LAST, "NONE", MIDI_TYPE_NONE, 0},
};
+
/*
* Translation from keyword in midi.props file to MIDIaction
*/
*onoff = 0;
}
+int MIDIstop() {
+ for (int i=0; i<n_midi_devices; i++) {
+ if (midi_devices[i].active) {
+ close_midi_device(i);
+ }
+ }
+ return 0;
+}
+
/*
- * Here we read in a MIDI description file "midi.def" and fill the MidiCommandsTable
+ * Release data from MidiCommandsTable
+ */
+
+void MidiReleaseCommands() {
+ int i;
+ struct desc *loop, *new;
+ for (i=0; i<129; i++) {
+ loop = MidiCommandsTable[i];
+ while (loop != NULL) {
+ new=loop->next;
+ free(loop);
+ loop = new;
+ }
+ MidiCommandsTable[i]=NULL;
+ }
+}
+
+/*
+ * Add a command to MidiCommandsTable
+ */
+
+void MidiAddCommand(int note, struct desc *desc) {
+ struct desc *loop;
+
+ if (note < 0 || note > 128) return;
+
+ //
+ // Actions with channel == -1 (ANY) must go to the end of the list
+ //
+ if (MidiCommandsTable[note] == NULL) {
+ // initialize linked list
+ MidiCommandsTable[note]=desc;
+ } else if (desc->channel >= 0) {
+ // add to top of the list
+ desc->next = MidiCommandsTable[note];
+ MidiCommandsTable[note]=desc;
+ } else {
+ // add to tail of the list
+ loop = MidiCommandsTable[note];
+ while (loop->next != NULL) {
+ loop = loop->next;
+ }
+ loop->next=desc;
+ }
+}
+
+/*
+ * Here we read in a MIDI description file and fill the MidiCommandsTable
* data structure
*/
-void MIDIstartup() {
+int MIDIstartup(char *filename) {
FILE *fpin;
char zeile[255];
char *cp,*cq;
enum MIDIevent event;
int i;
char c;
- struct timespec ts;
- for (i=0; i<128; i++) MidiCommandsTable.desc[i]=NULL;
- MidiCommandsTable.pitch=NULL;
+ MidiReleaseCommands();
- fpin=fopen("midi.props", "r");
- if (!fpin) return;
+ g_print("%s: %s\n",__FUNCTION__,filename);
+ fpin=fopen(filename, "r");
+
+ g_print("%s: fpin=%p\n",__FUNCTION__,fpin);
+ if (!fpin) {
+ g_print("%s: failed to open MIDI device\n",__FUNCTION__);
+ return -1;
+ }
for (;;) {
if (fgets(zeile, 255, fpin) == NULL) break;
cp++;
}
-//fprintf(stderr,"\nMIDI:INP:%s\n",zeile);
-
- if ((cp = strstr(zeile, "DEVICE="))) {
- // Delete comments and trailing blanks
- cq=cp+7;
- while (*cq != 0 && *cq != '#') cq++;
- *cq--=0;
- while (cq > cp+7 && (*cq == ' ' || *cq == '\t')) cq--;
- *(cq+1)=0;
-//fprintf(stderr,"MIDI:REG:>>>%s<<<\n",cp+7);
- midi_wait_startup=1;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- midi_startup_time=ts.tv_sec + 1E-9*ts.tv_nsec;
- register_midi_device(cp+7);
- continue; // nothing more in this line
- }
+g_print("\n%s:INP:%s\n",__FUNCTION__,zeile);
+
chan=-1; // default: any channel
t1=t3=t5=t7= t9=t11=128; // range that never occurs
t2=t4=t6=t8=t10=t12=-1; // range that never occurs
+ onoff=0;
event=MIDI_EVENT_NONE;
type=MIDI_TYPE_NONE;
key=0;
delay=0;
- onoff=0;
//
// The KEY=, CTRL=, and PITCH= cases are mutually exclusive
sscanf(cp+4, "%d", &key);
event=MIDI_EVENT_NOTE;
type=MIDI_TYPE_KEY;
-//fprintf(stderr,"MIDI:KEY:%d\n", key);
+g_print("%s: MIDI:KEY:%d\n",__FUNCTION__, key);
}
if ((cp = strstr(zeile, "CTRL="))) {
sscanf(cp+5, "%d", &key);
event=MIDI_EVENT_CTRL;
type=MIDI_TYPE_KNOB;
-//fprintf(stderr,"MIDI:CTL:%d\n", key);
+g_print("%s: MIDI:CTL:%d\n",__FUNCTION__, key);
}
if ((cp = strstr(zeile, "PITCH "))) {
event=MIDI_EVENT_PITCH;
type=MIDI_TYPE_KNOB;
-//fprintf(stderr,"MIDI:PITCH\n");
+g_print("%s: MIDI:PITCH\n",__FUNCTION__);
}
//
// If event is still undefined, skip line
sscanf(cp+5, "%d", &chan);
chan--;
if (chan<0 || chan>15) chan=-1;
-//fprintf(stderr,"MIDI:CHA:%d\n",chan);
+g_print("%s:CHAN:%d\n",__FUNCTION__,chan);
}
if ((cp = strstr(zeile, "WHEEL")) && (type == MIDI_TYPE_KNOB)) {
// change type from MIDI_TYPE_KNOB to MIDI_TYPE_WHEEL
type=MIDI_TYPE_WHEEL;
-//fprintf(stderr,"MIDI:WHEEL\n");
+g_print("%s:WHEEL\n",__FUNCTION__);
}
if ((cp = strstr(zeile, "DELAY="))) {
sscanf(cp+6, "%d", &delay);
-//fprintf(stderr,"MIDI:DELAY:%d\n",delay);
+g_print("%s:DELAY:%d\n",__FUNCTION__,delay);
}
if ((cp = strstr(zeile, "THR="))) {
sscanf(cp+4, "%d %d %d %d %d %d %d %d %d %d %d %d",
while (*cq != 0 && *cq != '\n' && *cq != ' ' && *cq != '\t') cq++;
*cq=0;
keyword2action(cp+7, &action, &onoff);
-//fprintf(stderr,"MIDI:ACTION:%s (%d), onoff=%d\n",cp+7, action, onoff);
+g_print("MIDI:ACTION:%s (%d), onoff=%d\n",cp+7, action, onoff);
}
//
// All data for a descriptor has been read. Construct it!
//
if (event == MIDI_EVENT_PITCH) {
//fprintf(stderr,"MIDI:TAB:Insert desc=%p in PITCH table\n",desc);
- dp = MidiCommandsTable.pitch;
- if (dp == NULL) {
- MidiCommandsTable.pitch = desc;
- } else {
- while (dp->next != NULL) dp=dp->next;
- dp->next=desc;
- }
+ MidiAddCommand(129, desc);
}
if (event == MIDI_EVENT_NOTE || event == MIDI_EVENT_CTRL) {
-//fprintf(stderr,"MIDI:TAB:Insert desc=%p in CMDS[%d] table\n",desc,key);
- dp = MidiCommandsTable.desc[key];
- if (dp == NULL) {
- MidiCommandsTable.desc[key]=desc;
- } else {
- while (dp->next != NULL) dp=dp->next;
- dp->next=desc;
- }
+g_print("%s:TAB:Insert desc=%p in CMDS[%d] table\n",__FUNCTION__,desc,key);
+ MidiAddCommand(key, desc);
}
}
+ return 0;
}
// code below, one can queue the "big switch statement" into the GTK
// idle queue and exectue all GUI functions directly.
//
-// However, this is not wanted for CWKEY, CWL and CWR since
+// However, this is not wanted for CWKEYER, CWLEFT and CWRIGHT since
// these have to be processed with minimal delay (and do not call GUI functions).
//
// Therefore, these three cases are already handled in the MIDI callback
static int DoTheRestOfTheMIDI(void *data);
void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
- if (action == MIDI_ACTION_CWKEY) {
+ if (action == MIDI_ACTION_CWKEYER) {
//
// This is a CW key-up/down which uses functions from the keyer
// that by-pass the interrupt-driven standard action.
// MIDI using this command.
//
// NO BREAK-IN! The keyer has to take care of sending MIDI PTT
- // on/off messages at appropriate times.
+ // on/off messages at appropriate times, or the operator has to
+ // manually engage/disengage PTT
//
// Since this if for immediate key-down, it does not rely on LOCALCW
//
return;
}
#ifdef LOCALCW
- if (action == MIDI_ACTION_CWL) {
+ if (action == MIDI_ACTION_CWLEFT) {
keyer_event(1, val);
return;
}
- if (action == MIDI_ACTION_CWR) {
+ if (action == MIDI_ACTION_CWRIGHT) {
keyer_event(0, val);
return;
}
MIDIcmd *cmd = (MIDIcmd *)data;
int new;
+ int id, c25;
double dnew;
enum MIDIaction action = cmd->action;
switch (action) {
/////////////////////////////////////////////////////////// "A2B"
case MIDI_ACTION_VFO_A2B: // only key supported
- if (type == MIDI_TYPE_KEY) {
- vfo_a_to_b();
- }
+ vfo_a_to_b();
break;
/////////////////////////////////////////////////////////// "AFGAIN"
case MIDI_ACTION_AF_GAIN: // knob or wheel supported
/////////////////////////////////////////////////////////// "AGCATTACK"
case MIDI_ACTION_AGCATTACK: // only key supported
// cycle through fast/med/slow AGC attack
- if (type == MIDI_TYPE_KEY) {
- new=active_receiver->agc + 1;
- if (new > AGC_FAST) new=0;
- active_receiver->agc=new;
- vfo_update();
- }
+ new=active_receiver->agc + 1;
+ if (new > AGC_FAST) new=0;
+ active_receiver->agc=new;
+ vfo_update();
break;
/////////////////////////////////////////////////////////// "AGCVAL"
case MIDI_ACTION_AGC: // knob or wheel supported
break;
/////////////////////////////////////////////////////////// "ANF"
case MIDI_ACTION_ANF: // only key supported
- if (type == MIDI_TYPE_KEY) {
- if (active_receiver->anf==0) {
- active_receiver->anf=1;
- mode_settings[vfo[active_receiver->id].mode].anf=1;
- } else {
- active_receiver->snb=0;
- mode_settings[vfo[active_receiver->id].mode].anf=0;
- }
- SetRXAANFRun(active_receiver->id, active_receiver->anf);
- vfo_update();
- }
+ if (active_receiver->anf==0) {
+ active_receiver->anf=1;
+ mode_settings[vfo[active_receiver->id].mode].anf=1;
+ } else {
+ active_receiver->snb=0;
+ mode_settings[vfo[active_receiver->id].mode].anf=0;
+ }
+ SetRXAANFRun(active_receiver->id, active_receiver->anf);
+ vfo_update();
break;
/////////////////////////////////////////////////////////// "ATT"
case MIDI_ACTION_ATT: // Key for ALEX attenuator, wheel or knob for slider
break;
/////////////////////////////////////////////////////////// "B2A"
case MIDI_ACTION_VFO_B2A: // only key supported
- if (type == MIDI_TYPE_KEY) {
- vfo_b_to_a();
- }
+ vfo_b_to_a();
break;
+ /////////////////////////////////////////////////////////// "BANDxxx"
+ case MIDI_ACTION_BAND_10:
+ vfo_band_changed(active_receiver->id, band10);
+ break;
+ case MIDI_ACTION_BAND_12:
+ vfo_band_changed(active_receiver->id, band12);
+ break;
+#ifdef SOAPYSDR
+ case MIDI_ACTION_BAND_1240:
+ vfo_band_changed(active_receiver->id, band1240);
+ break;
+ case MIDI_ACTION_BAND_144:
+ vfo_band_changed(active_receiver->id, band144);
+ break;
+#endif
+ case MIDI_ACTION_BAND_15:
+ vfo_band_changed(active_receiver->id, band15);
+ break;
+ case MIDI_ACTION_BAND_160:
+ vfo_band_changed(active_receiver->id, band160);
+ break;
+ case MIDI_ACTION_BAND_17:
+ vfo_band_changed(active_receiver->id, band17);
+ break;
+ case MIDI_ACTION_BAND_20:
+ vfo_band_changed(active_receiver->id, band20);
+ break;
+#ifdef SOAPYSDR
+ case MIDI_ACTION_BAND_220:
+ vfo_band_changed(active_receiver->id, band220);
+ break;
+ case MIDI_ACTION_BAND_2300:
+ vfo_band_changed(active_receiver->id, band2300);
+ break;
+#endif
+ case MIDI_ACTION_BAND_30:
+ vfo_band_changed(active_receiver->id, band30);
+ break;
+#ifdef SOAPYSDR
+ case MIDI_ACTION_BAND_3400:
+ vfo_band_changed(active_receiver->id, band3400);
+ break;
+#endif
+ case MIDI_ACTION_BAND_40:
+ vfo_band_changed(active_receiver->id, band40);
+ break;
+#ifdef SOAPYSDR
+ case MIDI_ACTION_BAND_430:
+ vfo_band_changed(active_receiver->id, band430);
+ break;
+#endif
+ case MIDI_ACTION_BAND_6:
+ vfo_band_changed(active_receiver->id, band6);
+ break;
+ case MIDI_ACTION_BAND_60:
+ vfo_band_changed(active_receiver->id, band60);
+ break;
+#ifdef SOAPYSDR
+ case MIDI_ACTION_BAND_70:
+ vfo_band_changed(active_receiver->id, band70);
+ break;
+#endif
+ case MIDI_ACTION_BAND_80:
+ vfo_band_changed(active_receiver->id, band80);
+ break;
+#ifdef SOAPYSDR
+ case MIDI_ACTION_BAND_902:
+ vfo_band_changed(active_receiver->id, band902);
+ break;
+ case MIDI_ACTION_BAND_AIR:
+ vfo_band_changed(active_receiver->id, bandAIR);
+ break;
+#endif
+ case MIDI_ACTION_BAND_GEN:
+ vfo_band_changed(active_receiver->id, bandGen);
+ break;
+ case MIDI_ACTION_BAND_WWV:
+ vfo_band_changed(active_receiver->id, bandWWV);
+ break;
/////////////////////////////////////////////////////////// "BANDDOWN"
/////////////////////////////////////////////////////////// "BANDUP"
case MIDI_ACTION_BAND_DOWN:
/////////////////////////////////////////////////////////// "CTUN"
case MIDI_ACTION_CTUN: // only key supported
// toggle CTUN
- if (type == MIDI_TYPE_KEY) {
- int id=active_receiver->id;
- vfo[id].ctun=vfo[id].ctun==1?0:1;
- if(!vfo[id].ctun) {
- vfo[id].offset=0;
- }
- vfo[id].ctun_frequency=vfo[id].frequency;
- set_offset(receiver[id],vfo[id].offset);
- }
+ id=active_receiver->id;
+ vfo[id].ctun=vfo[id].ctun==1?0:1;
+ if(!vfo[id].ctun) {
+ vfo[id].offset=0;
+ }
+ vfo[id].ctun_frequency=vfo[id].frequency;
+ set_offset(receiver[id],vfo[id].offset);
break;
/////////////////////////////////////////////////////////// "CURRVFO"
case MIDI_ACTION_VFO: // only wheel supported
- if (type == MIDI_TYPE_WHEEL && !locked) {
- vfo_step(val);
- }
+ vfo_step(val);
break;
/////////////////////////////////////////////////////////// "CWSPEED"
case MIDI_ACTION_CWSPEED: // knob or wheel
break;
/////////////////////////////////////////////////////////// "DIVTOGGLE"
case MIDI_ACTION_DIV_TOGGLE: // only key supported
- if (type == MIDI_TYPE_KEY) {
- // enable/disable DIVERSITY
- diversity_enabled = diversity_enabled ? 0 : 1;
- vfo_update();
- }
+ // enable/disable DIVERSITY
+ diversity_enabled = diversity_enabled ? 0 : 1;
+ vfo_update();
break;
/////////////////////////////////////////////////////////// "DUP"
case MIDI_ACTION_DUP:
vfo_filter_changed(new);
}
break;
+ /////////////////////////////////////////////////////////// "MENU_FILTER"
+ case MIDI_ACTION_MENU_FILTER:
+ start_filter();
+ break;
+ /////////////////////////////////////////////////////////// "MENU_MODE"
+ case MIDI_ACTION_MENU_MODE:
+ start_mode();
+ break;
/////////////////////////////////////////////////////////// "LOCK"
case MIDI_ACTION_LOCK: // only key supported
- if (type == MIDI_TYPE_KEY) {
- locked=!locked;
- vfo_update();
- }
+ locked=!locked;
+ vfo_update();
break;
/////////////////////////////////////////////////////////// "MICGAIN"
case MIDI_ACTION_MIC_VOLUME: // knob or wheel supported
/////////////////////////////////////////////////////////// "MOX"
case MIDI_ACTION_MOX: // only key supported
// Note this toggles the PTT state without knowing the
- // actual state. See MIDI_ACTION_PTTONOFF for actually
+ // actual state. See MIDI_ACTION_PTTKEYER for actually
// *setting* PTT
- if (type == MIDI_TYPE_KEY && can_transmit) {
+ if (can_transmit) {
new = !mox;
mox_update(new);
}
break;
/////////////////////////////////////////////////////////// "MUTE"
case MIDI_ACTION_MUTE:
- if (type == MIDI_TYPE_KEY) {
- active_receiver->mute_radio=!active_receiver->mute_radio;
- }
+ active_receiver->mute_radio=!active_receiver->mute_radio;
break;
/////////////////////////////////////////////////////////// "NOISEBLANKER"
case MIDI_ACTION_NB: // only key supported
// cycle through NoiseBlanker settings: OFF, NB, NB2
- if (type == MIDI_TYPE_KEY) {
- if (active_receiver->nb) {
- active_receiver->nb = 0;
- active_receiver->nb2= 1;
- } else if (active_receiver->nb2) {
- active_receiver->nb = 0;
- active_receiver->nb2= 0;
- } else {
- active_receiver->nb = 1;
- active_receiver->nb2= 0;
- }
- vfo_update();
+ if (active_receiver->nb) {
+ active_receiver->nb = 0;
+ active_receiver->nb2= 1;
+ } else if (active_receiver->nb2) {
+ active_receiver->nb = 0;
+ active_receiver->nb2= 0;
+ } else {
+ active_receiver->nb = 1;
+ active_receiver->nb2= 0;
}
+ update_noise();
+ vfo_update();
break;
/////////////////////////////////////////////////////////// "NOISEREDUCTION"
case MIDI_ACTION_NR: // only key supported
// cycle through NoiseReduction settings: OFF, NR1, NR2
- if (type == MIDI_TYPE_KEY) {
- if (active_receiver->nr) {
- active_receiver->nr = 0;
- active_receiver->nr2= 1;
- } else if (active_receiver->nr2) {
- active_receiver->nr = 0;
- active_receiver->nr2= 0;
- } else {
- active_receiver->nr = 1;
- active_receiver->nr2= 0;
- }
- update_noise();
- vfo_update();
+ if (active_receiver->nr) {
+ active_receiver->nr = 0;
+ active_receiver->nr2= 1;
+ } else if (active_receiver->nr2) {
+ active_receiver->nr = 0;
+ active_receiver->nr2= 0;
+ } else {
+ active_receiver->nr = 1;
+ active_receiver->nr2= 0;
}
+ update_noise();
+ vfo_update();
break;
+ /////////////////////////////////////////////////////////// "NUMPADxx"
+ case MIDI_ACTION_NUMPAD_0:
+ num_pad(0);
+ break;
+ case MIDI_ACTION_NUMPAD_1:
+ num_pad(1);
+ break;
+ case MIDI_ACTION_NUMPAD_2:
+ num_pad(2);
+ break;
+ case MIDI_ACTION_NUMPAD_3:
+ num_pad(3);
+ break;
+ case MIDI_ACTION_NUMPAD_4:
+ num_pad(4);
+ break;
+ case MIDI_ACTION_NUMPAD_5:
+ num_pad(5);
+ break;
+ case MIDI_ACTION_NUMPAD_6:
+ num_pad(6);
+ break;
+ case MIDI_ACTION_NUMPAD_7:
+ num_pad(7);
+ break;
+ case MIDI_ACTION_NUMPAD_8:
+ num_pad(9);
+ break;
+ case MIDI_ACTION_NUMPAD_9:
+ num_pad(9);
+ break;
+ case MIDI_ACTION_NUMPAD_CL:
+ num_pad(-1);
+ break;
+ case MIDI_ACTION_NUMPAD_ENTER:
+ num_pad(-2);
+ break;
/////////////////////////////////////////////////////////// "PAN"
case MIDI_ACTION_PAN: // wheel and knob
switch (type) {
break;
/////////////////////////////////////////////////////////// "PREAMP"
case MIDI_ACTION_PRE: // only key supported
- if (type == MIDI_TYPE_KEY) {
- //
- // Normally on/off, but for CHARLY25, cycle through three
- // possible states. Current HPSDR hardware does no have
- // switch'able preamps.
- //
- int c25= (filter_board == CHARLY25);
- new = active_receiver->preamp + active_receiver->dither;
- new++;
- if (c25) {
- if (new >2) new=0;
- } else {
- if (new >1) new=0;
- }
- switch (new) {
- case 0:
- active_receiver->preamp=0;
- if (c25) active_receiver->dither=0;
- break;
- case 1:
- active_receiver->preamp=1;
- if (c25) active_receiver->dither=0;
- break;
- case 2:
- active_receiver->preamp=1;
- if (c25) active_receiver->dither=1;
- break;
- }
- update_att_preamp();
+ //
+ // Normally on/off, but for CHARLY25, cycle through three
+ // possible states. Current HPSDR hardware does no have
+ // switch'able preamps.
+ //
+ c25= (filter_board == CHARLY25);
+ new = active_receiver->preamp + active_receiver->dither;
+ new++;
+ if (c25) {
+ if (new >2) new=0;
+ } else {
+ if (new >1) new=0;
+ }
+ switch (new) {
+ case 0:
+ active_receiver->preamp=0;
+ if (c25) active_receiver->dither=0;
+ break;
+ case 1:
+ active_receiver->preamp=1;
+ if (c25) active_receiver->dither=0;
+ break;
+ case 2:
+ active_receiver->preamp=1;
+ if (c25) active_receiver->dither=1;
+ break;
}
+ update_att_preamp();
break;
- /////////////////////////////////////////////////////////// "PTTONOFF"
- case MIDI_ACTION_PTTONOFF: // key only
+ /////////////////////////////////////////////////////////// "PTT(Keyer)"
+ case MIDI_ACTION_PTTKEYER: // key only
// always use with "ONOFF"
- if (type == MIDI_TYPE_KEY && can_transmit) {
+ if (can_transmit) {
mox_update(val);
}
break;
case MIDI_ACTION_PS: // only key supported
#ifdef PURESIGNAL
// toggle PURESIGNAL
- if (type == MIDI_TYPE_KEY) {
- if (can_transmit) {
- new=!(transmitter->puresignal);
- tx_set_ps(transmitter, new);
- }
- }
+ if (can_transmit) {
+ new=!(transmitter->puresignal);
+ tx_set_ps(transmitter, new);
+ }
#endif
break;
- /////////////////////////////////////////////////////////// "RECALLM[0-4]"
+ /////////////////////////////////////////////////////////// "RECALLMx"
case MIDI_ACTION_MEM_RECALL_M0:
+ recall_memory_slot(0);
+ break;
case MIDI_ACTION_MEM_RECALL_M1:
+ recall_memory_slot(1);
+ break;
case MIDI_ACTION_MEM_RECALL_M2:
+ recall_memory_slot(2);
+ break;
case MIDI_ACTION_MEM_RECALL_M3:
+ recall_memory_slot(3);
+ break;
case MIDI_ACTION_MEM_RECALL_M4:
- //
- // only key supported
- //
- if (type == MIDI_TYPE_KEY) {
- new = action - MIDI_ACTION_MEM_RECALL_M0;
- recall_memory_slot(new);
- }
+ recall_memory_slot(4);
break;
/////////////////////////////////////////////////////////// "RFGAIN"
case MIDI_ACTION_RF_GAIN: // knob or wheel supported
break;
/////////////////////////////////////////////////////////// "RITCLEAR"
case MIDI_ACTION_RIT_CLEAR: // only key supported
- if (type == MIDI_TYPE_KEY) {
- // clear RIT value
- vfo[active_receiver->id].rit = new;
- vfo_update();
- }
+ // clear RIT value
+ vfo[active_receiver->id].rit = new;
+ vfo_update();
+ break;
/////////////////////////////////////////////////////////// "RITSTEP"
case MIDI_ACTION_RIT_STEP: // key or wheel supported
// This cycles between RIT increments 1, 10, 100, 1, 10, 100, ...
break;
/////////////////////////////////////////////////////////// "RITTOGGLE"
case MIDI_ACTION_RIT_TOGGLE: // only key supported
- if (type == MIDI_TYPE_KEY) {
- // enable/disable RIT
- new=vfo[active_receiver->id].rit_enabled;
- vfo[active_receiver->id].rit_enabled = new ? 0 : 1;
- vfo_update();
- }
+ // enable/disable RIT
+ new=vfo[active_receiver->id].rit_enabled;
+ vfo[active_receiver->id].rit_enabled = new ? 0 : 1;
+ vfo_update();
break;
/////////////////////////////////////////////////////////// "RITVAL"
case MIDI_ACTION_RIT_VAL: // wheel or knob
break;
/////////////////////////////////////////////////////////// "SNB"
case MIDI_ACTION_SNB: // only key supported
- if (type == MIDI_TYPE_KEY) {
- if(active_receiver->snb==0) {
- active_receiver->snb=1;
- mode_settings[vfo[active_receiver->id].mode].snb=1;
- } else {
- active_receiver->snb=0;
- mode_settings[vfo[active_receiver->id].mode].snb=0;
- }
- update_noise();
- }
+ if(active_receiver->snb==0) {
+ active_receiver->snb=1;
+ mode_settings[vfo[active_receiver->id].mode].snb=1;
+ } else {
+ active_receiver->snb=0;
+ mode_settings[vfo[active_receiver->id].mode].snb=0;
+ }
+ update_noise();
break;
/////////////////////////////////////////////////////////// "SPLIT"
case MIDI_ACTION_SPLIT: // only key supported
// toggle split mode
- if (type == MIDI_TYPE_KEY) {
- new= split ? 0:1;
- set_split(new);
- }
+ new= split ? 0:1;
+ set_split(new);
break;
- /////////////////////////////////////////////////////////// "STOREM[0-4]"
+ /////////////////////////////////////////////////////////// "STOREMx"
case MIDI_ACTION_MEM_STORE_M0:
+ store_memory_slot(0);
+ break;
case MIDI_ACTION_MEM_STORE_M1:
+ store_memory_slot(1);
+ break;
case MIDI_ACTION_MEM_STORE_M2:
+ store_memory_slot(2);
+ break;
case MIDI_ACTION_MEM_STORE_M3:
+ store_memory_slot(3);
+ break;
case MIDI_ACTION_MEM_STORE_M4:
- //
- // only key supported
- //
- if (type == MIDI_TYPE_KEY) {
- new = action - MIDI_ACTION_MEM_STORE_M0;
- store_memory_slot(new);
- }
- break;
+ store_memory_slot(4);
+ break;
/////////////////////////////////////////////////////////// "SWAPRX"
case MIDI_ACTION_SWAP_RX: // only key supported
- if (type == MIDI_TYPE_KEY && receivers == 2) {
+ if (receivers == 2) {
new=active_receiver->id; // 0 or 1
new= (new == 1) ? 0 : 1; // id of currently inactive receiver
active_receiver=receiver[new];
break;
/////////////////////////////////////////////////////////// "SWAPVFO"
case MIDI_ACTION_SWAP_VFO: // only key supported
- if (type == MIDI_TYPE_KEY) {
- vfo_a_swap_b();
- }
+ vfo_a_swap_b();
break;
/////////////////////////////////////////////////////////// "TUNE"
case MIDI_ACTION_TUNE: // only key supported
- if (type == MIDI_TYPE_KEY && can_transmit) {
+ if (can_transmit) {
new = !tune;
tune_update(new);
}
/////////////////////////////////////////////////////////// "VFOB"
case MIDI_ACTION_VFOA: // only wheel supported
case MIDI_ACTION_VFOB: // only wheel supported
- if (type == MIDI_TYPE_WHEEL && !locked) {
+ if (!locked) {
new = (action == MIDI_ACTION_VFOA) ? 0 : 1;
vfo_id_step(new, val);
}
switch (type) {
case MIDI_TYPE_KEY:
new = (action == MIDI_ACTION_VFO_STEP_UP) ? 1 : -1;
+ update_vfo_step(new);
break;
case MIDI_TYPE_WHEEL:
new = (val > 0) ? 1 : -1;
+ update_vfo_step(new);
break;
default:
// do nothing
// we should not come here anyway
- new = 0;
- break;
+ break;
}
- if (new != 0) {
- //
- // locate where the current step size is located in our table
- //
- int i=0;
- while(steps[i]!=step && steps[i]!=0) {
- i++;
- }
- if(steps[i]!=0) {
- // found. current step size is at position #i
- if (new>0) {
- // next higher step size, if not yet at end of list
- i++;
- if(steps[i]!=0) {
- step=steps[i];
- }
- } else {
- // next lower step size, if not yet at end of list
- i--;
- if(i>=0) {
- step=steps[i];
- }
- }
- }
- vfo_update();
- }
break;
/////////////////////////////////////////////////////////// "VOX"
case MIDI_ACTION_VOX: // only key supported
// toggle VOX
- if (type == MIDI_TYPE_KEY) {
+ if (can_transmit) {
vox_enabled = !vox_enabled;
vfo_update();
- }
+ }
break;
/////////////////////////////////////////////////////////// "VOXLEVEL"
case MIDI_ACTION_VOXLEVEL: // knob or wheel supported
break;
/////////////////////////////////////////////////////////// "XITCLEAR"
case MIDI_ACTION_XIT_CLEAR: // only key supported
- if (type == MIDI_TYPE_KEY) {
- // this clears the XIT value and disables XIT
- if(can_transmit) {
- transmitter->xit = 0;
- transmitter->xit_enabled = 0;
- vfo_update();
- }
+ // this clears the XIT value and disables XIT
+ if(can_transmit) {
+ transmitter->xit = 0;
+ transmitter->xit_enabled = 0;
+ vfo_update();
}
break;
/////////////////////////////////////////////////////////// "XITVAL"
--- /dev/null
+/* Copyright (C)
+* 2020 - 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 <gtk/gtk.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <termios.h>
+
+#include "discovered.h"
+#include "mode.h"
+#include "filter.h"
+#include "band.h"
+#include "receiver.h"
+#include "transmitter.h"
+#include "receiver.h"
+#include "adc.h"
+#include "dac.h"
+#include "radio.h"
+#include "midi.h"
+#include "alsa_midi.h"
+#include "new_menu.h"
+#include "midi_menu.h"
+#include "property.h"
+
+enum {
+ EVENT_COLUMN,
+ CHANNEL_COLUMN,
+ NOTE_COLUMN,
+ TYPE_COLUMN,
+ ACTION_COLUMN,
+ N_COLUMNS
+};
+
+static GtkWidget *parent_window=NULL;
+static GtkWidget *menu_b=NULL;
+static GtkWidget *dialog=NULL;
+
+static GtkWidget *midi_enable_b;
+
+static GtkListStore *store;
+static GtkWidget *view;
+static GtkWidget *scrolled_window=NULL;
+static gulong selection_signal_id;
+GtkTreeSelection *selection;
+static GtkTreeModel *model;
+static GtkTreeIter iter;
+struct desc *current_cmd;
+
+static GtkWidget *filename;
+
+static GtkWidget *newEvent;
+static GtkWidget *newChannel;
+static GtkWidget *newNote;
+static GtkWidget *newVal;
+static GtkWidget *newType;
+static GtkWidget *newMin;
+static GtkWidget *newMax;
+static GtkWidget *newAction;
+static GtkWidget *configure_b;
+static GtkWidget *any_b;
+static GtkWidget *add_b;
+static GtkWidget *update_b;
+static GtkWidget *delete_b;
+static GtkWidget *device_b[MAX_MIDI_DEVICES];
+
+static enum MIDIevent thisEvent=MIDI_EVENT_NONE;
+static int thisChannel;
+static int thisNote;
+static int thisVal;
+static int thisMin;
+static int thisMax;
+static int thisDelay;
+static int thisVfl1, thisVfl2;
+static int thisFl1, thisFl2;
+static int thisLft1, thisLft2;
+static int thisRgt1, thisRgt2;
+static int thisFr1, thisFr2;
+static int thisVfr1, thisVfr2;
+
+static GtkWidget *WheelContainer;
+static GtkWidget *set_delay;
+static GtkWidget *set_vfl1, *set_vfl2;
+static GtkWidget *set_fl1, *set_fl2;
+static GtkWidget *set_lft1, *set_lft2;
+static GtkWidget *set_rgt1, *set_rgt2;
+static GtkWidget *set_fr1, *set_fr2;
+static GtkWidget *set_vfr1, *set_vfr2;
+
+static enum MIDItype thisType;
+static enum MIDIaction thisAction;
+
+static gboolean accept_any=FALSE;
+
+enum {
+ UPDATE_NEW,
+ UPDATE_CURRENT,
+ UPDATE_EXISTING
+};
+
+static int update(void *data);
+static void load_store();
+static void add_store(int key,struct desc *cmd);
+
+static void cleanup() {
+ configure_midi_device(FALSE);
+ if(dialog!=NULL) {
+ gtk_widget_destroy(dialog);
+ dialog=NULL;
+ sub_menu=NULL;
+ }
+}
+
+static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ cleanup();
+ return TRUE;
+}
+
+static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
+ cleanup();
+ return FALSE;
+}
+
+static void device_cb(GtkWidget *widget, gpointer data) {
+ int index=GPOINTER_TO_INT(data);
+ int val=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+ if (val == 1) {
+ register_midi_device(index);
+ } else {
+ close_midi_device(index);
+ }
+ // take care button remains un-checked if opening failed
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), midi_devices[index].active);
+}
+
+static void configure_cb(GtkWidget *widget, gpointer data) {
+ gboolean conf=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget));
+ configure_midi_device(conf);
+ if (conf) {
+ gtk_widget_show(any_b);
+ } else {
+ gtk_widget_hide(any_b);
+ }
+}
+
+static void any_cb(GtkWidget *widget, gpointer data) {
+ gboolean conf=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget));
+ accept_any = conf;
+}
+
+static void update_wheelparams(gpointer user_data) {
+ //
+ // Task: show or hide WheelContainer depending on whether
+ // thre current type is a wheel. If it is a wheel,
+ // set spin buttons to current values.
+ //
+ if (thisType==MIDI_TYPE_WHEEL) {
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_delay),(double) thisDelay);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_vfl1 ),(double) thisVfl1 );
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_vfl2 ),(double) thisVfl2 );
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_fl1 ),(double) thisFl1 );
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_fl2 ),(double) thisFl2 );
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_lft1 ),(double) thisLft1 );
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_lft2 ),(double) thisLft2 );
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_rgt1 ),(double) thisRgt1 );
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_rgt2 ),(double) thisRgt2 );
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_fr1 ),(double) thisFr1 );
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_fr2 ),(double) thisFr2 );
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_vfr1 ),(double) thisVfr1 );
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_vfr2 ),(double) thisVfr2 );
+ gtk_widget_show(WheelContainer);
+ } else {
+ gtk_widget_hide(WheelContainer);
+ }
+}
+
+static void type_changed_cb(GtkWidget *widget, gpointer data) {
+ int i=0;
+ int j=0;
+
+ // update actions available for the type
+ gchar *type=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(widget));
+
+ g_print("%s: type=%s action=%d\n",__FUNCTION__,type,thisAction);
+ gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(newAction));
+ if(type==NULL) {
+ // leave empty
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newAction),0);
+ } else if (strcmp(type,"NONE")==0) {
+ thisType=MIDI_TYPE_NONE;
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newAction),0);
+ } else if(strcmp(type,"KEY")==0) {
+ thisType=MIDI_TYPE_KEY;
+ // add all the Key actions
+ i=0;
+ j=0;
+ while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+ if(ActionTable[i].type&MIDI_TYPE_KEY) {
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newAction),NULL,ActionTable[i].str);
+ if(ActionTable[i].action==thisAction) {
+ gtk_combo_box_set_active(GTK_COMBO_BOX(newAction),j);
+ }
+ j++;
+ }
+ i++;
+ }
+ } else if(strcmp(type,"KNOB/SLIDER")==0) {
+ thisType=MIDI_TYPE_KNOB;
+ // add all the Knob actions
+ while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+ if(ActionTable[i].type&MIDI_TYPE_KNOB) {
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newAction),NULL,ActionTable[i].str);
+ if(ActionTable[i].action==thisAction) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newAction),j);
+ }
+ j++;
+ }
+ i++;
+ }
+ } else if(strcmp(type,"WHEEL")==0) {
+ thisType=MIDI_TYPE_WHEEL;
+ // add all the Wheel actions
+ while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+ if(ActionTable[i].type&MIDI_TYPE_WHEEL || ActionTable[i].type&MIDI_TYPE_KNOB) {
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newAction),NULL,ActionTable[i].str);
+ if(ActionTable[i].action==thisAction) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newAction),j);
+ }
+ j++;
+ }
+ i++;
+ }
+ }
+ update_wheelparams(NULL);
+}
+
+static void row_inserted_cb(GtkTreeModel *tree_model,GtkTreePath *path, GtkTreeIter *iter,gpointer user_data) {
+ //g_print("%s\n",__FUNCTION__);
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(view),path,NULL,FALSE);
+}
+
+
+static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data) {
+ char *str_event;
+ char *str_channel;
+ char *str_note;
+ char *str_type;
+ char *str_action;
+
+ //g_print("%s\n",__FUNCTION__);
+ //if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(configure_b))) {
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ gtk_tree_model_get(model, &iter, EVENT_COLUMN, &str_event, -1);
+ gtk_tree_model_get(model, &iter, CHANNEL_COLUMN, &str_channel, -1);
+ gtk_tree_model_get(model, &iter, NOTE_COLUMN, &str_note, -1);
+ gtk_tree_model_get(model, &iter, TYPE_COLUMN, &str_type, -1);
+ gtk_tree_model_get(model, &iter, ACTION_COLUMN, &str_action, -1);
+
+ g_print("%s: %s %s %s %s %s\n",__FUNCTION__,str_event,str_channel,str_note,str_type,str_action);
+
+ if(str_event!=NULL && str_channel!=NULL && str_note!=NULL && str_type!=NULL && str_action!=NULL) {
+
+ if(strcmp(str_event,"CTRL")==0) {
+ thisEvent=MIDI_EVENT_CTRL;
+ } else if(strcmp(str_event,"PITCH")==0) {
+ thisEvent=MIDI_EVENT_PITCH;
+ } else if(strcmp(str_event,"NOTE")==0) {
+ thisEvent=MIDI_EVENT_NOTE;
+ } else {
+ thisEvent=MIDI_EVENT_NONE;
+ }
+ if (!strncmp(str_channel,"Any", 3)) {
+ thisChannel=-1;
+ } else {
+ thisChannel=atoi(str_channel);
+ }
+ thisNote=atoi(str_note);
+ thisVal=0;
+ thisMin=0;
+ thisMax=0;
+ if(strcmp(str_type,"KEY")==0) {
+ thisType=MIDI_TYPE_KEY;
+ } else if(strcmp(str_type,"KNOB/SLIDER")==0) {
+ thisType=MIDI_TYPE_KNOB;
+ } else if(strcmp(str_type,"WHEEL")==0) {
+ thisType=MIDI_TYPE_WHEEL;
+ } else {
+ thisType=MIDI_TYPE_NONE;
+ }
+ thisAction=MIDI_ACTION_NONE;
+ int i=0;
+ while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+ if(strcmp(ActionTable[i].str,str_action)==0) {
+ thisAction=ActionTable[i].action;
+ break;
+ }
+ i++;
+ }
+ g_idle_add(update,GINT_TO_POINTER(UPDATE_EXISTING));
+ }
+ }
+ //}
+}
+
+static void find_current_cmd() {
+ struct desc *cmd;
+ g_print("%s: Note=%d Chan=%d Type=%d Action=%d\n",__FUNCTION__, thisNote, thisChannel, thisType, thisAction);
+ cmd=MidiCommandsTable[thisNote];
+ while(cmd!=NULL) {
+ if((cmd->channel==thisChannel) && cmd->type==thisType && cmd->action==thisAction) {
+ g_print("%s: found cmd %p\n",__FUNCTION__,cmd);
+ break;
+ }
+ cmd=cmd->next;
+ }
+ current_cmd=cmd; // NULL if not found
+}
+
+static void wheelparam_cb(GtkWidget *widget, gpointer user_data) {
+ int what = GPOINTER_TO_INT(user_data);
+ int val=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ int newval=val;
+
+ if (thisType != MIDI_TYPE_WHEEL) {
+ // we should never arrive here
+ return;
+ }
+ switch (what) {
+ case 1: // Delay
+ thisDelay=newval;
+ break;
+ case 2: // Very fast Left 1
+ if (newval > thisVfl2) newval=thisVfl2;
+ thisVfl1=newval;
+ break;
+ case 3: // Very fast Left 2
+ if (newval < thisVfl1) newval=thisVfl1;
+ thisVfl2=newval;
+ break;
+ case 4: // Fast Left 1
+ if (newval > thisFl2) newval=thisFl2;
+ thisFl1=newval;
+ break;
+ case 5: // Fast Left 2
+ if (newval < thisFl1) newval=thisFl1;
+ thisFl2=newval;
+ break;
+ case 6: // Left 1
+ if (newval > thisLft2) newval=thisLft2;
+ thisLft1=newval;
+ break;
+ case 7: // Left 2
+ if (newval < thisLft1) newval=thisLft1;
+ thisLft2=newval;
+ break;
+ case 8: // Right 1
+ if (newval > thisRgt2) newval=thisRgt2;
+ thisRgt1=newval;
+ break;
+ case 9: // Right 2
+ if (newval < thisRgt1) newval=thisRgt1;
+ thisRgt2=newval;
+ break;
+ case 10: // Fast Right 1
+ if (newval > thisFr2) newval=thisFr2;
+ thisFr1=newval;
+ break;
+ case 11: // Fast Right2
+ if (newval < thisFr1) newval=thisFr1;
+ thisFr2=newval;
+ break;
+ case 12: // Very fast Right 1
+ if (newval > thisVfr2) newval=thisVfr2;
+ thisVfr1=newval;
+ break;
+ case 13: // Very fast Right 2
+ if (newval < thisVfr1) newval=thisVfr1;
+ thisVfr2=newval;
+ break;
+ }
+ //
+ // If we have changed the value because we kept thisVfl2 >= thisVfl1 etc,
+ // update the spin button
+ //
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),(double) newval);
+}
+
+static void clear_cb(GtkWidget *widget,gpointer user_data) {
+
+ g_signal_handler_block(G_OBJECT(selection), selection_signal_id);
+ gtk_list_store_clear(store);
+ MidiReleaseCommands();
+ g_signal_handler_unblock(G_OBJECT(selection), selection_signal_id);
+}
+
+static void save_cb(GtkWidget *widget,gpointer user_data) {
+ GtkWidget *save_dialog;
+ GtkFileChooser *chooser;
+ GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE;
+ gchar *filename;
+ gint res;
+ struct desc *cmd;
+
+ save_dialog = gtk_file_chooser_dialog_new ("Save File",
+ GTK_WINDOW(dialog),
+ action,
+ "_Cancel",
+ GTK_RESPONSE_CANCEL,
+ "_Save",
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+ chooser = GTK_FILE_CHOOSER (save_dialog);
+ gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE);
+ gtk_file_chooser_set_current_name(chooser,"midi.midi");
+ res = gtk_dialog_run (GTK_DIALOG (save_dialog));
+ if(res==GTK_RESPONSE_ACCEPT) {
+ char *savefilename=gtk_file_chooser_get_filename(chooser);
+ clearProperties();
+ midi_save_state();
+ saveProperties(savefilename);
+ g_free(savefilename);
+ }
+ gtk_widget_destroy(save_dialog);
+}
+
+static void load_cb(GtkWidget *widget,gpointer user_data) {
+ GtkWidget *load_dialog;
+ GtkFileChooser *chooser;
+ GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
+ gchar *filename;
+ gint res;
+ struct desc *cmd;
+
+ load_dialog = gtk_file_chooser_dialog_new ("Open MIDI File",
+ GTK_WINDOW(dialog),
+ action,
+ "_Cancel",
+ GTK_RESPONSE_CANCEL,
+ "_Load",
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+ chooser = GTK_FILE_CHOOSER (load_dialog);
+ res = gtk_dialog_run (GTK_DIALOG (load_dialog));
+ if(res==GTK_RESPONSE_ACCEPT) {
+ char *loadfilename=gtk_file_chooser_get_filename(chooser);
+ clear_cb(NULL,NULL);
+ clearProperties();
+ loadProperties(loadfilename);
+ midi_restore_state();
+ g_signal_handler_block(G_OBJECT(selection), selection_signal_id);
+ load_store();
+ g_signal_handler_unblock(G_OBJECT(selection), selection_signal_id);
+ g_free(loadfilename);
+ }
+ gtk_widget_destroy(load_dialog);
+}
+
+static void load_original_cb(GtkWidget *widget,gpointer user_data) {
+ GtkWidget *load_dialog;
+ GtkFileChooser *chooser;
+ GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
+ gchar *filename;
+ gint res;
+ struct desc *cmd;
+
+ load_dialog = gtk_file_chooser_dialog_new ("Open LEGACY MIDI File",
+ GTK_WINDOW(dialog),
+ action,
+ "_Cancel",
+ GTK_RESPONSE_CANCEL,
+ "_Load",
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+ chooser = GTK_FILE_CHOOSER (load_dialog);
+ res = gtk_dialog_run (GTK_DIALOG (load_dialog));
+ if(res==GTK_RESPONSE_ACCEPT) {
+ char *loadfilename=gtk_file_chooser_get_filename(chooser);
+ clear_cb(NULL,NULL);
+ MIDIstartup(loadfilename);
+ g_free(loadfilename);
+ g_signal_handler_block(G_OBJECT(selection), selection_signal_id);
+ load_store();
+ g_signal_handler_unblock(G_OBJECT(selection), selection_signal_id);
+ }
+ gtk_widget_destroy(load_dialog);
+}
+
+static void add_store(int key,struct desc *cmd) {
+ char str_event[16];
+ char str_channel[16];
+ char str_note[16];
+ char str_type[32];
+ char str_action[32];
+
+ //g_print("%s: key=%d desc=%p\n",__FUNCTION__,key,cmd);
+ switch(cmd->event) {
+ case MIDI_EVENT_NONE:
+ strcpy(str_event,"NONE");
+ break;
+ case MIDI_EVENT_NOTE:
+ strcpy(str_event,"NOTE");
+ break;
+ case MIDI_EVENT_CTRL:
+ strcpy(str_event,"CTRL");
+ break;
+ case MIDI_EVENT_PITCH:
+ strcpy(str_event,"PITCH");
+ break;
+ }
+ if (cmd->channel >= 0) {
+ sprintf(str_channel,"%d",cmd->channel);
+ } else {
+ sprintf(str_channel,"%s","Any");
+ }
+ sprintf(str_note,"%d",key);
+ switch(cmd->type) {
+ case MIDI_TYPE_NONE:
+ strcpy(str_type,"NONE");
+ break;
+ case MIDI_TYPE_KEY:
+ strcpy(str_type,"KEY");
+ break;
+ case MIDI_TYPE_KNOB:
+ strcpy(str_type,"KNOB/SLIDER");
+ break;
+ case MIDI_TYPE_WHEEL:
+ strcpy(str_type,"WHEEL");
+ break;
+ }
+ // ATTENTION: this assumes ActionTable is sorted by action enum
+ strcpy(str_action,ActionTable[cmd->action].str);
+
+ //g_print("%s: Event=%s Channel=%s Note=%s Type=%s Action=%s\n", __FUNCTION__, str_event, str_channel, str_note, str_type, str_action);
+ gtk_list_store_prepend(store,&iter);
+ gtk_list_store_set(store,&iter,
+ EVENT_COLUMN,str_event,
+ CHANNEL_COLUMN,str_channel,
+ NOTE_COLUMN,str_note,
+ TYPE_COLUMN,str_type,
+ ACTION_COLUMN,str_action,
+ -1);
+
+ if(scrolled_window!=NULL) {
+ GtkAdjustment *adjustment=gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW(scrolled_window));
+ //g_print("%s: adjustment=%f lower=%f upper=%f\n",__FUNCTION__,gtk_adjustment_get_value(adjustment),gtk_adjustment_get_lower(adjustment),gtk_adjustment_get_upper(adjustment));
+ if(gtk_adjustment_get_value(adjustment)!=0.0) {
+ gtk_adjustment_set_value(adjustment,0.0);
+ }
+ }
+}
+
+static void load_store() {
+ struct desc *cmd;
+ gtk_list_store_clear(store);
+ for(int i=127;i>=0;i--) {
+ cmd=MidiCommandsTable[i];
+ while(cmd!=NULL) {
+ add_store(i,cmd);
+ cmd=cmd->next;
+ }
+ }
+}
+
+static void add_cb(GtkButton *widget,gpointer user_data) {
+
+ gchar *str_type=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(newType));
+ gchar *str_action=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(newAction));
+;
+
+ gint i;
+ gint type;
+ gint action;
+ gint onoff;
+
+ if(str_type==NULL || str_action==NULL) {
+ return;
+ }
+
+ if(strcmp(str_type,"KEY")==0) {
+ type=MIDI_TYPE_KEY;
+ } else if(strcmp(str_type,"KNOB/SLIDER")==0) {
+ type=MIDI_TYPE_KNOB;
+ } else if(strcmp(str_type,"WHEEL")==0) {
+ type=MIDI_TYPE_WHEEL;
+ } else {
+ type=MIDI_TYPE_NONE;
+ }
+
+ action=MIDI_ACTION_NONE;
+ onoff=0;
+ i=0;
+ while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+ if(strcmp(ActionTable[i].str,str_action)==0) {
+ action=ActionTable[i].action;
+ onoff=ActionTable[i].onoff;
+ break;
+ }
+ i++;
+ }
+
+ g_print("%s: type=%s (%d) action=%s (%d)\n",__FUNCTION__,str_type,type,str_action,action);
+
+ struct desc *desc;
+ desc = (struct desc *) malloc(sizeof(struct desc));
+ desc->next = NULL;
+ desc->action = action; // MIDIaction
+ desc->type = type; // MIDItype
+ desc->event = thisEvent; // MIDevent
+ desc->onoff = onoff;
+ desc->delay = thisDelay;
+ desc->vfl1 = thisVfl1;
+ desc->vfl2 = thisVfl2;
+ desc->fl1 = thisFl1;
+ desc->fl2 = thisFl2;
+ desc->lft1 = thisLft1;
+ desc->lft2 = thisLft2;
+ desc->rgt1 = thisRgt1;
+ desc->rgt2 = thisRgt2;
+ desc->fr1 = thisFr1;
+ desc->fr2 = thisFr2;
+ desc->vfr1 = thisVfr1;
+ desc->vfr2 = thisVfr2;
+ desc->channel = thisChannel;
+
+ gint key=thisNote;
+ if(key<0) key=0;
+ if(key>127) key=0;
+
+
+ MidiAddCommand(key, desc);
+ add_store(key,desc);
+
+ gtk_widget_set_sensitive(add_b,FALSE);
+ gtk_widget_set_sensitive(update_b,TRUE);
+ gtk_widget_set_sensitive(delete_b,TRUE);
+
+}
+
+static void update_cb(GtkButton *widget,gpointer user_data) {
+ char str_event[16];
+ char str_channel[16];
+ char str_note[16];
+ int i;
+ int onoff;
+
+ if (current_cmd == NULL) {
+ g_print("%s: current_cmd is NULL!\n", __FUNCTION__);
+ return;
+ }
+
+ gchar *str_type=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(newType));
+ gchar *str_action=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(newAction));
+;
+ //g_print("%s: type=%s action=%s\n",__FUNCTION__,str_type,str_action);
+
+ if(strcmp(str_type,"KEY")==0) {
+ thisType=MIDI_TYPE_KEY;
+ } else if(strcmp(str_type,"KNOB/SLIDER")==0) {
+ thisType=MIDI_TYPE_KNOB;
+ } else if(strcmp(str_type,"WHEEL")==0) {
+ thisType=MIDI_TYPE_WHEEL;
+ } else {
+ thisType=MIDI_TYPE_NONE;
+ }
+
+ thisAction=MIDI_ACTION_NONE;
+ i=0;
+ while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+ if(strcmp(ActionTable[i].str,str_action)==0) {
+ thisAction=ActionTable[i].action;
+ onoff=ActionTable[i].onoff;
+ break;
+ }
+ i++;
+ }
+
+ current_cmd->channel=thisChannel;
+ current_cmd->type =thisType;
+ current_cmd->action =thisAction;
+ current_cmd->onoff =onoff;
+ current_cmd->delay =thisDelay;
+
+ current_cmd->vfl1 =thisVfl1;
+ current_cmd->vfl2 =thisVfl2;
+ current_cmd->fl1 =thisFl1;
+ current_cmd->fl2 =thisFl2;
+ current_cmd->lft1 =thisLft1;
+ current_cmd->lft2 =thisLft2;
+ current_cmd->rgt1 =thisRgt1;
+ current_cmd->rgt2 =thisRgt2;
+ current_cmd->fr1 =thisFr1;
+ current_cmd->fr2 =thisFr2;
+ current_cmd->vfr1 =thisVfr1;
+ current_cmd->vfr2 =thisVfr2;
+
+ switch(current_cmd->event) {
+ case MIDI_EVENT_NONE:
+ strcpy(str_event,"NONE");
+ break;
+ case MIDI_EVENT_NOTE:
+ strcpy(str_event,"NOTE");
+ break;
+ case MIDI_EVENT_CTRL:
+ strcpy(str_event,"CTRL");
+ break;
+ case MIDI_EVENT_PITCH:
+ strcpy(str_event,"PITCH");
+ break;
+ }
+ if (current_cmd->channel >= 0) {
+ sprintf(str_channel,"%d",current_cmd->channel);
+ } else {
+ sprintf(str_channel,"%s","Any");
+ }
+ sprintf(str_note,"%d",thisNote);
+
+ g_print("%s: event=%s channel=%s note=%s type=%s action=%s\n",
+ __FUNCTION__,str_event,str_channel,str_note,str_type,str_action);
+ gtk_list_store_set(store,&iter,
+ EVENT_COLUMN,str_event,
+ CHANNEL_COLUMN,str_channel,
+ NOTE_COLUMN,str_note,
+ TYPE_COLUMN,str_type,
+ ACTION_COLUMN,str_action,
+ -1);
+}
+
+static void delete_cb(GtkButton *widget,gpointer user_data) {
+ struct desc *previous_cmd;
+ struct desc *next_cmd;
+ GtkTreeIter saved_iter;
+ g_print("%s: thisNote=%d current_cmd=%p\n",__FUNCTION__,thisNote,current_cmd);
+
+ if (current_cmd == NULL) {
+ g_print("%s: current_cmd is NULL!\n", __FUNCTION__);
+ return;
+ }
+
+ saved_iter=iter;
+
+
+ // remove from MidiCommandsTable
+ if(MidiCommandsTable[thisNote]==current_cmd) {
+ g_print("%s: remove first\n",__FUNCTION__);
+ MidiCommandsTable[thisNote]=current_cmd->next;
+ g_free(current_cmd);
+ current_cmd=NULL;
+ } else {
+ previous_cmd=MidiCommandsTable[thisNote];
+ while(previous_cmd->next!=NULL) {
+ next_cmd=previous_cmd->next;
+ if(next_cmd==current_cmd) {
+ g_print("%s: remove next\n",__FUNCTION__);
+ previous_cmd->next=next_cmd->next;
+ g_free(next_cmd);
+ current_cmd=NULL; // note next_cmd == current_cmd
+ break;
+ }
+ previous_cmd=next_cmd;
+ }
+ }
+
+ // remove from list store
+ gtk_list_store_remove(store,&saved_iter);
+
+ gtk_widget_set_sensitive(add_b,TRUE);
+ gtk_widget_set_sensitive(update_b,FALSE);
+ gtk_widget_set_sensitive(delete_b,FALSE);
+
+}
+
+void midi_menu(GtkWidget *parent) {
+ int i;
+ int col=0;
+ int row=0;
+ GtkCellRenderer *renderer;
+ GtkWidget *lbl;
+
+ parent_window=parent;
+
+ dialog=gtk_dialog_new();
+ gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window));
+ gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - MIDI");
+ g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL);
+
+ GdkRGBA color;
+ color.red = 1.0;
+ color.green = 1.0;
+ color.blue = 1.0;
+ color.alpha = 1.0;
+ gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color);
+
+ GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ GtkWidget *grid=gtk_grid_new();
+ gtk_grid_set_column_spacing (GTK_GRID(grid),2);
+
+ row=0;
+ col=0;
+
+ GtkWidget *close_b=gtk_button_new_with_label("Close");
+ g_signal_connect(close_b, "pressed", G_CALLBACK(close_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid), close_b, col, row, 1, 1);
+ col++;
+
+ get_midi_devices();
+ if (n_midi_devices > 0) {
+ GtkWidget *devices_label=gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(devices_label), "<b>Select MIDI device(s)</b>");
+ gtk_label_set_justify(GTK_LABEL(devices_label),GTK_JUSTIFY_LEFT);
+ gtk_grid_attach(GTK_GRID(grid),devices_label,col,row,2,1);
+ //
+ // Now put the device checkboxes in columns 3 (width: 1), 4 (width: 3), 7 (width: 1)
+ // and make as many rows as necessary
+ col=3;
+ int width = 1;
+ for (i=0; i<n_midi_devices; i++) {
+ device_b[i] = gtk_check_button_new_with_label(midi_devices[i].name);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(device_b[i]), midi_devices[i].active);
+ gtk_grid_attach(GTK_GRID(grid),device_b[i],col,row,width,1);
+ switch (col) {
+ case 3:
+ col=4;
+ width=3;
+ break;
+ case 4:
+ col=7;
+ width=1;
+ break;
+ case 7:
+ col=3;
+ width=1;
+ row++;
+ break;
+ }
+ g_signal_connect(device_b[i], "toggled", G_CALLBACK(device_cb), GINT_TO_POINTER(i));
+ gtk_widget_show(device_b[i]);
+ }
+ //
+ // Row containing device checkboxes is partially filled,
+ // advance to next one.
+ if (col > 3) {
+ col=0;
+ row++;
+ }
+ } else {
+ GtkWidget *devices_label=gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(devices_label), "<b>No MIDI devices found!</b>");
+ gtk_label_set_justify(GTK_LABEL(devices_label),GTK_JUSTIFY_LEFT);
+ gtk_grid_attach(GTK_GRID(grid),devices_label,col,row,3,1);
+ row++;
+ col=0;
+ }
+
+ row++;
+ col=0;
+
+ GtkWidget *clear_b=gtk_button_new_with_label("Clear");
+ gtk_grid_attach(GTK_GRID(grid),clear_b,col,row,1,1);
+ g_signal_connect(clear_b,"clicked",G_CALLBACK(clear_cb),NULL);
+ col++;
+
+ GtkWidget *save_b=gtk_button_new_with_label("Save");
+ gtk_grid_attach(GTK_GRID(grid),save_b,col,row,1,1);
+ g_signal_connect(save_b,"clicked",G_CALLBACK(save_cb),NULL);
+ col++;
+
+ GtkWidget *load_b=gtk_button_new_with_label("Load");
+ gtk_grid_attach(GTK_GRID(grid),load_b,col,row,1,1);
+ g_signal_connect(load_b,"clicked",G_CALLBACK(load_cb),NULL);
+ col++;
+
+ GtkWidget *load_original_b=gtk_button_new_with_label("Load Legacy");
+ gtk_grid_attach(GTK_GRID(grid),load_original_b,col,row,1,1);
+ g_signal_connect(load_original_b,"clicked",G_CALLBACK(load_original_cb),NULL);
+ col++;
+
+ configure_b=gtk_check_button_new_with_label("MIDI Configure");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (configure_b), FALSE);
+ gtk_grid_attach(GTK_GRID(grid),configure_b,col,row,3,1);
+ g_signal_connect(configure_b,"toggled",G_CALLBACK(configure_cb),NULL);
+
+ col+=3;
+ any_b=gtk_check_button_new_with_label("Configure for any channel");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (any_b), FALSE);
+ gtk_grid_attach(GTK_GRID(grid),any_b,col,row,6,1);
+ g_signal_connect(any_b,"toggled",G_CALLBACK(any_cb),NULL);
+
+ row++;
+ col=0;
+ GtkWidget *label=gtk_label_new("Evt");
+ gtk_grid_attach(GTK_GRID(grid),label,col++,row,1,1);
+ label=gtk_label_new("Ch");
+ gtk_grid_attach(GTK_GRID(grid),label,col++,row,1,1);
+ label=gtk_label_new("Note");
+ gtk_grid_attach(GTK_GRID(grid),label,col++,row,1,1);
+ label=gtk_label_new("Type");
+ gtk_grid_attach(GTK_GRID(grid),label,col++,row,1,1);
+ label=gtk_label_new("Value");
+ gtk_grid_attach(GTK_GRID(grid),label,col++,row,1,1);
+ label=gtk_label_new("Min");
+ gtk_grid_attach(GTK_GRID(grid),label,col++,row,1,1);
+ label=gtk_label_new("Max");
+ gtk_grid_attach(GTK_GRID(grid),label,col++,row,1,1);
+ label=gtk_label_new("Action");
+ gtk_grid_attach(GTK_GRID(grid),label,col++,row,1,1);
+
+
+ row++;
+ col=0;
+ newEvent=gtk_label_new("");
+ gtk_grid_attach(GTK_GRID(grid),newEvent,col++,row,1,1);
+ newChannel=gtk_label_new("");
+ gtk_grid_attach(GTK_GRID(grid),newChannel,col++,row,1,1);
+ newNote=gtk_label_new("");
+ gtk_grid_attach(GTK_GRID(grid),newNote,col++,row,1,1);
+ newType=gtk_combo_box_text_new();
+ gtk_grid_attach(GTK_GRID(grid),newType,col++,row,1,1);
+ g_signal_connect(newType,"changed",G_CALLBACK(type_changed_cb),NULL);
+ newVal=gtk_label_new("");
+ gtk_grid_attach(GTK_GRID(grid),newVal,col++,row,1,1);
+ newMin=gtk_label_new("");
+ gtk_grid_attach(GTK_GRID(grid),newMin,col++,row,1,1);
+ newMax=gtk_label_new("");
+ gtk_grid_attach(GTK_GRID(grid),newMax,col++,row,1,1);
+ newAction=gtk_combo_box_text_new();
+ gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(newAction),4);
+ gtk_grid_attach(GTK_GRID(grid),newAction,col++,row,3,1);
+
+//
+// Load Action button with all actions, such that it
+// *now* assumes the maximum width
+//
+ i=0;
+ while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newAction),NULL,ActionTable[i].str);
+ i++;
+ }
+ gtk_combo_box_set_active(GTK_COMBO_BOX(newAction),0);
+
+ row++;
+ col=0;
+
+ add_b=gtk_button_new_with_label("Add");
+ g_signal_connect(add_b, "pressed", G_CALLBACK(add_cb),NULL);
+ gtk_grid_attach(GTK_GRID(grid),add_b,col++,row,1,1);
+ gtk_widget_set_sensitive(add_b,FALSE);
+
+ update_b=gtk_button_new_with_label("Update");
+ g_signal_connect(update_b, "pressed", G_CALLBACK(update_cb),NULL);
+ gtk_grid_attach(GTK_GRID(grid),update_b,col++,row,1,1);
+ gtk_widget_set_sensitive(update_b,FALSE);
+
+ delete_b=gtk_button_new_with_label("Delete");
+ g_signal_connect(delete_b, "pressed", G_CALLBACK(delete_cb),NULL);
+ gtk_grid_attach(GTK_GRID(grid),delete_b,col++,row,1,1);
+ gtk_widget_set_sensitive(delete_b,FALSE);
+
+ row++;
+ col=0;
+
+ scrolled_window=gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),GTK_POLICY_AUTOMATIC,GTK_POLICY_ALWAYS);
+ //
+ // At the top of the window, there are rows of checkboxes for MIDI devices, up to 3 in a row.
+ // In the unlikely case there are very many MIDI devices, vertical space becomes scarce
+ //
+ gtk_widget_set_size_request(scrolled_window,400,300-15*((n_midi_devices+1)/3));
+
+ view=gtk_tree_view_new();
+
+ renderer=gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, "Event", renderer, "text", EVENT_COLUMN, NULL);
+
+ renderer=gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, "CHANNEL", renderer, "text", CHANNEL_COLUMN, NULL);
+
+ renderer=gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, "NOTE", renderer, "text", NOTE_COLUMN, NULL);
+
+ renderer=gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, "TYPE", renderer, "text", TYPE_COLUMN, NULL);
+
+ renderer=gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, "ACTION", renderer, "text", ACTION_COLUMN, NULL);
+
+ store=gtk_list_store_new(N_COLUMNS,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING);
+
+ load_store();
+
+ gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store));
+
+ gtk_container_add(GTK_CONTAINER(scrolled_window),view);
+
+ gtk_grid_attach(GTK_GRID(grid), scrolled_window, col, row, 5, 10);
+
+ model=gtk_tree_view_get_model(GTK_TREE_VIEW(view));
+ g_signal_connect(model,"row-inserted",G_CALLBACK(row_inserted_cb),NULL);
+
+ selection=gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+
+ selection_signal_id=g_signal_connect(G_OBJECT(selection),"changed",G_CALLBACK(tree_selection_changed_cb),NULL);
+
+ //
+ // Place a fixed container to hold the wheel parameters
+ // and create sub-grid
+ //
+ col=5;
+ WheelContainer=gtk_fixed_new();
+ gtk_widget_set_size_request(WheelContainer,300,300-15*((n_midi_devices+1)/3));
+ gtk_grid_attach(GTK_GRID(grid), WheelContainer, col, row, 6, 10);
+ //
+ // Showing/hiding the container may resize-the columns of the main grid,
+ // and causing other elements to move around. Therefore create a further
+ // "dummy" frame that is always shown. The dummy must have the same width
+ // and a small height.
+ //
+ GtkWidget *DummyContainer=gtk_fixed_new();
+ gtk_widget_set_size_request(DummyContainer,300,1);
+ gtk_grid_attach(GTK_GRID(grid), DummyContainer, col, row, 6, 1);
+
+ GtkWidget *WheelGrid=gtk_grid_new();
+ gtk_grid_set_column_spacing (GTK_GRID(WheelGrid),2);
+
+ col=0;
+ row=0;
+
+ lbl=gtk_label_new(NULL);
+ // the new-line in the label get some space between the text and the spin buttons
+ gtk_label_set_markup(GTK_LABEL(lbl), "<b>Configure special WHEEL parameters\n</b>");
+ gtk_widget_set_size_request(lbl,300,30);
+ gtk_widget_set_halign(lbl, GTK_ALIGN_CENTER);
+
+ gtk_grid_attach(GTK_GRID(WheelGrid), lbl, col, row, 3, 1);
+
+ //
+ // Finally, put wheel config elements into the wheel grid
+ //
+ col=0;
+ row++;
+
+ lbl=gtk_label_new("Delay");
+ gtk_widget_set_halign(lbl, GTK_ALIGN_START);
+ gtk_grid_attach(GTK_GRID(WheelGrid), lbl, col, row, 1, 1);
+ col++;
+
+ set_delay = gtk_spin_button_new_with_range(0.0, 500.0, 10.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_delay, col, row, 1, 1);
+ g_signal_connect(set_delay, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(1));
+ col++;
+
+ row++;
+ col=0;
+ lbl=gtk_label_new("Left <<<");
+ gtk_widget_set_halign(lbl, GTK_ALIGN_START);
+ gtk_grid_attach(GTK_GRID(WheelGrid), lbl, col, row, 1, 1);
+ col++;
+
+ set_vfl1 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_vfl1, col, row, 1, 1);
+ g_signal_connect(set_vfl1, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(2));
+ col++;
+
+ set_vfl2 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_vfl2, col, row, 1, 1);
+ g_signal_connect(set_vfl2, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(3));
+ col++;
+
+ row++;
+ col=0;
+
+ lbl=gtk_label_new("Left <<");
+ gtk_widget_set_halign(lbl, GTK_ALIGN_START);
+ gtk_grid_attach(GTK_GRID(WheelGrid), lbl, col, row, 1, 1);
+ col++;
+
+ set_fl1 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_fl1, col, row, 1, 1);
+ g_signal_connect(set_fl1, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(4));
+ col++;
+
+ set_fl2 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_fl2, col, row, 1, 1);
+ g_signal_connect(set_fl2, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(5));
+ col++;
+
+ row++;
+ col=0;
+ lbl=gtk_label_new("Left <");
+ gtk_widget_set_halign(lbl, GTK_ALIGN_START);
+ gtk_grid_attach(GTK_GRID(WheelGrid), lbl, col, row, 1, 1);
+ col++;
+
+ set_lft1 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_lft1, col, row, 1, 1);
+ g_signal_connect(set_lft1, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(6));
+ col++;
+
+ set_lft2 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_lft2, col, row, 1, 1);
+ g_signal_connect(set_lft2, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(7));
+ col++;
+
+ row++;
+ col=0;
+ lbl=gtk_label_new("Right >");
+ gtk_widget_set_halign(lbl, GTK_ALIGN_START);
+ gtk_grid_attach(GTK_GRID(WheelGrid), lbl, col, row, 1, 1);
+ col++;
+
+ set_rgt1 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_rgt1, col, row, 1, 1);
+ g_signal_connect(set_rgt1, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(8));
+ col++;
+
+ set_rgt2 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_rgt2, col, row, 1, 1);
+ g_signal_connect(set_rgt2, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(9));
+ col++;
+
+ row++;
+ col=0;
+ lbl=gtk_label_new("Right >>");
+ gtk_widget_set_halign(lbl, GTK_ALIGN_START);
+ gtk_grid_attach(GTK_GRID(WheelGrid), lbl, col, row, 1, 1);
+ col++;
+
+ set_fr1 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_fr1, col, row, 1, 1);
+ g_signal_connect(set_fr1, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(10));
+ col++;
+
+ set_fr2 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_fr2, col, row, 1, 1);
+ g_signal_connect(set_fr2, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(11));
+ col++;
+
+ row++;
+ col=0;
+ lbl=gtk_label_new("Right >>>");
+ gtk_widget_set_halign(lbl, GTK_ALIGN_START);
+ gtk_grid_attach(GTK_GRID(WheelGrid), lbl, col, row, 1, 1);
+ col++;
+
+ set_vfr1 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_vfr1, col, row, 1, 1);
+ g_signal_connect(set_vfr1, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(12));
+ col++;
+
+ set_vfr2 = gtk_spin_button_new_with_range(-1.0, 127.0, 1.0);
+ gtk_grid_attach(GTK_GRID(WheelGrid), set_vfr2, col, row, 1, 1);
+ g_signal_connect(set_vfr2, "value-changed", G_CALLBACK(wheelparam_cb), GINT_TO_POINTER(13));
+ col++;
+
+ gtk_container_add(GTK_CONTAINER(content),grid);
+ gtk_container_add(GTK_CONTAINER(WheelContainer), WheelGrid);
+ sub_menu=dialog;
+ gtk_widget_show_all(dialog);
+
+ //
+ // Clear Action box (we filled it just to set its width)
+ //
+ gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(newAction));
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newAction),0);
+ //
+ // Hide "accept from any source" checkbox
+ // (made visible only if config is checked)
+ gtk_widget_hide(any_b);
+ gtk_widget_hide(WheelContainer);
+}
+
+static int update(void *data) {
+ int state=GPOINTER_TO_INT(data);
+ gchar text[32];
+ gint i=1;
+ gint j;
+
+ switch(state) {
+ case UPDATE_NEW:
+ g_print("%s: UPDATE_NEW\n",__FUNCTION__);
+ switch(thisEvent) {
+ case MIDI_EVENT_NONE:
+ gtk_label_set_text(GTK_LABEL(newEvent),"NONE");
+ break;
+ case MIDI_EVENT_NOTE:
+ gtk_label_set_text(GTK_LABEL(newEvent),"NOTE");
+ break;
+ case MIDI_EVENT_CTRL:
+ gtk_label_set_text(GTK_LABEL(newEvent),"CTRL");
+ break;
+ case MIDI_EVENT_PITCH:
+ gtk_label_set_text(GTK_LABEL(newEvent),"PITCH");
+ break;
+ }
+ if (thisChannel >= 0) {
+ sprintf(text,"%d",thisChannel);
+ } else {
+ strcpy(text,"Any");
+ }
+ gtk_label_set_text(GTK_LABEL(newChannel),text);
+ sprintf(text,"%d",thisNote);
+ gtk_label_set_text(GTK_LABEL(newNote),text);
+ gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(newType));
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"NONE");
+ switch(thisEvent) {
+ case MIDI_EVENT_NONE:
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
+ break;
+ case MIDI_EVENT_NOTE:
+ case MIDI_EVENT_PITCH:
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"KEY");
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newType),1);
+ break;
+ case MIDI_EVENT_CTRL:
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"KNOB/SLIDER");
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"WHEEL");
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
+ break;
+ }
+ gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(newAction));
+ if(thisEvent==MIDI_EVENT_PITCH || thisEvent==MIDI_EVENT_NOTE) {
+ i=0;
+ j=0;
+ while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+ if(ActionTable[i].type&MIDI_TYPE_KEY) {
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newAction),NULL,ActionTable[i].str);
+ if(ActionTable[i].action==thisAction) {
+ gtk_combo_box_set_active(GTK_COMBO_BOX(newAction),j);
+ }
+ j++;
+ }
+ i++;
+ }
+
+ }
+ sprintf(text,"%d",thisVal);
+ gtk_label_set_text(GTK_LABEL(newVal),text);
+ sprintf(text,"%d",thisMin);
+ gtk_label_set_text(GTK_LABEL(newMin),text);
+ sprintf(text,"%d",thisMax);
+ gtk_label_set_text(GTK_LABEL(newMax),text);
+
+ gtk_widget_set_sensitive(add_b,TRUE);
+ gtk_widget_set_sensitive(update_b,FALSE);
+ gtk_widget_set_sensitive(delete_b,FALSE);
+ break;
+
+ case UPDATE_CURRENT:
+ g_print("%s: UPDATE_CURRENT\n",__FUNCTION__);
+ sprintf(text,"%d",thisVal);
+ gtk_label_set_text(GTK_LABEL(newVal),text);
+ sprintf(text,"%d",thisMin);
+ gtk_label_set_text(GTK_LABEL(newMin),text);
+ sprintf(text,"%d",thisMax);
+ gtk_label_set_text(GTK_LABEL(newMax),text);
+ break;
+
+ case UPDATE_EXISTING:
+ g_print("%s: UPDATE_EXISTING Type=%d Action=%d\n",__FUNCTION__,thisType,thisAction);
+ switch(thisEvent) {
+ case MIDI_EVENT_NONE:
+ gtk_label_set_text(GTK_LABEL(newEvent),"NONE");
+ break;
+ case MIDI_EVENT_NOTE:
+ gtk_label_set_text(GTK_LABEL(newEvent),"NOTE");
+ break;
+ case MIDI_EVENT_CTRL:
+ gtk_label_set_text(GTK_LABEL(newEvent),"CTRL");
+ break;
+ case MIDI_EVENT_PITCH:
+ gtk_label_set_text(GTK_LABEL(newEvent),"PITCH");
+ break;
+ }
+ if (thisChannel >= 0) {
+ sprintf(text,"%d",thisChannel);
+ } else {
+ sprintf(text,"%s","Any");
+ }
+ gtk_label_set_text(GTK_LABEL(newChannel),text);
+ sprintf(text,"%d",thisNote);
+ gtk_label_set_text(GTK_LABEL(newNote),text);
+ gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(newType));
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"NONE");
+ switch(thisEvent) {
+ case MIDI_EVENT_NONE:
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
+ break;
+ case MIDI_EVENT_NOTE:
+ case MIDI_EVENT_PITCH:
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"KEY");
+ if(thisType==MIDI_TYPE_NONE) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
+ } else if(thisType==MIDI_TYPE_KEY) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newType),1);
+ }
+ break;
+ case MIDI_EVENT_CTRL:
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"KNOB/SLIDER");
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"WHEEL");
+ if(thisType==MIDI_TYPE_NONE) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
+ } else if(thisType==MIDI_TYPE_KNOB) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newType),1);
+ } else if(thisType==MIDI_TYPE_WHEEL) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX(newType),2);
+ }
+ break;
+ }
+ sprintf(text,"%d",thisVal);
+ gtk_label_set_text(GTK_LABEL(newVal),text);
+ sprintf(text,"%d",thisMin);
+ gtk_label_set_text(GTK_LABEL(newMin),text);
+ sprintf(text,"%d",thisMax);
+ gtk_label_set_text(GTK_LABEL(newMax),text);
+
+ find_current_cmd();
+ g_print("%s: current_cmd %p\n",__FUNCTION__,current_cmd);
+
+ if (current_cmd != NULL) {
+ thisDelay = current_cmd->delay;
+ thisVfl1 = current_cmd->vfl1;
+ thisVfl2 = current_cmd->vfl2;
+ thisFl1 = current_cmd->fl1;
+ thisFl2 = current_cmd->fl2;
+ thisLft1 = current_cmd->lft1;
+ thisLft2 = current_cmd->lft2;
+ thisRgt1 = current_cmd->rgt1;
+ thisRgt2 = current_cmd->rgt2;
+ thisFr1 = current_cmd->fr1;
+ thisFr2 = current_cmd->fr2;
+ thisVfr1 = current_cmd->vfr1;
+ thisVfr2 = current_cmd->vfr2;
+ }
+ // no need for g_idle_add since this is called in the idle queue
+ update_wheelparams(NULL);
+ gtk_widget_set_sensitive(add_b,FALSE);
+ gtk_widget_set_sensitive(update_b,TRUE);
+ gtk_widget_set_sensitive(delete_b,TRUE);
+ break;
+
+ }
+
+ return 0;
+}
+
+void NewMidiConfigureEvent(enum MIDIevent event, int channel, int note, int val) {
+
+ gboolean valid;
+ char *str_event;
+ char *str_channel;
+ char *str_note;
+ char *str_type;
+ char *str_action;
+
+ gint tree_event;
+ gint tree_channel;
+ gint tree_note;
+
+ //g_print("%s: event=%d channel=%d note=%d val=%d\n", __FUNCTION__,event,channel,note,val);
+
+ if(event==thisEvent && channel==thisChannel && note==thisNote) {
+ //g_print("%s: current event\n",__FUNCTION__);
+ thisVal=val;
+ if(val<thisMin) thisMin=val;
+ if(val>thisMax) thisMax=val;
+ g_idle_add(update,GINT_TO_POINTER(UPDATE_CURRENT));
+ } else {
+ //g_print("%s: new or existing event\n",__FUNCTION__);
+ thisEvent=event;
+ thisChannel=channel;
+ if (accept_any) thisChannel=-1;
+ thisNote=note;
+ thisVal=val;
+ thisMin=val;
+ thisMax=val;
+ thisType=MIDI_TYPE_NONE;
+ thisAction=MIDI_ACTION_NONE;
+ //
+ // set default values for wheel parameters
+ //
+ thisDelay = 0;
+ thisVfl1 = -1;
+ thisVfl2 = -1;
+ thisFl1 = -1;
+ thisFl2 = -1;
+ thisLft1 = 0;
+ thisLft2 = 63;
+ thisRgt1 = 65;
+ thisRgt2 =127;
+ thisFr1 = -1;
+ thisFr2 = -1;
+ thisVfr1 = -1;
+ thisVfr2 = -1;
+
+ // search tree to see if it is existing event
+ valid=gtk_tree_model_get_iter_first(model,&iter);
+ while(valid) {
+ gtk_tree_model_get(model, &iter, EVENT_COLUMN, &str_event, -1);
+ gtk_tree_model_get(model, &iter, CHANNEL_COLUMN, &str_channel, -1);
+ gtk_tree_model_get(model, &iter, NOTE_COLUMN, &str_note, -1);
+ gtk_tree_model_get(model, &iter, TYPE_COLUMN, &str_type, -1);
+ gtk_tree_model_get(model, &iter, ACTION_COLUMN, &str_action, -1);
+
+ //g_print("%s: %s %s %s %s %s\n",__FUNCTION__,str_event,str_channel,str_note,str_type,str_action);
+
+ if(str_event!=NULL && str_channel!=NULL && str_note!=NULL && str_type!=NULL && str_action!=NULL) {
+ if(strcmp(str_event,"CTRL")==0) {
+ tree_event=MIDI_EVENT_CTRL;
+ } else if(strcmp(str_event,"PITCH")==0) {
+ tree_event=MIDI_EVENT_PITCH;
+ } else if(strcmp(str_event,"NOTE")==0) {
+ tree_event=MIDI_EVENT_NOTE;
+ } else {
+ tree_event=MIDI_EVENT_NONE;
+ }
+ if (!strncmp(str_channel,"Any", 3)) {
+ tree_channel=-1;
+ } else {
+ tree_channel=atoi(str_channel);
+ }
+ tree_note=atoi(str_note);
+
+ if(thisEvent==tree_event && thisChannel==tree_channel && thisNote==tree_note) {
+ thisVal=0;
+ thisMin=0;
+ thisMax=0;
+ if(strcmp(str_type,"KEY")==0) {
+ thisType=MIDI_TYPE_KEY;
+ } else if(strcmp(str_type,"KNOB/SLIDER")==0) {
+ thisType=MIDI_TYPE_KNOB;
+ } else if(strcmp(str_type,"WHEEL")==0) {
+ thisType=MIDI_TYPE_WHEEL;
+ } else {
+ thisType=MIDI_TYPE_NONE;
+ }
+ thisAction=MIDI_ACTION_NONE;
+ int i=1;
+ while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+ if(strcmp(ActionTable[i].str,str_action)==0) {
+ thisAction=ActionTable[i].action;
+ break;
+ }
+ i++;
+ }
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(view),gtk_tree_model_get_path(model,&iter),NULL,FALSE);
+ g_idle_add(update,GINT_TO_POINTER(UPDATE_EXISTING));
+ return;
+ }
+ }
+
+ valid=gtk_tree_model_iter_next(model,&iter);
+ }
+
+ //
+ // It is not guaranteed that update() will be executed before
+ // thisAction & friends are overwritten by the next incoming MIDI
+ // message. Therefore, we should allocate a data structure with
+ // all information therein that is needed by update() and pass
+ // a pointer.
+ //
+ g_idle_add(update,GINT_TO_POINTER(UPDATE_NEW));
+ }
+}
+
+void midi_save_state() {
+ char name[80];
+ char value[80];
+ struct desc *cmd;
+ gint index;
+
+ index=0;
+ for (int i=0; i<n_midi_devices; i++) {
+ if (midi_devices[i].active) {
+ sprintf(name,"mididevice[%d].name",index);
+ setProperty(name, midi_devices[i].name);
+ index++;
+ }
+ }
+
+ // the value i=128 is for the PitchBend
+ for(int i=0;i<129;i++) {
+ index=0;
+ cmd=MidiCommandsTable[i];
+ while(cmd!=NULL) {
+ //ATTENTION: g_print assumes ActionTable is sorted by action enum
+ //g_print("%s: channel=%d key=%d event=%s type=%s action=%s\n",__FUNCTION__,cmd->channel,i,midi_events[cmd->event],midi_types[cmd->type],ActionTable[cmd->action].str);
+
+ //
+ // There might be events that share the channel and the note value (one NOTE and one CTRL, for example)
+ // These must not share the same key in the property database so the "running index" must be part of the key
+ //
+
+ sprintf(name,"midi[%d].index[%d].event",i,index);
+ setProperty(name,midi_events[cmd->event]);
+
+ sprintf(name,"midi[%d].index[%d].type",i,index);
+ setProperty(name,midi_types[cmd->type]);
+
+ //ATTENTION: assumes ActionTable is sorted by action enum
+ sprintf(name,"midi[%d].index[%d].action",i,index);
+ setProperty(name,(char *) ActionTable[cmd->action].str);
+
+ sprintf(name,"midi[%d].index[%d].channel",i,index);
+ sprintf(value,"%d",cmd->channel);
+ setProperty(name, value);
+
+ //
+ // For wheels, also store the additional parameters,
+ // but do so only if they deviate from the default values.
+ //
+ if (cmd->type == MIDI_TYPE_WHEEL) {
+ if (cmd->delay > 0) {
+ sprintf(name,"midi[%d].index[%d].delay",i,index);
+ sprintf(value,"%d",cmd->delay);
+ setProperty(name, value);
+ }
+ if (cmd->vfl1 != -1 || cmd->vfl2 != -1) {
+ sprintf(name,"midi[%d].index[%d].vfl1",i,index);
+ sprintf(value,"%d",cmd->vfl1);
+ setProperty(name, value);
+ sprintf(name,"midi[%d].index[%d].vfl2",i,index);
+ sprintf(value,"%d",cmd->vfl2);
+ setProperty(name, value);
+ }
+ if (cmd->fl1 != -1 || cmd->fl2 != -1) {
+ sprintf(name,"midi[%d].index[%d].fl1",i,index);
+ sprintf(value,"%d",cmd->fl1);
+ setProperty(name, value);
+ sprintf(name,"midi[%d].index[%d].fl2",i,index);
+ sprintf(value,"%d",cmd->fl2);
+ setProperty(name, value);
+ }
+ if (cmd->lft1 != 0 || cmd->lft2 != 63) {
+ sprintf(name,"midi[%d].index[%d].lft1",i,index);
+ sprintf(value,"%d",cmd->lft1);
+ setProperty(name, value);
+ sprintf(name,"midi[%d].index[%d].lft2",i,index);
+ sprintf(value,"%d",cmd->lft2);
+ setProperty(name, value);
+ }
+ if (cmd->rgt1 != 65 || cmd->rgt2 != 127) {
+ sprintf(name,"midi[%d].index[%d].rgt1",i,index);
+ sprintf(value,"%d",cmd->rgt1);
+ setProperty(name, value);
+ sprintf(name,"midi[%d].index[%d].rgt2",i,index);
+ sprintf(value,"%d",cmd->rgt2);
+ setProperty(name, value);
+ }
+ if (cmd->fr1 != -1 || cmd->fr2 != -1) {
+ sprintf(name,"midi[%d].index[%d].fr1",i,index);
+ sprintf(value,"%d",cmd->fr1);
+ setProperty(name, value);
+ sprintf(name,"midi[%d].index[%d].fr2",i,index);
+ sprintf(value,"%d",cmd->fr2);
+ setProperty(name, value);
+ }
+ if (cmd->vfr1 != -1 || cmd->vfr2 != -1) {
+ sprintf(name,"midi[%d].index[%d].vfr1",i,index);
+ sprintf(value,"%d",cmd->vfr1);
+ setProperty(name, value);
+ sprintf(name,"midi[%d].index[%d].vfr2",i,index);
+ sprintf(value,"%d",cmd->vfr2);
+ setProperty(name, value);
+ }
+ }
+
+ cmd=cmd->next;
+ index++;
+ }
+
+ if(index!=0) {
+ sprintf(name,"midi[%d].indices",i);
+ sprintf(value,"%d",index);
+ setProperty(name,value);
+ }
+
+ }
+}
+
+void midi_restore_state() {
+ char name[80];
+ char *value;
+ gint indices;
+ gint channel;
+ gint event;
+ gint onoff;
+ gint type;
+ gint action;
+ gint delay;
+ gint vfl1, vfl2;
+ gint fl1, fl2;
+ gint lft1, lft2;
+ gint rgt1, rgt2;
+ gint fr1, fr2;
+ gint vfr1, vfr2;
+
+ get_midi_devices();
+ MidiReleaseCommands();
+
+ //g_print("%s\n",__FUNCTION__);
+
+ //
+ // Note this is too early to open the MIDI devices, since the
+ // radio has not yet fully been configured. Therefore, only
+ // set the "active" flag, and the devices will be opened in
+ // radio.c when it is appropriate
+ //
+
+ for(int i=0; i<MAX_MIDI_DEVICES; i++) {
+ sprintf(name,"mididevice[%d].name",i);
+ value=getProperty(name);
+ if (value) {
+ for (int j=0; j<n_midi_devices; j++) {
+ if(strcmp(midi_devices[j].name,value)==0) {
+ midi_devices[j].active=1;
+ g_print("%s: mark device %s at %d as active\n",__FUNCTION__,value,j);
+ }
+ }
+ }
+ }
+
+ // the value i=128 is for the PitchBend
+ for(int i=0;i<129;i++) {
+ sprintf(name,"midi[%d].indices",i);
+ value=getProperty(name);
+ if(value) {
+ indices=atoi(value);
+ for(int index=0; index<indices; index++) {
+ sprintf(name,"midi[%d].index[%d].event",i,index);
+ value=getProperty(name);
+ event=MIDI_EVENT_NONE;
+ if(value) {
+ for(int j=0;j<4;j++) {
+ if(strcmp(value,midi_events[j])==0) {
+ event=j;
+ break;
+ }
+ }
+ }
+ sprintf(name,"midi[%d].index[%d].type",i,index);
+ value=getProperty(name);
+ type=MIDI_TYPE_NONE;
+ if(value) {
+ for(int j=0;j<5;j++) {
+ if(strcmp(value,midi_types[j])==0) {
+ type=j;
+ break;
+ }
+ }
+ }
+ sprintf(name,"midi[%d].index[%d].action",i,index);
+ value=getProperty(name);
+ action=MIDI_ACTION_NONE;
+ if(value) {
+ int j=0;
+ while(ActionTable[j].type!=MIDI_ACTION_LAST) {
+ if(strcmp(value,ActionTable[j].str)==0) {
+ action=ActionTable[j].action;
+ break;
+ }
+ j++;
+ }
+ }
+ sprintf(name,"midi[%d].index[%d].channel",i,index);
+ value=getProperty(name);
+ channel=-1;
+ if (value) {
+ channel=atoi(value);
+ if (channel < -2 || channel > 15) channel=0;
+ }
+
+ sprintf(name,"midi[%d].index[%d].delay",i,index);
+ value=getProperty(name);
+ delay=0;
+ if (value) delay=atoi(value);
+
+ sprintf(name,"midi[%d].index[%d].vfl1",i,index);
+ value=getProperty(name);
+ vfl1=-1;
+ if (value) vfl1=atoi(value);
+ sprintf(name,"midi[%d].index[%d].vfl2",i,index);
+ value=getProperty(name);
+ vfl2=-1;
+ if (value) vfl2=atoi(value);
+
+ sprintf(name,"midi[%d].index[%d].fl1",i,index);
+ value=getProperty(name);
+ fl1=-1;
+ if (value) fl1=atoi(value);
+ sprintf(name,"midi[%d].index[%d].fl2",i,index);
+ value=getProperty(name);
+ fl2=-1;
+ if (value) fl2=atoi(value);
+
+ sprintf(name,"midi[%d].index[%d].lft1",i,index);
+ value=getProperty(name);
+ lft1=0;
+ if (value) lft1=atoi(value);
+ sprintf(name,"midi[%d].index[%d].lft2",i,index);
+ value=getProperty(name);
+ lft2=63;
+ if (value) lft2=atoi(value);
+
+ sprintf(name,"midi[%d].index[%d].rgt1",i,index);
+ value=getProperty(name);
+ rgt1=65;
+ if (value) rgt1=atoi(value);
+ sprintf(name,"midi[%d].index[%d].rgt2",i,index);
+ value=getProperty(name);
+ rgt2=127;
+ if (value) rgt2=atoi(value);
+
+ sprintf(name,"midi[%d].index[%d].fr1",i,index);
+ value=getProperty(name);
+ fr1=-1;
+ if (value) fr1=atoi(value);
+ sprintf(name,"midi[%d].index[%d].fr2",i,index);
+ value=getProperty(name);
+ fr2=-1;
+ if (value) fr2=atoi(value);
+
+ sprintf(name,"midi[%d].index[%d].vfr1",i,index);
+ value=getProperty(name);
+ vfr1=-1;
+ if (value) vfr1=atoi(value);
+ sprintf(name,"midi[%d].index[%d].vfr2",i,index);
+ value=getProperty(name);
+ vfr2=-1;
+ if (value) vfr2=atoi(value);
+
+ // ATTENTION: this assumes ActionTable is sorted by Action enums
+ onoff=ActionTable[action].onoff;
+
+ struct desc *desc = (struct desc *) malloc(sizeof(struct desc));
+
+ desc->next = NULL;
+ desc->action = action; // MIDIaction
+ desc->type = type; // MIDItype
+ desc->event = event; // MIDevent
+ desc->onoff = onoff;
+ desc->delay = delay;
+ desc->vfl1 = vfl1;
+ desc->vfl2 = vfl2;
+ desc->fl1 = fl1;
+ desc->fl2 = fl2;
+ desc->lft1 = lft1;
+ desc->lft2 = lft2;
+ desc->rgt1 = rgt1;
+ desc->rgt2 = rgt2;
+ desc->fr1 = fr1;
+ desc->fr2 = fr2;
+ desc->vfr1 = vfr1;
+ desc->vfr2 = vfr2;
+ desc->channel = channel;
+
+//g_print("DESC INIT Note=%3d Action=%3d Type=%3d Event=%3d OnOff=%3d Chan=%3d Delay=%3d THR=%3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d\n",
+// i, action, type, event, onoff, channel, delay,
+// vfl1, vfl2, fl1, fl2, lft1, lft2, rgt1, rgt2, fr1, fr2, vfr1, vfr2);
+ MidiAddCommand(i, desc);
+ }
+ }
+ }
+}
+
--- /dev/null
+/* Copyright (C)
+* 2021 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+extern void midi_menu(GtkWidget *parent);
+extern void NewMidiConfigureEvent(enum MIDIevent event, int channel, int note, int val);
+extern void midi_save_state();
+extern void midi_restore_state();
+
#ifdef CLIENT_SERVER
#include "server_menu.h"
#endif
+#ifdef MIDI
+#include "midi.h"
+#include "midi_menu.h"
+#endif
static GtkWidget *menu_b=NULL;
}
#endif
+#ifdef MIDI
+void start_midi() {
+ cleanup();
+ midi_menu(top_window);
+}
+
+static gboolean midi_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ start_midi();
+ return TRUE;
+}
+#endif
+
void new_menu()
{
int i;
}
#endif
+#ifdef MIDI
+ GtkWidget *midi_b=gtk_button_new_with_label("MIDI");
+ g_signal_connect (midi_b, "button-press-event", G_CALLBACK(midi_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),midi_b,(i%5),i/5,1,1);
+ i++;
+#endif
+
//
// We need at least two receivers and two ADCs to do DIVERSITY
//
#endif
#include "rigctl_menu.h"
#ifdef MIDI
-// rather than including MIDI.h with all its internal stuff
-// (e.g. enum components) we just declare the single bit thereof
-// we need here to make a strict compiler happy.
-void MIDIstartup();
+#include "midi.h"
+#include "alsa_midi.h"
+#include "midi_menu.h"
#endif
#ifdef CLIENT_SERVER
#include "client_server.h"
#define TOOLBAR_HEIGHT (30)
#define WATERFALL_HEIGHT (105)
+gint controller=NO_CONTROLLER;
+
GtkWidget *fixed;
static GtkWidget *vfo_panel;
static GtkWidget *meter;
static GtkWidget *waterfall;
static GtkWidget *audio_waterfall;
+/*
#ifdef GPIO
static GtkWidget *encoders;
static cairo_surface_t *encoders_surface = NULL;
#endif
- gint sat_mode;
+*/
+gint sat_mode;
- int region=REGION_OTHER;
+int region=REGION_OTHER;
- int echo=0;
+int echo=0;
- int radio_sample_rate;
- gboolean iqswap;
+int radio_sample_rate;
+gboolean iqswap;
- static gint save_timer_id;
+static gint save_timer_id;
- DISCOVERED *radio=NULL;
+DISCOVERED *radio=NULL;
#ifdef CLIENT_SERVER
- gboolean radio_is_remote=FALSE;
+gboolean radio_is_remote=FALSE;
#endif
- char property_path[128];
- GMutex property_mutex;
+char property_path[128];
+GMutex property_mutex;
RECEIVER *receiver[MAX_RECEIVERS];
RECEIVER *active_receiver;
break;
#ifdef SOAPYSDR
case SOAPYSDR_PROTOCOL:
- soapy_protocol_init(0,false);
+ soapy_protocol_init(FALSE);
break;
#endif
}
#ifdef SOAPYSDR
adc[0].antenna=0;
if(device==SOAPYSDR_USB_DEVICE) {
- adc[0].rx_gain=malloc(radio->info.soapy.rx_gains*sizeof(gint));
- for (size_t i = 0; i < radio->info.soapy.rx_gains; i++) {
- adc[0].rx_gain[i]=0;
+ adc[0].gain=0;
+ if(radio->info.soapy.rx_gains>0) {
+ adc[0].min_gain=radio->info.soapy.rx_range[0].minimum;
+ adc[0].max_gain=radio->info.soapy.rx_range[0].maximum;;
+ } else {
+ adc[0].min_gain=0.0;
+ adc[0].max_gain=100.0;
}
adc[0].agc=FALSE;
dac[0].antenna=1;
- dac[0].tx_gain=malloc(radio->info.soapy.tx_gains*sizeof(gint));
- for (size_t i = 0; i < radio->info.soapy.tx_gains; i++) {
- dac[0].tx_gain[i]=0;
- }
+ dac[0].gain=0;
}
#endif
#ifdef SOAPYSDR
adc[1].antenna=0;
if(device==SOAPYSDR_USB_DEVICE) {
- adc[1].rx_gain=malloc(radio->info.soapy.rx_gains*sizeof(gint));
- for (size_t i = 0; i < radio->info.soapy.rx_gains; i++) {
- adc[1].rx_gain[i]=0;
+ adc[1].gain=0;
+ if(radio->info.soapy.rx_gains>0) {
+ adc[1].min_gain=radio->info.soapy.rx_range[0].minimum;
+ adc[1].max_gain=radio->info.soapy.rx_range[0].maximum;;
+ } else {
+ adc[1].min_gain=0.0;
+ adc[1].max_gain=100.0;
}
+ adc[1].max_gain=0;
adc[1].agc=FALSE;
-
- dac[1].tx_gain=malloc(radio->info.soapy.tx_gains*sizeof(gint));
- for (size_t i = 0; i < radio->info.soapy.tx_gains; i++) {
- dac[1].tx_gain[i]=0;
- }
+ dac[1].antenna=1;
+ dac[1].gain=0;
}
radio_sample_rate=radio->info.soapy.sample_rate;
if(can_transmit) {
soapy_protocol_create_transmitter(transmitter);
soapy_protocol_set_tx_antenna(transmitter,dac[0].antenna);
-/*
- for(int i=0;i<radio->info.soapy.tx_gains;i++) {
- soapy_protocol_set_tx_gain_element(transmitter,radio->info.soapy.tx_gain[i],dac[0].tx_gain[i]);
- }
-*/
soapy_protocol_set_tx_gain(transmitter,transmitter->drive);
soapy_protocol_set_tx_frequency(transmitter);
soapy_protocol_start_transmitter(transmitter);
}
soapy_protocol_set_rx_antenna(rx,adc[0].antenna);
-/*
- for(int i=0;i<radio->info.soapy.rx_gains;i++) {
- soapy_protocol_set_gain_element(rx,radio->info.soapy.rx_gain[i],adc[0].rx_gain[i]);
- }
-*/
-
soapy_protocol_set_rx_frequency(rx,VFO_A);
soapy_protocol_set_automatic_gain(rx,adc[0].agc);
- for(int i=0;i<radio->info.soapy.rx_gains;i++) {
- soapy_protocol_set_gain_element(rx,radio->info.soapy.rx_gain[i],adc[0].rx_gain[i]);
- }
+ soapy_protocol_set_gain(rx);
if(vfo[0].ctun) {
setFrequency(vfo[0].ctun_frequency);
soapy_protocol_start_receiver(rx);
//g_print("radio: set rf_gain=%f\n",rx->rf_gain);
- soapy_protocol_set_gain(rx,rx->rf_gain);
+ soapy_protocol_set_gain(rx);
}
#endif
gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW));
+#ifdef MIDI
//
- // MIDIstartup must not be called before the radio is completely set up, since
- // then MIDI can asynchronously trigger actions which require the radio already
- // running. So this is the last thing we do when starting the radio.
+ // The MIDI devices could not be opened in midi_restore_state() since MIDI events
+ // must not fly in before the radio is fully configured. Therefore midi_restore_state()
+ // simply marks the devices to be opened here by hi-jacking the "active" flag. Note that
+ // apart from this (ab)use, this flag is updated ONLY in register_midi_device() and
+ // close_midi_device().
//
-#ifdef MIDI
- MIDIstartup();
+ for (i=0; i<n_midi_devices; i++) {
+ if (midi_devices[i].active) {
+ //
+ // If device was marked "active" in the props file, open (register) it
+ // Note this flag is hi-jacked, so clear it before opening. It will be set
+ // if the MIDI device has been opened successfully
+ //
+ midi_devices[i].active=0;
+ register_midi_device(i);
+ }
+ }
#endif
#ifdef CLIENT_SERVER
break;
#ifdef SOAPYSDR
case SOAPYSDR_PROTOCOL:
- soapy_protocol_set_gain(active_receiver,value * 1.0);
+ soapy_protocol_set_gain_element(active_receiver,radio->info.soapy.rx_gain[0],(int)adc[0].gain);
break;
#endif
}
memRestoreState();
vfo_restore_state();
modesettings_restore_state();
-#ifdef GPIO
gpio_restore_actions();
-#endif
value=getProperty("rigctl_enable");
if(value) rigctl_enable=atoi(value);
value=getProperty("rigctl_port_base");
value=getProperty("rigctl_serial_port");
if (value) strcpy(ser_port,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);
+ */
value=getProperty("split");
if(value) split=atoi(value);
value=getProperty("mute_rx_while_transmitting");
if(value) mute_rx_while_transmitting=atoi(value);
-#ifdef SOAPYSDR
+ value=getProperty("radio.adc[0].filters");
+ if(value) adc[0].filters=atoi(value);
+ value=getProperty("radio.adc[0].hpf");
+ if(value) adc[0].hpf=atoi(value);
+ value=getProperty("radio.adc[0].lpf");
+ if(value) adc[0].lpf=atoi(value);
+ value=getProperty("radio.adc[0].antenna");
+ if(value) adc[0].antenna=atoi(value);
+ value=getProperty("radio.adc[0].dither");
+ if(value) adc[0].dither=atoi(value);
+ value=getProperty("radio.adc[0].random");
+ if(value) adc[0].random=atoi(value);
+ value=getProperty("radio.adc[0].preamp");
+ if(value) adc[0].preamp=atoi(value);
+ value=getProperty("radio.adc[0].attenuation");
+ if(value) adc[0].attenuation=atoi(value);
+ value=getProperty("radio.adc[0].enable_step_attenuation");
+ if(value) adc[0].enable_step_attenuation=atoi(value);
+ value=getProperty("radio.adc[0].gain");
+ if(value) adc[0].gain=atof(value);
+ value=getProperty("radio.adc[0].min_gain");
+ if(value) adc[0].min_gain=atof(value);
+ value=getProperty("radio.adc[0].max_gain");
+ if(value) adc[0].max_gain=atof(value);
+
+#ifdef SOAPYSDR
if(device==SOAPYSDR_USB_DEVICE) {
- char name[128];
- for(int i=0;i<radio->info.soapy.rx_gains;i++) {
- sprintf(name,"radio.adc[0].rx_gain.%s",radio->info.soapy.rx_gain[i]) ;
- value=getProperty(name);
- if(value!=NULL) adc[0].rx_gain[i]=atoi(value);
- }
value=getProperty("radio.adc[0].agc");
- if(value!=NULL) adc[0].agc=atoi(value);
- value=getProperty("radio.adc[0].antenna");
- if(value!=NULL) adc[0].antenna=atoi(value);
-
- value=getProperty("radio.dac[0].antenna");
- if(value!=NULL) dac[0].antenna=atoi(value);
- for(int i=0;i<radio->info.soapy.tx_gains;i++) {
- sprintf(name,"radio.dac[0].tx_gain.%s",radio->info.soapy.tx_gain[i]);
- value=getProperty(name);
- if(value!=NULL) dac[0].tx_gain[i]=atoi(value);
+ if(value) adc[0].agc=atoi(value);
+ }
+#endif
+ value=getProperty("radio.dac[0].antenna");
+ if(value) dac[0].antenna=atoi(value);
+ value=getProperty("radio.dac[0].gain");
+ if(value) dac[0].gain=atof(value);
+
+ if(receivers>1) {
+ value=getProperty("radio.adc[1].filters");
+ if(value) adc[1].filters=atoi(value);
+ value=getProperty("radio.adc[1].hpf");
+ if(value) adc[1].hpf=atoi(value);
+ value=getProperty("radio.adc[1].lpf");
+ if(value) adc[1].lpf=atoi(value);
+ value=getProperty("radio.adc[1].antenna");
+ if(value) adc[1].antenna=atoi(value);
+ value=getProperty("radio.adc[1].dither");
+ if(value) adc[1].dither=atoi(value);
+ value=getProperty("radio.adc[1].random");
+ if(value) adc[1].random=atoi(value);
+ value=getProperty("radio.adc[1].preamp");
+ if(value) adc[1].preamp=atoi(value);
+ value=getProperty("radio.adc[1].attenuation");
+ if(value) adc[1].attenuation=atoi(value);
+ value=getProperty("radio.adc[1].enable_step_attenuation");
+ if(value) adc[1].enable_step_attenuation=atoi(value);
+ value=getProperty("radio.adc[1].gain");
+ if(value) adc[1].gain=atof(value);
+ value=getProperty("radio.adc[1].min_gain");
+ if(value) adc[1].min_gain=atof(value);
+ value=getProperty("radio.adc[1].max_gain");
+ if(value) adc[1].max_gain=atof(value);
+
+
+#ifdef SOAPYSDR
+ if(device==SOAPYSDR_USB_DEVICE) {
+ value=getProperty("radio.adc[1].agc");
+ if(value) adc[1].agc=atoi(value);
}
+#endif
+
+ value=getProperty("radio.dac[1].antenna");
+ if(value) dac[1].antenna=atoi(value);
+ value=getProperty("radio.dac[1].gain");
+ if(value) dac[1].gain=atof(value);
+
}
+
+#ifdef MIDI
+ midi_restore_state();
#endif
value=getProperty("radio.display_sequence_errors");
sprintf(value,"%f",tone_level);
setProperty("tone_level",value);
+ /*
sprintf(value,"%d",adc_attenuation[0]);
setProperty("adc_0_attenuation",value);
sprintf(value,"%d",adc_attenuation[1]);
setProperty("adc_1_attenuation",value);
+ */
sprintf(value,"%d",rx_gain_calibration);
setProperty("rx_gain_calibration",value);
-#ifdef SOAPYSDR
+ sprintf(value,"%d", adc[0].filters);
+ setProperty("radio.adc[0].filters",value);
+ sprintf(value,"%d", adc[0].hpf);
+ setProperty("radio.adc[0].hpf",value);
+ sprintf(value,"%d", adc[0].lpf);
+ setProperty("radio.adc[0].lpf",value);
+ sprintf(value,"%d", adc[0].antenna);
+ setProperty("radio.adc[0].antenna",value);
+ sprintf(value,"%d", adc[0].dither);
+ setProperty("radio.adc[0].dither",value);
+ sprintf(value,"%d", adc[0].random);
+ setProperty("radio.adc[0].random",value);
+ sprintf(value,"%d", adc[0].preamp);
+ setProperty("radio.adc[0].preamp",value);
+ sprintf(value,"%d", adc[0].attenuation);
+ setProperty("radio.adc[0].attenuation",value);
+ sprintf(value,"%d", adc[0].enable_step_attenuation);
+ setProperty("radio.adc[0].enable_step_attenuation",value);
+ sprintf(value,"%f", adc[0].gain);
+ setProperty("radio.adc[0].gain",value);
+ sprintf(value,"%f", adc[0].min_gain);
+ setProperty("radio.adc[0].min_gain",value);
+ sprintf(value,"%f", adc[0].max_gain);
+ setProperty("radio.adc[0].max_gain",value);
+
+
+#ifdef SOAPYSDR
if(device==SOAPYSDR_USB_DEVICE) {
- char name[128];
- for(int i=0;i<radio->info.soapy.rx_gains;i++) {
- sprintf(name,"radio.adc[0].rx_gain.%s",radio->info.soapy.rx_gain[i]);
- sprintf(value,"%d", adc[0].rx_gain[i]);
- setProperty(name,value);
- }
- sprintf(name,"radio.adc[0].agc");
sprintf(value,"%d", soapy_protocol_get_automatic_gain(receiver[0]));
- setProperty(name,value);
- sprintf(name,"radio.adc[0].antenna");
- sprintf(value,"%d", adc[0].antenna);
- setProperty(name,value);
-
- sprintf(name,"radio.dac[0].antenna");
- sprintf(value,"%d", dac[0].antenna);
- setProperty(name,value);
-
- for(int i=0;i<radio->info.soapy.tx_gains;i++) {
- sprintf(name,"radio.dac[0].tx_gain.%s",radio->info.soapy.tx_gain[i]);
- sprintf(value,"%d", dac[0].tx_gain[i]);
- setProperty(name,value);
- }
+ setProperty("radio.adc[0].agc",value);
+ }
+#endif
- for(int i=0;i<radio->info.soapy.rx_gains;i++) {
- sprintf(name,"radio.adc[1].rx_gain.%s",radio->info.soapy.rx_gain[i]);
- sprintf(value,"%d", adc[1].rx_gain[i]);
- setProperty(name,value);
- }
- sprintf(name,"radio.adc[1].agc");
- sprintf(value,"%d", soapy_protocol_get_automatic_gain(receiver[1]));
- setProperty(name,value);
- sprintf(name,"radio.adc[1].antenna");
+ if(receivers>1) {
+ sprintf(value,"%d", adc[1].filters);
+ setProperty("radio.adc[1].filters",value);
+ sprintf(value,"%d", adc[1].hpf);
+ setProperty("radio.adc[1].hpf",value);
+ sprintf(value,"%d", adc[1].lpf);
+ setProperty("radio.adc[1].lpf",value);
sprintf(value,"%d", adc[1].antenna);
- setProperty(name,value);
-
- sprintf(name,"radio.dac[1].antenna");
- sprintf(value,"%d", dac[1].antenna);
- setProperty(name,value);
-
- for(int i=0;i<radio->info.soapy.tx_gains;i++) {
- sprintf(name,"radio.dac[1].tx_gain.%s",radio->info.soapy.tx_gain[i]);
- sprintf(value,"%d", dac[1].tx_gain[i]);
- setProperty(name,value);
+ setProperty("radio.adc[1].antenna",value);
+ sprintf(value,"%d", adc[1].dither);
+ setProperty("radio.adc[1].dither",value);
+ sprintf(value,"%d", adc[1].random);
+ setProperty("radio.adc[1].random",value);
+ sprintf(value,"%d", adc[1].preamp);
+ setProperty("radio.adc[1].preamp",value);
+ sprintf(value,"%d", adc[1].attenuation);
+ setProperty("radio.adc[1].attenuation",value);
+ sprintf(value,"%d", adc[1].enable_step_attenuation);
+ setProperty("radio.adc[1].enable_step_attenuation",value);
+ sprintf(value,"%f", adc[1].gain);
+ setProperty("radio.adc[1].gain",value);
+ sprintf(value,"%f", adc[1].min_gain);
+ setProperty("radio.adc[1].min_gain",value);
+ sprintf(value,"%f", adc[1].max_gain);
+ setProperty("radio.adc[1].max_gain",value);
+
+#ifdef SOAPYSDR
+ if(device==SOAPYSDR_USB_DEVICE) {
+ sprintf(value,"%d", soapy_protocol_get_automatic_gain(receiver[1]));
+ setProperty("radio.adc[1].agc",value);
}
- }
#endif
+ sprintf(value,"%d", dac[1].antenna);
+ setProperty("radio.dac[1].antenna",value);
+ sprintf(value,"%f", dac[1].gain);
+ setProperty("radio.dac[1].gain",value);
+ }
sprintf(value,"%d",receivers);
setProperty("receivers",value);
}
#endif
+#ifdef MIDI
+ midi_save_state();
+#endif
+
saveProperties(property_path);
g_mutex_unlock(&property_mutex);
}
reconfigure_radio();
g_idle_add(ext_vfo_update,(gpointer)NULL);
gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW));
-#ifdef MIDI
- MIDIstartup();
-#endif
for(int i=0;i<receivers;i++) {
gint timer_id=gdk_threads_add_timeout_full(G_PRIORITY_DEFAULT_IDLE,100, start_spectrum, receiver[i], NULL);
}
PA_500W
};
+extern gint controller;
+
extern DISCOVERED *radio;
#ifdef CLIENT_SERVER
extern gboolean radio_is_remote;
extern TRANSMITTER *transmitter;
-
#define PA_DISABLED 0
#define PA_ENABLED 1
#ifdef SOAPYSDR
static void rf_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
ADC *adc=(ADC *)data;
- active_receiver->rf_gain=gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget));
-
- if(radio->device==SOAPYSDR_USB_DEVICE) {
- soapy_protocol_set_gain(receiver[0],active_receiver->rf_gain);
- }
+ adc->gain=gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget));
-/*
- for(int i=0;i<radio->info.soapy.rx_gains;i++) {
- int value=soapy_protocol_get_gain_element(active_receiver,radio->info.soapy.rx_gain[i]);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(rx_gains[i]),(double)value);
+ if(radio->device==SOAPYSDR_USB_DEVICE) {
+ soapy_protocol_set_gain(receiver[0]);
}
-*/
-
}
static void rx_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
ADC *adc=(ADC *)data;
- int gain;
if(radio->device==SOAPYSDR_USB_DEVICE) {
- gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
- soapy_protocol_set_gain_element(receiver[0],(char *)gtk_widget_get_name(widget),gain);
-
+ adc->gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ soapy_protocol_set_gain_element(receiver[0],(char *)gtk_widget_get_name(widget),adc->gain);
/*
for(int i=0;i<radio->info.soapy.rx_gains;i++) {
if(strcmp(radio->info.soapy.rx_gain[i],(char *)gtk_widget_get_name(widget))==0) {
adc[0].rx_gain[i]=gain;
+ soapy_protocol_set_gain_element(receiver[0],(char *)gtk_widget_get_name(widget),gain);
break;
}
}
*/
-
}
}
static void agc_changed_cb(GtkWidget *widget, gpointer data) {
ADC *adc=(ADC *)data;
gboolean agc=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
- soapy_protocol_set_automatic_gain(receiver[0],agc);
+ soapy_protocol_set_automatic_gain(active_receiver,agc);
+ if(!agc) {
+ soapy_protocol_set_gain(active_receiver);
+ }
}
/*
#ifdef SOAPYSDR
case SOAPYSDR_PROTOCOL:
- {
- GtkWidget *sample_rate_label=gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(sample_rate_label), "<b>Sample Rate:</b>");
- gtk_grid_attach(GTK_GRID(grid),sample_rate_label,col,row,1,1);
- row++;
+ if(strcmp(radio->name,"sdrplay")==0) {
+ GtkWidget *sample_rate_combo_box=gtk_combo_box_text_new();
+// gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sample_rate_combo_box),NULL,"96000");
+// gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sample_rate_combo_box),NULL,"192000");
+// gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sample_rate_combo_box),NULL,"384000");
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sample_rate_combo_box),NULL,"768000");
+ switch(radio_sample_rate) {
+ case 96000:
+ gtk_combo_box_set_active(GTK_COMBO_BOX(sample_rate_combo_box),0);
+ break;
+ case 192000:
+ gtk_combo_box_set_active(GTK_COMBO_BOX(sample_rate_combo_box),1);
+ break;
+ case 384000:
+ gtk_combo_box_set_active(GTK_COMBO_BOX(sample_rate_combo_box),2);
+ break;
+ case 768000:
+ gtk_combo_box_set_active(GTK_COMBO_BOX(sample_rate_combo_box),3);
+ break;
+ }
+ g_signal_connect(sample_rate_combo_box,"changed",G_CALLBACK(sample_rate_cb),radio);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_combo_box,col,row,1,1);
+ row++;
+ } else {
+ GtkWidget *sample_rate_label=gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(sample_rate_label), "<b>Sample Rate:</b>");
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_label,col,row,1,1);
+ row++;
- char rate[16];
- sprintf(rate,"%d",radio->info.soapy.sample_rate);
+ char rate[16];
+ sprintf(rate,"%d",radio->info.soapy.sample_rate);
- GtkWidget *sample_rate=gtk_radio_button_new_with_label(NULL,rate);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate), radio->info.soapy.sample_rate);
- gtk_grid_attach(GTK_GRID(grid),sample_rate,col,row,1,1);
- g_signal_connect(sample_rate,"toggled",G_CALLBACK(sample_rate_cb),GINT_TO_POINTER(radio->info.soapy.sample_rate));
+ GtkWidget *sample_rate=gtk_radio_button_new_with_label(NULL,rate);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate), radio->info.soapy.sample_rate);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate,col,row,1,1);
+ g_signal_connect(sample_rate,"toggled",G_CALLBACK(sample_rate_cb),GINT_TO_POINTER(radio->info.soapy.sample_rate));
- col++;
+ col++;
}
break;
#endif
#include "rx_panadapter.h"
#include "vfo.h"
#include "mode.h"
+#include "actions.h"
#ifdef GPIO
#include "gpio.h"
#endif
}
f = ((min_display/divisor)*divisor)+divisor;
+
cairo_select_font_face(cr, DISPLAY_FONT,
CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_BOLD);
// agc
if(rx->agc!=AGC_OFF) {
- double knee_y=rx->agc_thresh+(double)adc_attenuation[rx->adc];
+ double knee_y=rx->agc_thresh+(double)adc[rx->adc].attenuation;
if (filter_board == ALEX && rx->adc == 0) knee_y += (double)(10*rx->alex_attenuation);
knee_y = floor((rx->panadapter_high - knee_y)
* (double) display_height
/ (rx->panadapter_high - rx->panadapter_low));
- double hang_y=rx->agc_hang+(double)adc_attenuation[rx->adc];
+ double hang_y=rx->agc_hang+(double)adc[rx->adc].attenuation;
if (filter_board == ALEX && rx->adc == 0) hang_y += (double)(10*rx->alex_attenuation);
hang_y = floor((rx->panadapter_high - hang_y)
* (double) display_height
samples[pan]=-200.0;
samples[display_width-1+pan]=-200.0;
if(have_rx_gain) {
- s1=(double)samples[pan]+rx_gain_calibration-adc_attenuation[rx->adc];
+ s1=(double)samples[pan]+rx_gain_calibration-adc[rx->adc].attenuation;
} else {
- s1=(double)samples[pan]+(double)adc_attenuation[rx->adc];
+ s1=(double)samples[pan]+(double)adc[rx->adc].attenuation;
}
cairo_move_to(cr, 0.0, s1);
if (filter_board == ALEX && rx->adc == 0) s1 += (double)(10*rx->alex_attenuation);
}
#ifdef SOAPYSDR
if(protocol==SOAPYSDR_PROTOCOL) {
- s1-=rx->rf_gain;
+ //s1-=rx->rf_gain;
+ s1-=adc[rx->id].gain;
}
#endif
cairo_move_to(cr, 0.0, s1);
for(i=1;i<display_width;i++) {
if(have_rx_gain) {
- s2=(double)samples[i+pan]+rx_gain_calibration-adc_attenuation[rx->adc];
+ s2=(double)samples[i+pan]+rx_gain_calibration-adc[rx->adc].attenuation;
} else {
- s2=(double)samples[i+pan]+(double)adc_attenuation[rx->adc];
+ s2=(double)samples[i+pan]+(double)adc[rx->adc].attenuation;
}
if (filter_board == ALEX && rx->adc == 0) s2 += (double)(10*rx->alex_attenuation);
if (filter_board == CHARLY25) {
}
#ifdef SOAPYSDR
if(protocol==SOAPYSDR_PROTOCOL) {
- s2-=rx->rf_gain;
+ //s2-=rx->rf_gain;
+ s2-=adc[rx->id].gain;
}
#endif
s2 = floor((rx->panadapter_high - s2)
cairo_line_to(cr, (double)i, s2);
}
- cairo_pattern_t *gradient;
- gradient=NULL;
+ cairo_pattern_t *gradient=NULL;
if(display_gradient) {
gradient = cairo_pattern_create_linear(0.0, display_height, 0.0, 0.0);
// calculate where S9 is
//
cairo_set_line_width(cr, 1.0);
}
+ cairo_set_line_width(cr, LINE_WIDTH);
cairo_stroke(cr);
if(gradient) {
cairo_pattern_destroy(gradient);
}
+/*
#ifdef GPIO
if(rx->id==0 && controller==CONTROLLER1) {
}
}
#endif
-
+*/
if(display_sequence_errors) {
if(sequence_errors!=0) {
cairo_move_to(cr,100.0,50.0);
static void rf_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
active_receiver->rf_gain=gtk_range_get_value(GTK_RANGE(af_gain_scale));
+ switch(protocol) {
#ifdef SOAPYSDR
- if(protocol==SOAPYSDR_PROTOCOL) {
- soapy_protocol_set_gain(active_receiver,active_receiver->rf_gain);
- }
+ case SOAPYSDR_PROTOCOL:
+ soapy_protocol_set_gain(active_receiver);
+ break;
#endif
+ default:
+ break;
+ }
}
void update_rf_gain() {
- set_rf_gain(active_receiver->id,active_receiver->rf_gain);
+ //set_rf_gain(active_receiver->id,active_receiver->rf_gain);
+ set_rf_gain(active_receiver->id,adc[active_receiver->id].gain);
}
void set_rf_gain(int rx,double value) {
- receiver[rx]->rf_gain=value;
+ g_print("%s\n",__FUNCTION__);
+ adc[receiver[rx]->id].gain=value;
#ifdef SOAPYSDR
if(protocol==SOAPYSDR_PROTOCOL) {
- soapy_protocol_set_gain(active_receiver,active_receiver->rf_gain);
+ soapy_protocol_set_gain(receiver[rx]);
}
#endif
if(display_sliders) {
- gtk_range_set_value (GTK_RANGE(attenuation_scale),receiver[rx]->rf_gain);
+ //gtk_range_set_value (GTK_RANGE(attenuation_scale),receiver[rx]->rf_gain);
+ gtk_range_set_value (GTK_RANGE(rf_gain_scale),adc[receiver[rx]->id].gain);
} else {
if(scale_status!=RF_GAIN || scale_rx!=rx) {
if(scale_status!=NO_FUNCTION) {
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
rf_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
gtk_widget_set_size_request (rf_gain_scale, 400, 30);
- gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+ //gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+ gtk_range_set_value (GTK_RANGE(rf_gain_scale),adc[receiver[rx]->id].gain);
gtk_widget_show(rf_gain_scale);
gtk_container_add(GTK_CONTAINER(content),rf_gain_scale);
scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
gtk_dialog_run(GTK_DIALOG(scale_dialog));
} else {
g_source_remove(scale_timer);
- gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+ //gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+ gtk_range_set_value (GTK_RANGE(rf_gain_scale),adc[receiver[rx]->id].gain);
scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
}
}
#include "SoapySDR/Device.h"
#include "SoapySDR/Formats.h"
#include "SoapySDR/Version.h"
+#include "SoapySDR/Logger.h"
//#define TIMING
#ifdef TIMING
#include "filter.h"
#include "receiver.h"
#include "transmitter.h"
-//#include "wideband.h"
-//#include "adc.h"
-//#include "dac.h"
#include "radio.h"
#include "main.h"
-//#include "protocol1.h"
#include "soapy_protocol.h"
#include "audio.h"
#include "signal.h"
#include "ext.h"
#include "error_handler.h"
-static double bandwidth=2000000.0;
-static SoapySDRDevice *soapy_device;
-static SoapySDRStream *rx_stream;
+#define MAX_CHANNELS 2
+static SoapySDRStream *rx_stream[MAX_CHANNELS];
static SoapySDRStream *tx_stream;
+static SoapySDRDevice *soapy_device;
static int max_samples;
static int samples=0;
+static double bandwidth=2000000.0;
+
static GThread *receive_thread_id;
static gpointer receive_thread(gpointer data);
}
void soapy_protocol_change_sample_rate(RECEIVER *rx) {
+ int rc;
+
// rx->mutex already locked
- if(rx->sample_rate==radio_sample_rate) {
+ if(strcmp(radio->name,"sdrplay")==0) {
+ g_print("%s: setting samplerate=%f\n",__FUNCTION__,(double)rx->sample_rate);
+ rc=SoapySDRDevice_setSampleRate(soapy_device,SOAPY_SDR_RX,rx->adc,(double)rx->sample_rate);
+ if(rc!=0) {
+ g_print("%s: SoapySDRDevice_setSampleRate(%f) failed: %s\n",__FUNCTION__,(double)rx->sample_rate,SoapySDR_errToStr(rc));
+ }
+ } else if(rx->sample_rate==radio_sample_rate) {
if(rx->resample_buffer!=NULL) {
g_free(rx->resample_buffer);
rx->resample_buffer=NULL;
mic_sample_divisor=rx->sample_rate/48000;
-fprintf(stderr,"soapy_protocol_create_receiver: setting samplerate=%f adc=%d mic_sample_divisor=%d\n",(double)radio_sample_rate,rx->adc,mic_sample_divisor);
+ g_print("%s: device=%p adc=%d setting bandwidth=%f\n",__FUNCTION__,soapy_device,rx->adc,bandwidth);
+ rc=SoapySDRDevice_setBandwidth(soapy_device,SOAPY_SDR_RX,rx->adc,bandwidth);
+ if(rc!=0) {
+ g_print("%s: SoapySDRDevice_setBandwidth(%f) failed: %s\n",__FUNCTION__,(double)bandwidth,SoapySDR_errToStr(rc));
+ }
+
+ g_print("%s: setting samplerate=%f device=%p adc=%d mic_sample_divisor=%d\n",__FUNCTION__,(double)radio_sample_rate,soapy_device,rx->adc,mic_sample_divisor);
rc=SoapySDRDevice_setSampleRate(soapy_device,SOAPY_SDR_RX,rx->adc,(double)radio_sample_rate);
if(rc!=0) {
- fprintf(stderr,"soapy_protocol_create_receiver: SoapySDRDevice_setSampleRate(%f) failed: %s\n",(double)radio_sample_rate,SoapySDR_errToStr(rc));
+ g_print("%s: SoapySDRDevice_setSampleRate(%f) failed: %s\n",__FUNCTION__,(double)radio_sample_rate,SoapySDR_errToStr(rc));
}
size_t channel=rx->adc;
#if defined(SOAPY_SDR_API_VERSION) && (SOAPY_SDR_API_VERSION < 0x00080000)
-fprintf(stderr,"soapy_protocol_create_receiver: SoapySDRDevice_setupStream(version<0x00080000): channel=%ld\n",channel);
- rc=SoapySDRDevice_setupStream(soapy_device,&rx_stream,SOAPY_SDR_RX,SOAPY_SDR_CF32,&channel,1,NULL);
+ g_print("%s: SoapySDRDevice_setupStream(version<0x00080000): channel=%ld\n",__FUNCTION__,channel);
+ rc=SoapySDRDevice_setupStream(soapy_device,&rx_stream[channel],SOAPY_SDR_RX,SOAPY_SDR_CF32,&channel,1,NULL);
if(rc!=0) {
- fprintf(stderr,"soapy_protocol_create_receiver: SoapySDRDevice_setupStream (RX) failed: %s\n",SoapySDR_errToStr(rc));
+ g_print("%s: SoapySDRDevice_setupStream (RX) failed: %s\n",__FUNCTION__,SoapySDR_errToStr(rc));
_exit(-1);
}
#else
-fprintf(stderr,"soapy_protocol_create_receiver: SoapySDRDevice_setupStream(version>=0x00080000): channel=%ld\n",channel);
- rx_stream=SoapySDRDevice_setupStream(soapy_device,SOAPY_SDR_RX,SOAPY_SDR_CF32,&channel,1,NULL);
- if(rx_stream==NULL) {
- fprintf(stderr,"soapy_protocol_create_receiver: SoapySDRDevice_setupStream (RX) failed (rx_stream is NULL)\n");
+ g_print("%s: SoapySDRDevice_setupStream(version>=0x00080000): channel=%ld\n",__FUNCTION__,channel);
+ rx_stream[channel]=SoapySDRDevice_setupStream(soapy_device,SOAPY_SDR_RX,SOAPY_SDR_CF32,&channel,1,NULL);
+ if(rx_stream[channel]==NULL) {
+ g_print("%s: SoapySDRDevice_setupStream (RX) failed (rx_stream is NULL)\n",__FUNCTION__);
_exit(-1);
}
#endif
+ g_print("%s: id=%d soapy_device=%p rx_stream=%p\n",__FUNCTION__,rx->id,soapy_device,rx_stream);
- max_samples=SoapySDRDevice_getStreamMTU(soapy_device,rx_stream);
+ max_samples=SoapySDRDevice_getStreamMTU(soapy_device,rx_stream[channel]);
+ g_print("%s: max_samples=%d\n",__FUNCTION__,max_samples);
if(max_samples>(2*rx->fft_size)) {
max_samples=2*rx->fft_size;
}
- if(max_samples>=4096) {
- max_samples=4096;
- } else if(max_samples>=2048) {
- max_samples=2048;
- } else {
- max_samples=1024;
- }
rx->buffer=g_new(double,max_samples*2);
if(rx->sample_rate==radio_sample_rate) {
}
-fprintf(stderr,"soapy_protocol_create_receiver: max_samples=%d buffer=%p\n",max_samples,rx->buffer);
+g_print("%s: max_samples=%d buffer=%p\n",__FUNCTION__,max_samples,rx->buffer);
}
void soapy_protocol_start_receiver(RECEIVER *rx) {
int rc;
-double rate=SoapySDRDevice_getSampleRate(soapy_device,SOAPY_SDR_RX,rx->adc);
-fprintf(stderr,"soapy_protocol_start_receiver: activate_stream rate=%f\n",rate);
- rc=SoapySDRDevice_activateStream(soapy_device, rx_stream, 0, 0LL, 0);
+ g_print("%s: id=%d soapy_device=%p rx_stream=%p\n",__FUNCTION__,rx->id,soapy_device,rx_stream);
+
+ size_t channel=rx->adc;
+ double rate=SoapySDRDevice_getSampleRate(soapy_device,SOAPY_SDR_RX,rx->adc);
+ g_print("%s: rate=%f\n",__FUNCTION__,rate);
+
+ g_print("%s: activate Stream\n",__FUNCTION__);
+ rc=SoapySDRDevice_activateStream(soapy_device, rx_stream[channel], 0, 0LL, 0);
if(rc!=0) {
- fprintf(stderr,"soapy_protocol_start_receiver: SoapySDRDevice_activateStream failed: %s\n",SoapySDR_errToStr(rc));
+ g_print("%s: SoapySDRDevice_activateStream failed: %s\n",__FUNCTION__,SoapySDR_errToStr(rc));
_exit(-1);
}
-fprintf(stderr,"soapy_protocol_start_receiver: create receive_thread\n");
+ g_print("%s: create receiver_thread\n",__FUNCTION__);
receive_thread_id = g_thread_new( "soapy_rx", receive_thread, rx);
if( ! receive_thread_id )
{
- fprintf(stderr,"g_thread_new failed for receive_thread\n");
+ g_print("%s: g_thread_new failed for receive_thread\n",__FUNCTION__);
exit( -1 );
}
- fprintf(stderr, "receive_thread: id=%p\n",receive_thread_id);
+ g_print("%s: receiver_thread_id=%p\n",__FUNCTION__,receive_thread_id);
}
void soapy_protocol_create_transmitter(TRANSMITTER *tx) {
int rc;
-
-fprintf(stderr,"soapy_protocol_create_transmitter: setting samplerate=%f\n",(double)tx->iq_output_rate);
+ g_print("%s: setting samplerate=%f\n",__FUNCTION__,(double)tx->iq_output_rate);
rc=SoapySDRDevice_setSampleRate(soapy_device,SOAPY_SDR_TX,tx->dac,(double)tx->iq_output_rate);
if(rc!=0) {
- fprintf(stderr,"soapy_protocol_configure_transmitter: SoapySDRDevice_setSampleRate(%f) failed: %s\n",(double)tx->iq_output_rate,SoapySDR_errToStr(rc));
+ g_print("%s: SoapySDRDevice_setSampleRate(%f) failed: %s\n",__FUNCTION__,(double)tx->iq_output_rate,SoapySDR_errToStr(rc));
}
size_t channel=tx->dac;
-fprintf(stderr,"soapy_protocol_create_transmitter: SoapySDRDevice_setupStream: channel=%ld\n",channel);
+ g_print("%s: SoapySDRDevice_setupStream: channel=%ld\n",__FUNCTION__,channel);
#if defined(SOAPY_SDR_API_VERSION) && (SOAPY_SDR_API_VERSION < 0x00080000)
rc=SoapySDRDevice_setupStream(soapy_device,&tx_stream,SOAPY_SDR_TX,SOAPY_SDR_CF32,&channel,1,NULL);
if(rc!=0) {
- fprintf(stderr,"soapy_protocol_create_transmitter: SoapySDRDevice_setupStream (RX) failed: %s\n",SoapySDR_errToStr(rc));
+ g_print("%s: SoapySDRDevice_setupStream (RX) failed: %s\n",__FUNCTION__,SoapySDR_errToStr(rc));
_exit(-1);
}
#else
tx_stream=SoapySDRDevice_setupStream(soapy_device,SOAPY_SDR_TX,SOAPY_SDR_CF32,&channel,1,NULL);
if(tx_stream==NULL) {
- fprintf(stderr,"soapy_protocol_create_transmitter: SoapySDRDevice_setupStream (TX) failed: %s\n",SoapySDR_errToStr(rc));
+ g_print("%s: SoapySDRDevice_setupStream (TX) failed: %s\n",__FUNCTION__,SoapySDR_errToStr(rc));
_exit(-1);
}
#endif
if(max_tx_samples>(2*tx->fft_size)) {
max_tx_samples=2*tx->fft_size;
}
-fprintf(stderr,"soapy_protocol_create_transmitter: max_tx_samples=%d\n",max_tx_samples);
+ g_print("%s: max_tx_samples=%d\n",__FUNCTION__,max_tx_samples);
output_buffer=(float *)malloc(max_tx_samples*sizeof(float)*2);
}
}
}
-void soapy_protocol_init(int rx,gboolean hf) {
+void soapy_protocol_init(gboolean hf) {
SoapySDRKwargs args={};
+ char temp[32];
int rc;
int i;
-fprintf(stderr,"soapy_protocol_init: rx=%d hf=%d\n",rx,hf);
+
+ SoapySDR_setLogLevel(SOAPY_SDR_TRACE);
+
+g_print("%s: hf=%d driver=%s\n",__FUNCTION__,hf,radio->name);
// initialize the radio
-fprintf(stderr,"soapy_protocol_init: SoapySDRDevice_make\n");
SoapySDRKwargs_set(&args, "driver", radio->name);
if(strcmp(radio->name,"rtlsdr")==0) {
- char id[16];
- sprintf(id,"%d",radio->info.soapy.rtlsdr_count);
- SoapySDRKwargs_set(&args, "rtl", id);
+ sprintf(temp,"%d",radio->info.soapy.rtlsdr_count);
+ SoapySDRKwargs_set(&args, "rtl", temp);
if(hf) {
SoapySDRKwargs_set(&args, "direct_samp", "2");
} else {
SoapySDRKwargs_set(&args, "direct_samp", "0");
}
+ } else if(strcmp(radio->name,"sdrplay")==0) {
+ sprintf(temp,"SDRplay Dev%d",radio->info.soapy.sdrplay_count);
+ g_print("%s: label=%s\n",__FUNCTION__,temp);
+ SoapySDRKwargs_set(&args, "label", temp);
}
soapy_device=SoapySDRDevice_make(&args);
if(soapy_device==NULL) {
- fprintf(stderr,"soapy_protocol: SoapySDRDevice_make failed: %s\n",SoapySDRDevice_lastError());
+ g_print("%s: SoapySDRDevice_make failed: %s\n",__FUNCTION__,SoapySDRDevice_lastError());
_exit(-1);
}
SoapySDRKwargs_clear(&args);
+ g_print("%s: soapy_device=%p\n",__FUNCTION__,soapy_device);
+
if(can_transmit) {
if(transmitter->local_microphone) {
if(audio_open_input()!=0) {
- fprintf(stderr,"audio_open_input failed\n");
+ g_print("%s: audio_open_input failed\n",__FUNCTION__);
transmitter->local_microphone=0;
}
}
float fsample;
running=TRUE;
fprintf(stderr,"soapy_protocol: receive_thread\n");
+ size_t channel=rx->adc;
while(running) {
- elements=SoapySDRDevice_readStream(soapy_device,rx_stream,buffs,max_samples,&flags,&timeNs,timeoutUs);
+ elements=SoapySDRDevice_readStream(soapy_device,rx_stream[channel],buffs,max_samples,&flags,&timeNs,timeoutUs);
//fprintf(stderr,"soapy_protocol_receive_thread: SoapySDRDevice_readStream failed: max_samples=%d read=%d\n",max_samples,elements);
if(elements<0) {
continue;
}
fprintf(stderr,"soapy_protocol: receive_thread: SoapySDRDevice_deactivateStream\n");
- SoapySDRDevice_deactivateStream(soapy_device,rx_stream,0,0LL);
+ SoapySDRDevice_deactivateStream(soapy_device,rx_stream[channel],0,0LL);
+ /*
fprintf(stderr,"soapy_protocol: receive_thread: SoapySDRDevice_closeStream\n");
- SoapySDRDevice_closeStream(soapy_device,rx_stream);
+ SoapySDRDevice_closeStream(soapy_device,rx_stream[channel]);
fprintf(stderr,"soapy_protocol: receive_thread: SoapySDRDevice_unmake\n");
SoapySDRDevice_unmake(soapy_device);
+ */
return NULL;
}
}
}
-void soapy_protocol_set_gain(RECEIVER *rx,double gain) {
+void soapy_protocol_set_gain(RECEIVER *rx) {
int rc;
//fprintf(stderr,"soapy_protocol_set_gain: adc=%d gain=%f\n",gain);
- rc=SoapySDRDevice_setGain(soapy_device,SOAPY_SDR_RX,rx->adc,gain);
+ rc=SoapySDRDevice_setGain(soapy_device,SOAPY_SDR_RX,rx->adc,adc[rx->adc].gain);
if(rc!=0) {
fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGain failed: %s\n",SoapySDR_errToStr(rc));
}
void soapy_protocol_set_gain_element(RECEIVER *rx,char *name,int gain) {
int rc;
-//fprintf(stderr,"soapy_protocol_set_gain: adc=%d %s=%d\n",rx->adc,name,gain);
+g_print("%s: adc=%d %s=%d\n",__FUNCTION__,rx->adc,name,gain);
rc=SoapySDRDevice_setGainElement(soapy_device,SOAPY_SDR_RX,rx->adc,name,(double)gain);
if(rc!=0) {
- fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGainElement %s failed: %s\n",name,SoapySDR_errToStr(rc));
+ g_print("%s: SoapySDRDevice_setGainElement %s failed: %s\n",__FUNCTION__,name,SoapySDR_errToStr(rc));
}
}
void soapy_protocol_create_receiver(RECEIVER *rx);
void soapy_protocol_start_receiver(RECEIVER *rx);
-void soapy_protocol_init(int rx,gboolean hf);
+void soapy_protocol_init(gboolean hf);
void soapy_protocol_stop();
void soapy_protocol_set_rx_frequency(RECEIVER *rx,int v);
void soapy_protocol_set_rx_antenna(RECEIVER *rx,int ant);
void soapy_protocol_set_lna_gain(RECEIVER *rx,int gain);
-void soapy_protocol_set_gain(RECEIVER *rx,double gain);
+void soapy_protocol_set_gain(RECEIVER *rx);
void soapy_protocol_set_gain_element(RECEIVER *rx,char *name,int gain);
int soapy_protocol_get_gain_element(RECEIVER *rx,char *name);
void soapy_protocol_change_sample_rate(RECEIVER *rx);
*/
#include <gtk/gtk.h>
+#include <glib/gprintf.h>
#include <stdio.h>
#include <string.h>
#include "receiver.h"
#include "vfo.h"
#include "button_text.h"
+#include "toolbar.h"
+#include "actions.h"
#include "gpio.h"
#include "i2c.h"
static GtkWidget *dialog=NULL;
+static SWITCH *temp_switches;
+
static void cleanup() {
if(dialog!=NULL) {
return FALSE;
}
+void switch_page_cb(GtkNotebook *notebook,GtkWidget *page,guint page_num,gpointer user_data) {
+ g_print("%s: page %d\n",__FUNCTION__,page_num);
+ temp_switches=switches_controller1[page_num];
+}
-static void sw_select_cb(GtkWidget *widget, gpointer data) {
+static void switch_select_cb(GtkWidget *widget, gpointer data) {
char text[128];
CHOICE *choice=(CHOICE *)data;
- sw_action[choice->sw]=choice->action;
+g_print("%s: temp_switches=%p\n",__FUNCTION__,temp_switches);
+ temp_switches[choice->sw].switch_function=choice->action;
GtkWidget *label=gtk_bin_get_child(GTK_BIN(choice->button));
sprintf(text,"<span size=\"smaller\">%s</span>",sw_string[choice->action]);
gtk_label_set_markup (GTK_LABEL(label), text);
+ update_toolbar_labels();
}
-static gboolean sw_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
+static gboolean switch_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
int sw=GPOINTER_TO_INT(data);
int i;
choice->sw=sw;
choice->action=i;
choice->button=widget;
- g_signal_connect(menu_item,"activate",G_CALLBACK(sw_select_cb),choice);
+ g_signal_connect(menu_item,"activate",G_CALLBACK(switch_select_cb),choice);
gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
-fprintf(stderr,"%d=%s\n",i,sw_string[i]);
}
gtk_widget_show_all(menu);
#if GTK_CHECK_VERSION(3,22,0)
return TRUE;
}
+static void response_event(GtkWidget *dialog,gint id,gpointer user_data) {
+ g_print("%s: id=%d\n",__FUNCTION__,id);
+ if(id==GTK_RESPONSE_ACCEPT) {
+ g_print("%s: ACCEPT\n",__FUNCTION__);
+ }
+ gtk_widget_destroy(dialog);
+ dialog=NULL;
+ active_menu=NO_MENU;
+ sub_menu=NULL;
+}
+
void switch_menu(GtkWidget *parent) {
- int row=0;
- int col=0;
- char label[64];
- int i;
+ gint row;
+ gint col;
+ gchar label[64];
+ GtkWidget *notebook;
+ GtkWidget *grid;
+ GtkWidget *widget;
+ gint function=0;
+
+g_print("%s: switches_no_controller=%p switches_controller1=%p switches_controller2_v1=%p switches_controller2_v2=%p\n",__FUNCTION__,&switches_no_controller,&switches_controller1,&switches_controller2_v1,&switches_controller2_v2);
- dialog=gtk_dialog_new();
- gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window));
- //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE);
- char title[32];
- sprintf(title,"piHPSDR - Encoder Actions:");
- gtk_window_set_title(GTK_WINDOW(dialog),title);
- g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL);
+ dialog=gtk_dialog_new_with_buttons("piHPSDR - Switch Actions",GTK_WINDOW(parent),GTK_DIALOG_DESTROY_WITH_PARENT,("OK"),GTK_RESPONSE_ACCEPT,NULL);
+ g_signal_connect (dialog, "response", G_CALLBACK (response_event), NULL);
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- GtkWidget *grid=gtk_grid_new();
+ function=0;
+
+ if(controller==NO_CONTROLLER || controller==CONTROLLER1) {
+ notebook=gtk_notebook_new();
+ }
+
+next_function_set:
+ grid=gtk_grid_new();
gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE);
gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE);
gtk_grid_set_column_spacing (GTK_GRID(grid),2);
gtk_grid_set_row_spacing (GTK_GRID(grid),2);
- GtkWidget *close_b=gtk_button_new_with_label("Close");
- GtkWidget *close_label=gtk_bin_get_child(GTK_BIN(close_b));
- sprintf(label,"<span size=\"smaller\">Close</span>");
- gtk_label_set_markup (GTK_LABEL(close_label), label);
- g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),close_b,col,row,1,1);
- row++;
+ row=0;
col=0;
+ gint max_switches=MAX_SWITCHES;
switch(controller) {
- default:
- {
- GtkWidget *sw7_title=gtk_label_new("SW7: ");
- gtk_grid_attach(GTK_GRID(grid),sw7_title,col,row,1,1);
- col++;
-
- GtkWidget *sw7_combo_box=gtk_combo_box_text_new();
- for(i=0;i<SWITCH_ACTIONS;i++) {
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sw7_combo_box),NULL,sw_string[i]);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(sw7_combo_box),sw_action[6]);
- g_signal_connect(sw7_combo_box,"changed",G_CALLBACK(sw_cb),GINT_TO_POINTER(CONTROLLER1_SW7));
- gtk_grid_attach(GTK_GRID(grid),sw7_combo_box,col,row,1,1);
- col++;
-
- GtkWidget *sw1_title=gtk_label_new("SW1: ");
- gtk_grid_attach(GTK_GRID(grid),sw1_title,col,row,1,1);
- col++;
-
- GtkWidget *sw1_combo_box=gtk_combo_box_text_new();
- for(i=0;i<SWITCH_ACTIONS;i++) {
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sw1_combo_box),NULL,sw_string[i]);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(sw1_combo_box),sw_action[0]);
- g_signal_connect(sw1_combo_box,"changed",G_CALLBACK(sw_cb),GINT_TO_POINTER(CONTROLLER1_SW1));
- gtk_grid_attach(GTK_GRID(grid),sw1_combo_box,col,row,1,1);
- row++;
- col=0;
-
- GtkWidget *sw2_title=gtk_label_new("SW2: ");
- gtk_grid_attach(GTK_GRID(grid),sw2_title,col,row,1,1);
- col++;
-
- GtkWidget *sw2_combo_box=gtk_combo_box_text_new();
- for(i=0;i<SWITCH_ACTIONS;i++) {
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sw2_combo_box),NULL,sw_string[i]);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(sw2_combo_box),sw_action[1]);
- g_signal_connect(sw2_combo_box,"changed",G_CALLBACK(sw_cb),GINT_TO_POINTER(CONTROLLER1_SW2));
- gtk_grid_attach(GTK_GRID(grid),sw2_combo_box,col,row,1,1);
- col++;
-
- GtkWidget *sw3_title=gtk_label_new("SW3: ");
- gtk_grid_attach(GTK_GRID(grid),sw3_title,col,row,1,1);
- col++;
-
- GtkWidget *sw3_combo_box=gtk_combo_box_text_new();
- for(i=0;i<SWITCH_ACTIONS;i++) {
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sw3_combo_box),NULL,sw_string[i]);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(sw3_combo_box),sw_action[2]);
- g_signal_connect(sw3_combo_box,"changed",G_CALLBACK(sw_cb),GINT_TO_POINTER(CONTROLLER1_SW3));
- gtk_grid_attach(GTK_GRID(grid),sw3_combo_box,col,row,1,1);
- row++;
- col=0;
-
- GtkWidget *sw4_title=gtk_label_new("SW4: ");
- gtk_grid_attach(GTK_GRID(grid),sw4_title,col,row,1,1);
- col++;
-
- GtkWidget *sw4_combo_box=gtk_combo_box_text_new();
- for(i=0;i<SWITCH_ACTIONS;i++) {
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sw4_combo_box),NULL,sw_string[i]);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(sw4_combo_box),sw_action[3]);
- g_signal_connect(sw4_combo_box,"changed",G_CALLBACK(sw_cb),GINT_TO_POINTER(CONTROLLER1_SW4));
- gtk_grid_attach(GTK_GRID(grid),sw4_combo_box,col,row,1,1);
- col++;
-
- GtkWidget *sw5_title=gtk_label_new("SW5: ");
- gtk_grid_attach(GTK_GRID(grid),sw5_title,col,row,1,1);
- col++;
-
- GtkWidget *sw5_combo_box=gtk_combo_box_text_new();
- for(i=0;i<SWITCH_ACTIONS;i++) {
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sw5_combo_box),NULL,sw_string[i]);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(sw5_combo_box),sw_action[4]);
- g_signal_connect(sw5_combo_box,"changed",G_CALLBACK(sw_cb),GINT_TO_POINTER(CONTROLLER1_SW5));
- gtk_grid_attach(GTK_GRID(grid),sw5_combo_box,col,row,1,1);
- row++;
- col=0;
-
- GtkWidget *sw6_title=gtk_label_new("SW6: ");
- gtk_grid_attach(GTK_GRID(grid),sw6_title,col,row,1,1);
- col++;
-
- GtkWidget *sw6_combo_box=gtk_combo_box_text_new();
- for(i=0;i<SWITCH_ACTIONS;i++) {
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sw6_combo_box),NULL,sw_string[i]);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(sw6_combo_box),sw_action[5]);
- g_signal_connect(sw6_combo_box,"changed",G_CALLBACK(sw_cb),GINT_TO_POINTER(CONTROLLER1_SW6));
- gtk_grid_attach(GTK_GRID(grid),sw6_combo_box,col,row,1,1);
- col++;
-
- GtkWidget *sw8_title=gtk_label_new("SW8: ");
- gtk_grid_attach(GTK_GRID(grid),sw8_title,col,row,1,1);
- col++;
-
- GtkWidget *sw8_combo_box=gtk_combo_box_text_new();
- for(i=0;i<SWITCH_ACTIONS;i++) {
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(sw8_combo_box),NULL,sw_string[i]);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(sw8_combo_box),sw_action[7]);
- g_signal_connect(sw8_combo_box,"changed",G_CALLBACK(sw_cb),GINT_TO_POINTER(CONTROLLER1_SW8));
- gtk_grid_attach(GTK_GRID(grid),sw8_combo_box,col,row,1,1);
- col++;
- }
+ case NO_CONTROLLER:
+ max_switches=8;
+ temp_switches=switches_controller1[function];
+ break;
+ case CONTROLLER1:
+ max_switches=8;
+ temp_switches=switches_controller1[function];
break;
-
case CONTROLLER2_V1:
+ max_switches=16;
+ temp_switches=switches_controller2_v1;
+ break;
case CONTROLLER2_V2:
- {
- col=8;
-
- GtkWidget *sw13=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW13]]);
- GtkWidget *sw13_label=gtk_bin_get_child(GTK_BIN(sw13));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW13]]);
- gtk_label_set_markup (GTK_LABEL(sw13_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw13,col,row,1,1);
- g_signal_connect (sw13, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW13));
- row++;
- col=7;
-
- GtkWidget *sw12=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW12]]);
- GtkWidget *sw12_label=gtk_bin_get_child(GTK_BIN(sw12));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW12]]);
- gtk_label_set_markup (GTK_LABEL(sw12_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw12,col,row,1,1);
- g_signal_connect (sw12, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW12));
- col++;
-
- GtkWidget *sw11=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW11]]);
- GtkWidget *sw11_label=gtk_bin_get_child(GTK_BIN(sw11));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW11]]);
- gtk_label_set_markup (GTK_LABEL(sw11_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw11,col,row,1,1);
- g_signal_connect (sw11, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW11));
- row++;
- col=7;
-
- GtkWidget *sw10=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW10]]);
- GtkWidget *sw10_label=gtk_bin_get_child(GTK_BIN(sw10));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW10]]);
- gtk_label_set_markup (GTK_LABEL(sw10_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw10,col,row,1,1);
- g_signal_connect (sw10, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW10));
- col++;
-
- GtkWidget *sw9=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW9]]);
- GtkWidget *sw9_label=gtk_bin_get_child(GTK_BIN(sw9));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW9]]);
- gtk_label_set_markup (GTK_LABEL(sw9_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw9,col,row,1,1);
- g_signal_connect (sw9, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW9));
- row++;
- col=7;
-
- GtkWidget *sw7=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW7]]);
- GtkWidget *sw7_label=gtk_bin_get_child(GTK_BIN(sw7));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW7]]);
- gtk_label_set_markup (GTK_LABEL(sw7_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw7,col,row,1,1);
- g_signal_connect (sw7, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW7));
- col++;
-
- GtkWidget *sw8=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW8]]);
- GtkWidget *sw8_label=gtk_bin_get_child(GTK_BIN(sw8));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW8]]);
- gtk_label_set_markup (GTK_LABEL(sw8_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw8,col,row,1,1);
- g_signal_connect (sw8, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW8));
- row++;
- col=7;
-
- GtkWidget *sw16=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW16]]);
- GtkWidget *sw16_label=gtk_bin_get_child(GTK_BIN(sw16));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW16]]);
- gtk_label_set_markup (GTK_LABEL(sw16_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw16,col,row,1,1);
- g_signal_connect (sw16, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW16));
- col++;
-
- GtkWidget *sw17=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW17]]);
- GtkWidget *sw17_label=gtk_bin_get_child(GTK_BIN(sw17));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW17]]);
- gtk_label_set_markup (GTK_LABEL(sw17_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw17,col,row,1,1);
- g_signal_connect (sw17, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW17));
- row++;
- col=0;
-
- GtkWidget *sw2=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW2]]);
- GtkWidget *sw2_label=gtk_bin_get_child(GTK_BIN(sw2));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW2]]);
- gtk_label_set_markup (GTK_LABEL(sw2_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw2,col,row,1,1);
- g_signal_connect (sw2, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW2));
- col++;
-
- GtkWidget *sw3=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW3]]);
- GtkWidget *sw3_label=gtk_bin_get_child(GTK_BIN(sw3));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW3]]);
- gtk_label_set_markup (GTK_LABEL(sw3_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw3,col,row,1,1);
- g_signal_connect (sw3, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW3));
- col++;
-
- GtkWidget *sw4=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW4]]);
- GtkWidget *sw4_label=gtk_bin_get_child(GTK_BIN(sw4));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW4]]);
- gtk_label_set_markup (GTK_LABEL(sw4_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw4,col,row,1,1);
- g_signal_connect (sw4, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW4));
- col++;
-
- GtkWidget *sw5=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW5]]);
- GtkWidget *sw5_label=gtk_bin_get_child(GTK_BIN(sw5));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW5]]);
- gtk_label_set_markup (GTK_LABEL(sw5_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw5,col,row,1,1);
- g_signal_connect (sw5, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW5));
- col++;
-
- GtkWidget *sw6=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW6]]);
- GtkWidget *sw6_label=gtk_bin_get_child(GTK_BIN(sw6));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW6]]);
- gtk_label_set_markup (GTK_LABEL(sw6_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw6,col,row,1,1);
- g_signal_connect (sw6, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW6));
- col++;
-
- GtkWidget *sw14=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW14]]);
- GtkWidget *sw14_label=gtk_bin_get_child(GTK_BIN(sw14));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW14]]);
- gtk_label_set_markup (GTK_LABEL(sw14_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw14,col,row,1,1);
- g_signal_connect (sw14, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW14));
- col++;
-
- GtkWidget *sw15=gtk_button_new_with_label(sw_string[sw_action[CONTROLLER2_SW15]]);
- GtkWidget *sw15_label=gtk_bin_get_child(GTK_BIN(sw15));
- sprintf(label,"<span size=\"smaller\">%s</span>",sw_string[sw_action[CONTROLLER2_SW15]]);
- gtk_label_set_markup (GTK_LABEL(sw15_label), label);
- gtk_grid_attach(GTK_GRID(grid),sw15,col,row,1,1);
- g_signal_connect (sw15, "button_press_event", G_CALLBACK(sw_cb), GINT_TO_POINTER(CONTROLLER2_SW15));
- col++;
- }
+ max_switches=16;
+ temp_switches=switches_controller2_v2;
break;
}
- gtk_container_add(GTK_CONTAINER(content),grid);
+ g_print("%s: temp_switches=%p\n",__FUNCTION__,temp_switches);
+
+ int original_row=row;
+
+ if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
+ row=row+5;
+ col=0;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[0].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(0));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[1].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(1));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[2].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(2));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[3].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(3));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[4].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(4));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[5].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(5));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[6].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(6));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+
+ row=original_row;
+ col=8;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[7].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(7));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ row++;
+ col=7;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[8].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(8));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[9].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(9));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ row++;
+ col=7;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[10].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(10));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[11].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(11));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ row++;
+ col=7;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[12].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(12));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[13].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(13));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ row++;
+ col=7;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[14].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(14));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ widget=gtk_button_new_with_label(sw_string[temp_switches[15].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(15));
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+
+ gtk_container_add(GTK_CONTAINER(content),grid);
+ } else {
+ int start_row=row;
+ for(int i=0;i<max_switches;i++) {
+ if((controller==NO_CONTROLLER || controller==CONTROLLER1) && (temp_switches[i].switch_function==FUNCTION)) {
+ widget=gtk_label_new(NULL);
+ g_sprintf(label,"<b>%s</b>",sw_string[temp_switches[i].switch_function]);
+ gtk_label_set_markup (GTK_LABEL(widget), label);
+ } else {
+ widget=gtk_button_new_with_label(sw_string[temp_switches[i].switch_function]);
+ g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(i));
+ }
+ gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+ col++;
+ }
+
+ g_sprintf(label,"Function %d",function);
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid,gtk_label_new(label));
+ function++;
+ if(function<MAX_FUNCTIONS) {
+ goto next_function_set;
+ }
+ gtk_container_add(GTK_CONTAINER(content),notebook);
+ g_signal_connect (notebook, "switch-page",G_CALLBACK(switch_page_cb),NULL);
+ }
sub_menu=dialog;
static gint xit_plus_timer=-1;
static gint xit_minus_timer=-1;
+SWITCH *toolbar_switches=switches_controller1[0];
+
static gboolean rit_timer_cb(gpointer data) {
int i=GPOINTER_TO_INT(data);
vfo_rit(active_receiver->id,i);
#ifndef _TOOLBAR_H
#define _TOOLBAR_H
+#include "gpio.h"
#define MAX_FUNCTION 5
extern int function;
+extern SWITCH *toolbar_switches;
void update_toolbar_labels();
void ptt_update(int state);
// reflected power, so correct for that
//
double gamma=(double) rev_average / (double) fwd_average;
+ //
+ // this prevents SWR going to infinity, from which the
+ // moving average cannot recover
+ //
+ if (gamma > 0.95) gamma=0.95;
tx->swr=0.7*(1+gamma)/(1-gamma) + 0.3*tx->swr;
} else {
//
GtkWidget *label=gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(label), "<b>TX Filter: </b>");
-#ifdef GTK316
- gtk_label_set_xalign(GTK_LABEL(label),0);
-#endif
+ gtk_widget_set_halign(label, GTK_ALIGN_START);
gtk_grid_attach(GTK_GRID(grid),label,col,row,1,1);
col++;
GtkWidget *panadapter_high_label=gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(panadapter_high_label), "<b>Panadapter High: </b>");
-#ifdef GTK316
- gtk_label_set_xalign(GTK_LABEL(panadapter_high_label),0);
-#endif
+ gtk_widget_set_halign(panadapter_high_label, GTK_ALIGN_START);
gtk_widget_show(panadapter_high_label);
gtk_grid_attach(GTK_GRID(grid),panadapter_high_label,col,row,1,1);
GtkWidget *panadapter_low_label=gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(panadapter_low_label), "<b>Panadapter Low: </b>");
-#ifdef GTK316
- gtk_label_set_xalign(GTK_LABEL(panadapter_low_label),0);
-#endif
+ gtk_widget_set_halign(panadapter_low_label, GTK_ALIGN_START);
gtk_widget_show(panadapter_low_label);
gtk_grid_attach(GTK_GRID(grid),panadapter_low_label,col,row,1,1);
GtkWidget *panadapter_step_label=gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(panadapter_step_label), "<b>Panadapter Step: </b>");
-#ifdef GTK316
- gtk_label_set_xalign(GTK_LABEL(panadapter_step_label),0);
-#endif
+ gtk_widget_set_halign(panadapter_step_label, GTK_ALIGN_START);
gtk_widget_show(panadapter_step_label);
gtk_grid_attach(GTK_GRID(grid),panadapter_step_label,col,row,1,1);
GtkWidget *am_carrier_level_label=gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(am_carrier_level_label), "<b>AM Carrier Level:</b>");
-#ifdef GTK316
- gtk_label_set_xalign(GTK_LABEL(am_carrier_level_label),0);
-#endif
+ gtk_widget_set_halign(am_carrier_level_label, GTK_ALIGN_START);
gtk_widget_show(am_carrier_level_label);
gtk_grid_attach(GTK_GRID(grid),am_carrier_level_label,col,row,1,1);
GtkWidget *tune_percent_label=gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(tune_percent_label), "<b>Tune Percent:</b>");
-#ifdef GTK316
- gtk_label_set_xalign(GTK_LABEL(tune_percent_label),0);
-#endif
+ gtk_widget_set_halign(tune_percent_label, GTK_ALIGN_START);
gtk_widget_show(tune_percent_label);
gtk_grid_attach(GTK_GRID(grid),tune_percent_label,col,row,1,1);
GtkWidget *swr_alarm_label=gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(swr_alarm_label), "<b>SWR alarm at:</b>");
-#ifdef GTK316
- gtk_label_set_xalign(GTK_LABEL(swr_alarm_label),0);
-#endif
+ gtk_widget_set_halign(swr_alarm_label, GTK_ALIGN_START);
gtk_widget_show(swr_alarm_label);
gtk_grid_attach(GTK_GRID(grid),swr_alarm_label,col,row,1,1);
#include "tx_panadapter.h"
#include "vfo.h"
#include "mode.h"
+#include "actions.h"
#ifdef GPIO
#include "gpio.h"
#endif
cairo_set_line_width(cr, 1.0);
cairo_stroke(cr);
+/*
#ifdef GPIO
if(controller==CONTROLLER1 && tx->dialog == NULL) {
char text[64];
}
}
#endif
-
+*/
#ifdef PURESIGNAL
if(tx->puresignal) {
cairo_set_font_size(cr, DISPLAY_FONT_SIZE3);
if(transmitter->fwd<0.0001) {
- sprintf(text,"FWD %0.3f W",transmitter->exciter);
+ sprintf(text,"FWD %0.3f",transmitter->exciter);
} else {
static int max_count=0;
static double max_level=0.0;
}
cairo_move_to(cr,10,15);
cairo_show_text(cr, text);
-
//
// Since colour is already red, no special
// action for "high SWR" warning
cairo_move_to(cr,10,30);
cairo_show_text(cr, text);
- sprintf(text,"ALC %2.1f dB",transmitter->alc);
+ sprintf(text,"ALC %2.1f",transmitter->alc);
cairo_move_to(cr,10,45);
cairo_show_text(cr, text);
cairo_show_text(cr, text);
*/
}
-
//
// If the SWR protection has been triggered, display message for three seconds
//
cairo_move_to(cr, 160.0, 30.0);
cairo_show_text(cr, text);
+
if (tx_fifo_overrun || tx_fifo_underrun) {
cairo_set_source_rgb(cr,1.0,0.0,0.0);
if (tx_fifo_underrun) {
long long af = vfo[0].ctun ? vfo[0].ctun_frequency : vfo[0].frequency;
long long bf = vfo[1].ctun ? vfo[1].ctun_frequency : vfo[1].frequency;
+ if(vfo[0].entering_frequency) {
+ af=vfo[0].entered_frequency;
+ }
+ if(vfo[1].entering_frequency) {
+ bf=vfo[1].entered_frequency;
+ }
+
#if 0
//
// DL1YCF: code still here but deactivated:
if (oob) sprintf(temp_text,"VFO A: Out of band");
cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
} else {
- if(id==0) {
+ if(vfo[0].entering_frequency) {
+ cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
+ } else if(id==0) {
cairo_set_source_rgb(cr, 0.0, 1.0, 0.0);
} else {
cairo_set_source_rgb(cr, 0.0, 0.65, 0.0);
if (oob) sprintf(temp_text,"VFO B: Out of band");
cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
} else {
- if(id==1) {
+ if(vfo[1].entering_frequency) {
+ cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
+ } else if(id==1) {
cairo_set_source_rgb(cr, 0.0, 1.0, 0.0);
} else {
cairo_set_source_rgb(cr, 0.0, 0.65, 0.0);
long long lo;
long long offset;
+ gboolean entering_frequency;
+ long long entered_frequency;
};
extern struct _vfo vfo[MAX_VFOS];
long long frequency;
} SET_FREQUENCY;
+#define STEPS 15
extern int steps[];
extern char *step_labels[];