diff --git a/Makefile.Windows b/Makefile.Windows deleted file mode 100755 index a15e378a2..000000000 --- a/Makefile.Windows +++ /dev/null @@ -1,1993 +0,0 @@ -# -# GNU Makefile for Hamlib (MSVC / clang-cl / MinGW). -# -# G. Vanem 2019 - 2021. -# -THIS_FILE = Makefile.Windows -DATE = $(shell date +%d-%B-%Y) -ABI_VER = 4 - -# -# From 'configure.ac': -# -MAJOR_VER = 4 -MINOR_VER = 2 -VERSION = $(MAJOR_VER).$(MINOR_VER) - -# -# Choose your weapons. Do a 'make vclean' after changing any of these. -# -USE_LIBGD ?= 1 -USE_LIBINDI ?= 0 -USE_LIBREADLINE ?= 0 -USE_LIBUSB ?= 1 -USE_LIBUSRP ?= 1 -USE_LIBXML2 ?= 1 -USE_LUAJIT ?= 0 -USE_MP_COMPILE ?= 1 - -# -# Add support for a 'GnuRadio' device. -# Impossible as it is not up-to-date with current GnuRadio 3.9 API. -# -USE_GNURADIO ?= 0 - -# -# Use the Winsock tracing library (works badly for MinGW): -# https://github.com/gvanem/wsock-trace -# -USE_WSOCK_TRACE ?= 1 - -# -# Use only static external libraries to create '$(Hamlib_DLL)'. -# But '_Hamlib.pyd' and 'HamlibLua.dll' always uses '$(Hamlib_DLL)'. -# -USE_STATIC ?= 1 - -# -# Use '$(Hamlib_DLL)' for all C programs. -# And '$(Hamlib++_DLL)' for all C++ programs. -# -USE_DLLs_FOR_PROGRAMS ?= 1 - -# -# Set to 0 for no Python module. -# Set to 2 to create a Python 2.x module. -# Set to 3 to create a Python 3.x module. -# -USE_PY_BINDING ?= 3 - -# -# Use 'astyle' or 'clang-format' in the "%.i: %.c" preprocess rules below. -# -USE_ASTYLE ?= 0 -USE_CLANG_FORMAT ?= 0 - -# -# Change these as needed: -# (or create env-vars like 'LIBXML2_ROOT=c:/whatever/xml2'). -# -LIBXML2_ROOT ?= f:/MinGW32/src/Parsers/libxml2 -LIBICONV_ROOT ?= f:/MinGW32/src/libiconv-1.15 -LIBGD_ROOT ?= f:/MinGW32/src/Graphics/libgd-2.1.0 -LIBREADLINE_ROOT ?= f:/MinGW32/src/misc/libreadline -LUAJIT_ROOT ?= f:/MinGW32/src/LUA/LuaJIT -LUA5_ROOT ?= f:/MinGW32/src/LUA/Lua-5.4 -LIBUSB_ROOT ?= f:/MinGW32/src/USB/libusb -LIBUSRP_ROOT ?= f:/gv/dx-radio/Bor-IP/src/libusrp/usrp/host -GNURADIO_ROOT ?= f:/gv/dx-radio/GnuRadio/gv-build -LIBINDI_ROOT ?= f:/ProgramFiler/Stellarium/src/src/external/libindi - -PYTHON ?= py -3 - -ifeq ($(USE_LUAJIT),1) - LUA_ROOT = $(realpath $(LUAJIT_ROOT)) - LUA_LIB = $(call select, $(LUA_ROOT)/src/libluajit.a, $(LUA_ROOT)/src/luajit.lib) -else - LUA_ROOT = $(realpath $(LUA5_ROOT)) - LUA_LIB = $(call select, $(LUA_ROOT)/src/liblua.a, $(LUA_ROOT)/src/lua.lib) -endif - -MKDIR = mkdir -RMDIR = rmdir --parents -MOVE = mv --force -COPY = cp --preserve=timestamps --update - -# -# 'clang-cl' may not like stuff in '%CL'. -# Just remove it. -# -export CL= - -define Usage - - Usage: "$(MAKE) -f $(THIS_FILE) CC=[cl | clang-cl | gcc] [CPU=x86 | x64] [all | clean | vclean | realclean | depend | doxy_docs | py_module | lua_module]" - Specify CC=cl - use MSVC - Specify CC=clang-cl - use clang-cl - Specify CC=gcc - use MinGW -endef - -# -# Check the casing of '$CPU'. GNU-make is case-sensitive. -# -ifeq ($(CPU),) - CPU = x86 -endif - -ifeq ($(CPU),X86) - CPU = x86 -else ifeq ($(CPU),X64) - CPU = x64 -endif - -# -# If '$(CPU)=x64', build 64-bit version. Assuming your MinGW -# is dual-target capable and supports the '-mxx' option. -# Otherwise 32-bit programs. -# -ifeq ($(CPU),x64) - BITS = 64 - RCFLAGS = --target=pe-x86-64 - X_SUFFIX = _x64 -else - BITS = 32 - RCFLAGS = --target=pe-i386 - X_SUFFIX = -endif - -ifeq ($(CC),gcc) - OBJ_DIR = MinGW_obj - USE_MP_COMPILE := 0 - -else ifeq ($(CC),clang-cl) - OBJ_DIR = clang_obj - USE_MP_COMPILE := 0 - -else ifeq ($(CC),cl) - OBJ_DIR = MSVC_obj - -else - $(error $(Usage)) -endif - -ifeq ($(CC),gcc) - select = $(1) - CFLAGS = -m$(BITS) -O2 -g --include config.h - LDFLAGS = -m$(BITS) -Wl,--print-map,--sort-common - O = o - A = a - - # - # We want true Winsock2. Not some POSIX emulation that messes up things big-time. - # - CFLAGS += -D__USE_W32_SOCKETS - - WS2_32_LIB = -lws2_32 - -else - select = $(2) - CFLAGS = -nologo -MD -W3 -Zi -O2 -EHsc -DWIN32 -FI./config.h - LDFLAGS = -nologo -debug -incremental:no -verbose -machine:$(CPU) -nodefaultlib:uuid.lib - O = obj - A = lib - - ifeq ($(CC),clang-cl) - CFLAGS += -fms-compatibility -ferror-limit=5 - endif - - ifeq ($(USE_WSOCK_TRACE),1) - WS2_32_LIB = wsock_trace.lib - else - WS2_32_LIB = ws2_32.lib - endif -endif - -# -# Warning control: -# -ifeq ($(CC),gcc) - CFLAGS += -Wall \ - -Wno-format \ - -Wno-array-bounds \ - -Wno-missing-braces \ - -Wno-unused-function \ - -Wno-unused-variable \ - -Wno-shift-count-overflow - -else ifeq ($(CC),clang-cl) - CFLAGS += -Wall \ - -Wno-undef \ - -Wno-unused-function \ - -Wno-unused-macros \ - -Wno-unused-parameter \ - -Wno-unused-variable \ - -Wno-visibility \ - -Wno-unknown-pragmas \ - -Wno-ignored-attributes \ - -Wno-strict-prototypes \ - -Wno-reserved-id-macro \ - -Wno-shadow \ - -Wno-cast-align \ - -Wno-cast-qual \ - -Wno-shorten-64-to-32 \ - -Wno-pedantic \ - -Wno-format-pedantic \ - -Wno-format-nonliteral \ - -Wno-switch-enum \ - -Wno-covered-switch-default \ - -Wno-sign-conversion \ - -Wno-sign-compare \ - -Wno-double-promotion \ - -Wno-assign-enum \ - -Wno-unreachable-code \ - -Wno-unreachable-code-return \ - -Wno-unreachable-code-break \ - -Wno-c++98-compat-pedantic \ - -Wno-old-style-cast \ - -Wno-extra-semi-stmt \ - -Wno-missing-field-initializers \ - -Wno-missing-noreturn \ - -Wno-missing-prototypes \ - -Wno-missing-variable-declarations \ - -Wno-bad-function-cast \ - -Wno-redundant-parens \ - -Wno-tautological-unsigned-zero-compare \ - -Wno-nonportable-system-include-path \ - -Wno-implicit-int-conversion \ - -Wno-float-conversion \ - -Wno-float-equal \ - -Wno-implicit-float-conversion \ - -Wno-implicit-fallthrough \ - -Wno-shift-count-overflow \ - -Wno-documentation \ - -Wno-documentation-unknown-command \ - -Wno-gnu-zero-variadic-macro-arguments \ - -Wno-zero-as-null-pointer-constant - - ifeq ($(USE_LIBUSRP),1) - CFLAGS += -Wno-suggest-override \ - -Wno-suggest-destructor-override - endif - - # - # When on AppVeyor, do not suppress these warnings since they have an old 'clang-cl'. - # - ifeq ($(APPVEYOR_PROJECT_NAME)x,x) - CFLAGS += -Wno-implicit-int-float-conversion \ - -Wno-deprecated-copy-dtor - endif - - # - # This warning is kinda important: - # - # rigs/dummy/dummy.h(46,5): warning: 'netrigctl_get_vfo_mode' redeclared without 'dllimport' attribute: previous - # 'dllimport' ignored [-Winconsistent-dllimport] - # int netrigctl_get_vfo_mode(RIG *); - # ^ - # So do not add a '-Wno-inconsistent-dllimport'. - # - # And so is this '-Wconditional-uninitialized'. - # -else - CFLAGS += -wd4018 -wd4101 -wd4142 -wd4146 -wd4244 -wd4251 -wd4305 -wd4700 -wd4800 - - ifeq ($(BITS),64) - CFLAGS += -wd4267 - endif -endif - -# CFLAGS += -DHASH_BLOOM - -# -# External libraries for '$(Hamlib_DLL)': -# -EX_LIBS = $(WS2_32_LIB) - -# -# The DLL and library names: -# -Hamlib_DLL = Hamlib-$(ABI_VER).dll -Hamlib_IMP_LIB = $(call select, libHamlib-$(ABI_VER).dll.a, Hamlib-$(ABI_VER)_imp.lib) -Hamlib_STAT_LIB = $(call select, libHamlib-$(ABI_VER).a, Hamlib-$(ABI_VER).lib) - -# -# The C++ library -# -Hamlib++_DLL = Hamlib-$(ABI_VER)++.dll -Hamlib++_IMP_LIB = $(call select, libHamlib-$(ABI_VER)++.dll.a, Hamlib-$(ABI_VER)++_imp.lib) - -# -# The internal utility library; '$(hamlib_misc_SRC)'. -# -misc_LIB = $(call select, libmisc.a, misc.lib) - -# -# What to build: -# -TARGETS = $(Hamlib_STAT_LIB) $(Hamlib_DLL) \ - $(Hamlib_IMP_LIB) $(misc_LIB) - -# -# The C++ interface is dynamic only. -# -TARGETS += $(Hamlib++_DLL) $(Hamlib++_IMP_LIB) - -# -# For 'test/*.c' only. They all use '$(Hamlib_DLL)'. -# -PROG_LIBS = $(WS2_32_LIB) $(call select, -lwinpthread) - -ifeq ($(USE_DLLs_FOR_PROGRAMS),1) - # - # A strangely named macro ('-DUSE_Hamlib_DLL' would be better), but - # this will let all .c and .cc programs to use 'Hamlib-$(ABI_VER).dll' - # - PROG_CFLAGS = -DDLL_EXPORT - - # - # Use 'Hamlib-$(ABI_VER).dll' for C programs. - # - C_PROG_LIBS = $(misc_LIB) $(Hamlib_IMP_LIB) - - # - # Use 'Hamlib-$(ABI_VER)++.dll and 'Hamlib-$(ABI_VER).dll' for C++ programs. - # The library order matter for MinGW only. - # - CPP_PROG_LIBS = $(Hamlib_IMP_LIB) $(Hamlib++_IMP_LIB) -else - PROG_CFLAGS = - PROG_LIBS = $(EX_LIBS) - C_PROG_LIBS = $(Hamlib_STAT_LIB) $(misc_LIB) - CPP_PROG_LIBS = $(Hamlib_STAT_LIB) $(misc_LIB) $(Hamlib++_IMP_LIB) -endif - -# -# For 'rigs/kit/usrp.c' and 'rigs/kit/usrp_impl.cc'. -# This needs Boost too. Untested by me. -# -ifeq ($(USE_LIBUSRP),1) - CFLAGS += -DHAVE_USRP \ - -I$(LIBUSRP_ROOT)/include \ - -I$(LIBUSRP_ROOT)/include/usrp - - EX_LIBS += $(call select, $(LIBUSRP_ROOT)/libUSRP.a, \ - $(LIBUSRP_ROOT)/libUSRP_imp.lib) - - hamlib_CC_SRC = kit/usrp_impl.cc -endif - -ifeq ($(USE_LIBUSB),1) - CFLAGS += -DHAVE_LIBUSB \ - -DHAVE_LIBUSB_H \ - -I$(LIBUSB_ROOT)/libusb - - ifeq ($(USE_STATIC),1) - EX_LIBS += $(call select, $(LIBUSB_ROOT)/libusb-1.0.a -ladvapi32, \ - $(LIBUSB_ROOT)/libusb-1.0.lib advapi32.lib) - else - EX_LIBS += $(call select, $(LIBUSB_ROOT)/libusb-1.0.dll.a, \ - $(LIBUSB_ROOT)/libusb-1.0_imp.lib) - endif -endif - -# -# Untested; does it exist except for MinGW? -# -ifeq ($(USE_LIBREADLINE),1) - CFLAGS += -DHAVE_LIBREADLINE \ - -I$(LIBREADLINE_ROOT)/include - - EX_LIBS += $(call select, $(LIBREADLINE_ROOT)/libreadline.a, \ - $(LIBREADLINE_ROOT)/libreadline.lib) -endif - -CFLAGS += -I. \ - -I./include \ - -I./include/hamlib \ - -I./lib \ - -I./src \ - -I./tests - -ifneq ($(CC),gcc) - CFLAGS += -I$(OBJ_DIR) - EX_LIBS += user32.lib kernel32.lib -endif - -c_to_obj = $(addprefix $(OBJ_DIR)/, \ - $(notdir $(1:.c=.$(O)))) - -cc_to_obj = $(addprefix $(OBJ_DIR)/, \ - $(notdir $(1:.cc=.$(O)))) - -cpp_to_obj = $(addprefix $(OBJ_DIR)/, \ - $(notdir $(1:.cpp=.$(O)))) - -c_to_i = $(notdir $(1:.c=.i)) -cc_to_i = $(notdir $(1:.cc=.i)) - -VPATH = rigs/dummy src tests c++ amplifiers/elecraft - -VPATH += $(addprefix rigs/, \ - adat \ - alinco \ - aor \ - barrett \ - dorji \ - drake \ - elad \ - flexradio \ - icmarine \ - icom \ - jrc \ - kachina \ - kenwood \ - kit \ - lowe \ - pcr \ - prm80 \ - racal \ - rft \ - rs \ - skanti \ - tapr \ - tentec \ - tuner \ - uniden \ - winradio \ - wj \ - yaesu) - -VPATH += $(addprefix rotators/, \ - amsat \ - ars \ - celestron \ - cnctrk \ - easycomm \ - ether6 \ - fodtrack \ - gs232a \ - heathkit \ - indi \ - ioptron \ - m2 \ - meade \ - prosistel \ - rotorez \ - sartek \ - satel \ - spid \ - ts7400) - -# -# For compiling 'HamlibPy2_wrap.c,' 'HamlibPy3_wrap.c' and 'HamlibLua_wrap.c'. -# -VPATH += $(OBJ_DIR) - -# -# All of these use '$(Hamlib_DLL)': -# -TESTS_PROGS = ampctl.exe \ - ampctld.exe \ - dumpmem.exe \ - example.exe \ - listrigs.exe \ - rigctl.exe \ - rigctld.exe \ - rigctlcom.exe \ - rigsmtr.exe \ - rigswr.exe \ - rig_bench.exe \ - rotctl.exe \ - rotctld.exe \ - simyaesu.exe \ - testbcd.exe \ - testfreq.exe \ - testloc.exe \ - testrig.exe \ - testrigcaps.exe \ - testrigopen.exe \ - testtrn.exe - -ifneq ($(APPVEYOR_PROJECT_NAME),) - # - # TODO: build with 'LIBUSB_ROOT = ./CI/libusb', 'LIBXML2_ROOT = ./CI/libxml2' etc. - # when running via 'appveyor.yml' - # -endif - -ifeq ($(USE_LIBXML2),1) - TESTS_PROGS += rigmem.exe - PROG_CFLAGS += -I$(LIBXML2_ROOT)/include \ - -I$(LIBICONV_ROOT)/include \ - -DHAVE_XML2 - - # - # Use the dynamic version of 'libxml2'. - # I.e. do not set 'PROG_CFLAGS += -DLIBXML_STATIC'. - # Otherwise we could need to link to a static 'Iconv', 'Zlib' and - # a 'liblzma' too (depending on how 'libxml2' was built). - # - XML2_LIB = $(call select, $(LIBXML2_ROOT)/libxml2.dll.a, \ - $(LIBXML2_ROOT)/xml2_imp.lib) -endif - -ifeq ($(USE_LIBGD),1) - TESTS_PROGS += rigmatrix.exe - PROG_CFLAGS += -I$(LIBGD_ROOT)/src -endif - -# -# This always uses '$(Hamlib++_DLL)'. -# -TESTS_PROGS += testcpp.exe - -# -# All .c-files for '$(Hamlib_DLL)'. -# Except for those in '$(hamlib_misc_SRC)' which do not need to be exported. -# -hamlib_C_SRC = $(addprefix src/, \ - amp_conf.c \ - amp_reg.c \ - amp_settings.c \ - amplifier.c \ - cal.c \ - cm108.c \ - conf.c \ - debug.c \ - event.c \ - ext.c \ - extamp.c \ - gpio.c \ - locator.c \ - iofunc.c \ - mem.c \ - misc.c \ - microham.c \ - network.c \ - parallel.c \ - register.c \ - rig.c \ - rot_conf.c \ - rot_ext.c \ - rot_reg.c \ - rot_settings.c \ - rotator.c \ - serial.c \ - settings.c \ - sleep.c \ - tones.c \ - usb_port.c) - -hamlib_C_SRC += $(addprefix rigs/dummy/, \ - amp_dummy.c \ - dummy.c \ - dummy_common.c \ - flrig.c \ - netampctl.c \ - netrigctl.c \ - netrotctl.c \ - rot_dummy.c \ - trxmanager.c) - -hamlib_C_SRC += $(addprefix rigs/adat/, \ - adat.c \ - adt_200a.c) - -hamlib_C_SRC += $(addprefix rigs/alinco/, \ - alinco.c \ - dx77.c \ - dxsr8.c) - -hamlib_C_SRC += $(addprefix rigs/aor/, \ - aor.c \ - ar2700.c \ - ar3000.c \ - ar3030.c \ - ar5000.c \ - ar7030.c \ - ar7030p.c \ - ar7030p_utils.c \ - ar8000.c \ - ar8200.c \ - ar8600.c \ - sr2200.c) - -hamlib_C_SRC += $(addprefix rigs/barrett/, \ - 950.c \ - barrett.c) - -hamlib_C_SRC += $(addprefix rigs/dorji/, \ - dorji.c \ - dra818.c) - -hamlib_C_SRC += $(addprefix rigs/drake/, \ - drake.c \ - r8a.c \ - r8b.c) - -hamlib_C_SRC += $(addprefix rigs/elad/, \ - elad.c \ - fdm_duo.c) - -hamlib_C_SRC += $(addprefix rigs/flexradio/, \ - dttsp.c \ - flexradio.c \ - sdr1k.c) - -hamlib_C_SRC += $(addprefix rigs/icmarine/, \ - icm700pro.c \ - icm710.c \ - icm802.c \ - icm803.c \ - icmarine.c) - -hamlib_C_SRC += $(addprefix rigs/icom/, \ - delta2.c \ - frame.c \ - ic78.c \ - ic92d.c \ - ic271.c \ - ic275.c \ - ic471.c \ - ic475.c \ - ic703.c \ - ic706.c \ - ic707.c \ - ic718.c \ - ic725.c \ - ic726.c \ - ic728.c \ - ic735.c \ - ic736.c \ - ic737.c \ - ic738.c \ - ic746.c \ - ic751.c \ - ic756.c \ - ic761.c \ - ic765.c \ - ic775.c \ - ic781.c \ - ic785x.c \ - ic820h.c \ - ic821h.c \ - ic910.c \ - ic970.c \ - ic1275.c \ - ic2730.c \ - ic7000.c \ - ic7100.c \ - ic7200.c \ - ic7300.c \ - ic7410.c \ - ic7600.c \ - ic7610.c \ - ic7700.c \ - ic7800.c \ - ic9100.c \ - icom.c \ - icr6.c \ - icr10.c \ - icr20.c \ - icr30.c \ - icr71.c \ - icr72.c \ - icr75.c \ - icr7000.c \ - icr8500.c \ - icr8600.c \ - icr9000.c \ - icr9500.c \ - icrx7.c \ - id1.c \ - id31.c \ - id4100.c \ - id51.c \ - id5100.c \ - omni.c \ - optoscan.c \ - os456.c \ - os535.c \ - perseus.c \ - x108g.c) - -hamlib_C_SRC += $(addprefix rigs/jrc/, \ - jrc.c \ - nrd525.c \ - nrd535.c \ - nrd545.c) - -hamlib_C_SRC += $(addprefix rigs/kachina/, \ - 505dsp.c \ - kachina.c) - -hamlib_C_SRC += $(addprefix rigs/kenwood/, \ - elecraft.c \ - flex.c \ - flex6xxx.c \ - ic10.c \ - k2.c \ - k3.c \ - kenwood.c \ - pihpsdr.c \ - r5000.c \ - th.c \ - thd7.c \ - thd72.c \ - thd74.c \ - thf6a.c \ - thf7.c \ - thg71.c \ - tmd700.c \ - tmd710.c \ - tmv7.c \ - transfox.c \ - trc80.c \ - ts50s.c \ - ts140.c \ - ts440.c \ - ts450s.c \ - ts480.c \ - ts570.c \ - ts590.c \ - ts680.c \ - ts690.c \ - ts711.c \ - ts790.c \ - ts811.c \ - ts850.c \ - ts870s.c \ - ts930.c \ - ts940.c \ - ts950.c \ - ts990s.c \ - ts2000.c \ - xg3.c) - -hamlib_C_SRC += $(addprefix rigs/kit/, \ - dds60.c \ - drt1.c \ - dwt.c \ - elektor304.c \ - elektor507.c \ - fifisdr.c \ - funcube.c \ - hiqsdr.c \ - kit.c \ - miniVNA.c \ - pcrotor.c \ - rs_hfiq.c \ - si570avrusb.c \ - usrp.c) - -hamlib_C_SRC += $(addprefix rigs/lowe/, \ - hf235.c \ - lowe.c) - -hamlib_C_SRC += $(addprefix rigs/pcr/, \ - pcr.c \ - pcr100.c \ - pcr1000.c \ - pcr1500.c \ - pcr2500.c) - -hamlib_C_SRC += $(addprefix rigs/prm80/, \ - prm80.c \ - prm8060.c) - -hamlib_C_SRC += $(addprefix rigs/racal/, \ - ra37xx.c \ - ra3702.c \ - ra6790.c \ - racal.c) - -hamlib_C_SRC += $(addprefix rigs/rft/, \ - ekd500.c \ - rft.c) - -hamlib_C_SRC += $(addprefix rigs/rs/, \ - eb200.c \ - esmc.c \ - gp2000.c \ - rs.c \ - xk2100.c) - -hamlib_C_SRC += $(addprefix rigs/skanti/, \ - skanti.c \ - trp8000.c \ - trp8255.c) - -hamlib_C_SRC += $(addprefix rigs/tapr/, \ - dsp10.c \ - tapr.c) - -hamlib_C_SRC += $(addprefix rigs/tentec/, \ - argonaut.c \ - jupiter.c \ - omnivii.c \ - orion.c \ - paragon.c \ - pegasus.c \ - rx320.c \ - rx331.c \ - rx340.c \ - rx350.c \ - tentec.c \ - tentec2.c \ - tt550.c) - -hamlib_C_SRC += $(addprefix rigs/tuner/, \ - tuner.c \ - v4l.c \ - v4l2.c) - -hamlib_C_SRC += $(addprefix rigs/uniden/, \ - bc245.c \ - bc250.c \ - bc780.c \ - bc895.c \ - bc898.c \ - bcd396t.c \ - bcd996t.c \ - pro2052.c \ - uniden.c \ - uniden_digital.c) - -hamlib_C_SRC += $(addprefix rigs/winradio/, \ - g303.c \ - g305.c \ - g313-win.c \ - winradio.c \ - wr1000.c \ - wr1500.c \ - wr1550.c \ - wr3100.c \ - wr3150.c \ - wr3500.c \ - wr3700.c) - -hamlib_C_SRC += $(addprefix rigs/wj/, \ - wj.c \ - wj8888.c) - -hamlib_C_SRC += $(addprefix rigs/yaesu/, \ - frg100.c \ - frg8800.c \ - frg9600.c \ - ft100.c \ - ft450.c \ - ft600.c \ - ft736.c \ - ft747.c \ - ft757gx.c \ - ft767gx.c \ - ft817.c \ - ft840.c \ - ft847.c \ - ft857.c \ - ft890.c \ - ft891.c \ - ft897.c \ - ft900.c \ - ft920.c \ - ft950.c \ - ft980.c \ - ft990.c \ - ft991.c \ - ft1000d.c \ - ft1000mp.c \ - ft1200.c \ - ft2000.c \ - ft3000.c \ - ft5000.c \ - ft9000.c \ - ftdx10.c \ - ftdx101.c \ - ftdx101mp.c \ - newcat.c \ - vr5000.c \ - vx1700.c \ - yaesu.c) - -# -# Code for Antenna Rotators: -# -hamlib_C_SRC += $(addprefix rotators/, \ - amsat/if100.c \ - ars/ars.c \ - celestron/celestron.c \ - cnctrk/cnctrk.c \ - easycomm/easycomm.c \ - ether6/ether6.c \ - fodtrack/fodtrack.c \ - heathkit/hd1780.c \ - ioptron/rot_ioptron.c \ - m2/rc2800.c \ - meade/meade.c \ - prosistel/prosistel.c \ - rotorez/rotorez.c \ - sartek/sartek.c \ - satel/satel.c \ - spid/spid.c \ - ts7400/ts7400.c) - -hamlib_C_SRC += $(addprefix rotators/gs232a/, \ - gs232.c \ - gs232a.c \ - gs232b.c) - -hamlib_C_SRC += $(addprefix amplifiers/elecraft/, \ - kpa.c \ - kpa1500.c) - -# -# Untested. -# -ifeq ($(USE_LIBINDI),1) - VPATH += $(LIBINDI_ROOT)/libs/indibase - - CFLAGS += -DHAVE_LIBINDI=1 \ - -DHAVE_INDIBASE_LAYOUT=1 \ - -I$(LIBINDI_ROOT) \ - -I$(LIBINDI_ROOT)/libs \ - -I$(LIBINDI_ROOT)/../zlib - - hamlib_C_SRC += rotators/indi/indi.c - hamlib_CPP_SRC = rotators/indi/indi_wrapper.cpp \ - $(addprefix $(LIBINDI_ROOT)/libs/indibase/, \ - basedevice.cpp \ - indiproperty.cpp) -endif - -ifeq ($(USE_GNURADIO),1) - VPATH += extra/gnuradio - CFLAGS += -I./extra/gnuradio -I$(GNURADIO_ROOT)/include - - hamlib_C_SRC += $(addprefix extra/gnuradio/, \ - gr.c \ - graudio.c \ - mc4020.c) - - hamlib_CC_SRC += gnuradio/gnuradio.cc -endif - -# -# Various support code for Hamlib's internal use: -# -hamlib_misc_SRC = lib/termios.c \ - lib/win-misc.c \ - tests/sprintflst.c - -ifneq ($(CC),gcc) - hamlib_misc_SRC += $(addprefix lib/, \ - getopt_long.c \ - gettimeofday.c \ - usleep.c) -endif - -# -# .cc sources for $(Hamlib++_DLL)': -# -hamlib++_SRC = $(addprefix c++/, \ - ampclass.cc \ - rigclass.cc \ - rotclass.cc) - -# -# .c sources for various programs: -# -ampctl_SRC = $(addprefix tests/, \ - ampctl.c \ - ampctl_parse.c \ - dumpcaps_amp.c) - -ampctld_SRC = $(addprefix tests/, \ - ampctld.c \ - ampctl_parse.c \ - dumpcaps_amp.c) - -rigctlcom_SRC = $(addprefix tests/, \ - dumpcaps.c \ - rigctlcom.c \ - rigctl_parse.c) - -rigctl_SRC = $(addprefix tests/, \ - dumpcaps.c \ - dumpcaps_rot.c \ - rigctl.c \ - rigctl_parse.c) - -rigctld_SRC = $(addprefix tests/, \ - dumpcaps.c \ - dumpcaps_rot.c \ - rigctld.c \ - rigctl_parse.c) - -rigmem_SRC = $(addprefix tests/, \ - rigmem.c \ - memcsv.c \ - memload.c \ - memsave.c) - -rotctl_SRC = $(addprefix tests/, \ - rotctl.c \ - rotctl_parse.c \ - dumpcaps.c \ - dumpcaps_rot.c) - -rotctld_SRC = $(addprefix tests/, \ - rotctld.c \ - rotctl_parse.c \ - dumpcaps.c \ - dumpcaps_rot.c) - -hamlib_C_OBJ = $(call c_to_obj, $(hamlib_C_SRC)) -hamlib_CC_OBJ = $(call cc_to_obj, $(hamlib_CC_SRC)) -hamlib_CPP_OBJ = $(call cpp_to_obj,$(hamlib_CPP_SRC)) -hamlib++_OBJ = $(call cc_to_obj, $(hamlib++_SRC)) - -hamlib_misc_OBJ = $(call c_to_obj, $(hamlib_misc_SRC)) -ampctl_OBJ = $(call c_to_obj, $(ampctl_SRC)) -ampctld_OBJ = $(call c_to_obj, $(ampctld_SRC)) -rigctlcom_OBJ = $(call c_to_obj, $(rigctlcom_SRC)) -rigctl_OBJ = $(call c_to_obj, $(rigctl_SRC)) -rigctld_OBJ = $(call c_to_obj, $(rigctld_SRC)) -rigmatrix_OBJ = $(call c_to_obj, tests/rigmatrix.c) -rigmem_OBJ = $(call c_to_obj, $(rigmem_SRC)) -rotctl_OBJ = $(call c_to_obj, $(rotctl_SRC)) -rotctld_OBJ = $(call c_to_obj, $(rotctld_SRC)) - -hamlib_i = $(call c_to_i, $(hamlib_C_SRC)) -hamlib++_i = $(call cc_to_i, $(hamlib++_SRC)) - -$(hamlib_C_OBJ) \ -$(hamlib++_OBJ) \ -$(hamlib_i) \ -$(hamlib++_i): EXTRA_CFLAGS = -DIN_HAMLIB - -$(hamlib++_OBJ) \ -$(hamlib++_i): EXTRA_CFLAGS += -DDLL_EXPORT - -all_test_OBJ = $(addprefix $(OBJ_DIR)/, \ - dumpmem.$(O) \ - example.$(O) \ - listrigs.$(O) \ - rig_bench.$(O) \ - rigsmtr.$(O) \ - rigswr.$(O) \ - simyaesu.$(O) \ - testcpp.$(O) \ - testfreq.$(O) \ - testbcd.$(O) \ - testfreq.$(O) \ - testloc.$(O) \ - testrig.$(O) \ - testrigcaps.$(O) \ - testrigopen.$(O) \ - testtrn.$(O)) - -all_test_OBJ += $(ampctl_OBJ) \ - $(ampctld_OBJ) \ - $(rigctlcom_OBJ) \ - $(rigctl_OBJ) \ - $(rigctld_OBJ) \ - $(rigmatrix_OBJ) \ - $(rigmem_OBJ) \ - $(rotctl_OBJ) \ - $(rotctld_OBJ) \ - -all_test_I = $(notdir $(all_test_OBJ:.$(O)=.i)) - -$(all_test_OBJ) $(all_test_I): EXTRA_CFLAGS = $(PROG_CFLAGS) - -.SECONDARY: $(all_test_OBJ) - -GENERATED = config.h \ - tests/hamlibdatetime.h - -ifneq ($(CC),gcc) - GENERATED += $(addprefix $(OBJ_DIR)/, \ - unistd.h \ - termios.h \ - strings.h \ - sys/time.h \ - sys/ioctl.h) -endif - -all: $(OBJ_DIR) $(OBJ_DIR)/sys $(GENERATED) rm_elecraft $(TARGETS) programs epilogue - -$(OBJ_DIR) $(OBJ_DIR)/sys: - - $(MKDIR) $@ - -# -# This is a 0-byte file that messes with 'rigs/kenwood/elecraft.c' -# -rm_elecraft: - rm -f amplifiers/elecraft/elecraft.c - -epilogue: - $(call white_message, Welcome to $(Hamlib_DLL) and $(Hamlib++_DLL) (CPU=$(CPU)).) - $(call green_message, You could also do a 'make -f $(THIS_FILE) [doxy_docs | py_module | lua_module]'.\n) - -programs: $(GENERATED) $(TESTS_PROGS) - -$(hamlib_misc_OBJ): EXTRA_CFLAGS += -DIN_HAMLIB_MISC_LIB - -$(misc_LIB): $(hamlib_misc_OBJ) - $(call create_lib, $@, $^) - -$(Hamlib_STAT_LIB): $(hamlib_C_OBJ) $(hamlib_CC_OBJ) $(hamlib_CPP_OBJ) - $(call create_lib, $@, $^) - -$(Hamlib_IMP_LIB): $(Hamlib_DLL) -$(Hamlib++_IMP_LIB): $(Hamlib++_DLL) - -$(Hamlib_DLL): $(OBJ_DIR)/Hamlib.def $(Hamlib_STAT_LIB) $(misc_LIB) $(OBJ_DIR)/Hamlib.res - $(call link_DLL, $@, $(Hamlib_IMP_LIB), $(call select,,-def:)$^ $(EX_LIBS)) - -$(Hamlib++_DLL): $(hamlib++_OBJ) $(Hamlib_IMP_LIB) $(OBJ_DIR)/Hamlib++.res - $(call link_DLL, $@, $(Hamlib++_IMP_LIB), $^ $(call select, -lstdc++,) $(EX_LIBS)) - -# -# For MSVC only. -# -ifeq ($(USE_MP_COMPILE),1) - $(hamlib_C_OBJ): $(hamlib_C_SRC) | $(CC).args - $(CC) -MP @$(CC).args -DIN_HAMLIB -Fo./$(OBJ_DIR)\\ $(hamlib_C_SRC) - @echo -endif - -$(CC).args: $(THIS_FILE) - $(call green_message, Creating $@) - $(call create_resp_file, $@, $(CFLAGS) -c) - -# -# For 'testcpp.exe': -# -testcpp.exe: $(OBJ_DIR)/testcpp.$(O) $(CPP_PROG_LIBS) - $(call link_EXE, $@, $^ $(call select, -lstdc++,) $(EX_LIBS)) - -# -# For '$(TESTS_PROGS)': -# -$(OBJ_DIR)/%.$(O): tests/%.c | $(CC).args - $(call Compile, $<, $@) - -ampctl.exe: $(ampctl_OBJ) $(C_PROG_LIBS) - $(call link_EXE, $@, $^ $(PROG_LIBS)) - -ampctld.exe: $(ampctld_OBJ) $(C_PROG_LIBS) - $(call link_EXE, $@, $^ $(PROG_LIBS)) - -rigctlcom.exe: $(rigctlcom_OBJ) $(C_PROG_LIBS) - $(call link_EXE, $@, $^ $(PROG_LIBS)) - -rigctl.exe: $(rigctl_OBJ) $(C_PROG_LIBS) - $(call link_EXE, $@, $^ $(PROG_LIBS)) - -rigctld.exe: $(rigctld_OBJ) $(C_PROG_LIBS) - $(call link_EXE, $@, $^ $(PROG_LIBS)) - -rigmem.exe: $(rigmem_OBJ) $(C_PROG_LIBS) $(XML2_LIB) - $(call link_EXE, $@, $^ $(PROG_LIBS)) - -rotctl.exe: $(rotctl_OBJ) $(C_PROG_LIBS) - $(call link_EXE, $@, $^ $(PROG_LIBS)) - -rotctld.exe: $(rotctld_OBJ) $(C_PROG_LIBS) - $(call link_EXE, $@, $^ $(PROG_LIBS)) - -# -# I do not have a GD.lib for MSVC/clang. Use the dynamic MinGW version instead. -# Copy it's .DLL here to avoid another DLL-hell. -# -rigmatrix.exe: $(rigmatrix_OBJ) $(C_PROG_LIBS) $(LIBGD_ROOT)/src/libgd.dll.a - $(call link_EXE, $@, $^ $(PROG_LIBS)) - $(COPY) $(LIBGD_ROOT)/src/bgd.dll . - -# -# For all other simple test-programs: -# -%.exe: $(OBJ_DIR)/%.$(O) $(C_PROG_LIBS) - $(call link_EXE, $@, $^ $(PROG_LIBS)) - -# -# For '$(hamlib_C_SRC)' and '$(hamlib_CC_SRC)': -# -$(OBJ_DIR)/%.$(O): %.c | $(CC).args - $(call Compile, $<, $@) - -$(OBJ_DIR)/%.$(O): %.cc | $(CC).args - $(call Compile, $<, $@) - -$(OBJ_DIR)/%.$(O): %.cpp | $(CC).args - $(call Compile, $<, $@) - -# -# For '$(hamlib_misc_SRC)' since 'lib' is not in 'VPATH' due to 'lib/dummy.c'. -# -$(OBJ_DIR)/%.$(O): lib/%.c | $(CC).args - $(call Compile, $<, $@) - -clean: $(CC)_clean - rm -f $(GENERATED) $(OBJ_DIR)/*.{$(O),rc,res,def} \ - $(TESTS_PROGS:.exe=.map) cl.args clang-cl.args gcc.args lib.args cpp_filter.py - - $(RMDIR) $(OBJ_DIR)/sys $(OBJ_DIR) - -gcc_clean: ; - -cl_clean clang-cl_clean: - rm -f link.tmp vc1*.pdb $(Hamlib_DLL:.dll=.pdb) $(Hamlib++_DLL:.dll=.pdb) \ - $(TESTS_PROGS:.exe=.pdb) $(TESTS_PROGS:.exe=.exp) $(TESTS_PROGS:.exe=.lib) - -vclean realclean: clean doc_clean py_clean lua_clean - rm -f $(TARGETS) $(Hamlib_DLL:.dll=.map) $(Hamlib++_DLL:.dll=.map) \ - $(TESTS_PROGS) bgd.dll .depend.Windows - -config.h: $(THIS_FILE) - $(call Generate, $@, //) - $(file >> $@,#ifndef _CONFIG_H) - $(file >> $@,#define _CONFIG_H) - $(file >> $@,$(CONFIG_H)) - $(file >> $@,#endif /* _CONFIG_H */) - -tests/hamlibdatetime.h: $(THIS_FILE) - $(call Generate, $@, //) - $(file >> $@, #define HAMLIBDATETIME "__DATE__") - -$(OBJ_DIR)/unistd.h: $(THIS_FILE) - $(call Generate_fake, $@, #include "lib/getopt.h") - -$(OBJ_DIR)/sys/time.h: $(THIS_FILE) - $(call Generate_fake, $@) - -$(OBJ_DIR)/strings.h: $(THIS_FILE) - $(call Generate_fake, $@, #include ) - -$(OBJ_DIR)/termios.h: $(THIS_FILE) - $(call Generate_fake, $@) - -$(OBJ_DIR)/sys/ioctl.h: $(THIS_FILE) - $(call Generate_fake, $@) - -%.i: %.c FORCE $(GENERATED) cpp_filter.py $(CC).args - $(call Cxx_preprocess, $@, $<, c) - -%.i: lib/%.c FORCE $(GENERATED) cpp_filter.py $(CC).args - $(call Cxx_preprocess, $@, $<, c) - -%.i: $(OBJ_DIR)/%.c FORCE $(GENERATED) cpp_filter.py $(CC).args - $(call Cxx_preprocess, $@, $<, c) - -%.i: %.cc FORCE $(GENERATED) cpp_filter.py $(CC).args - $(call Cxx_preprocess, $@, $<, cpp) - -%.i: %.cpp FORCE $(GENERATED) cpp_filter.py $(CC).args - $(call Cxx_preprocess, $@, $<, cpp) - -FORCE: - -# -# Create API documentation in 'doc/html/index.html': -# -doxy_docs: doc/Hamlib.cfg - cd doc ; \ - doxygen Hamlib.cfg 2> doxygen.log ; \ - cd html ; \ - hhc index.hhp ; \ - mv -f Hamlib.chm .. - @echo 'Doxygen done. Look in "doc/doxygen.log" for messages.' - -doc/Hamlib.cfg: $(THIS_FILE) - $(call Generate, $@, #) - $(file >> $@,$(hamlib_CFG)) - -doc_clean: - rm -f doc/doxygen.log doc/hamlib.cfg doc/Hamlib.chm - rm -fR doc/html/* - - rmdir doc/html - -# -# Python 2/3 module stuff. -# -# Get the Python prefix via the 'py -x' launcher. -# The Python major version (2 or 3) is simply '$(USE_PY_BINDING)'. -# -PY_ROOT = $(subst \,/,$(shell py -$(USE_PY_BINDING) -c "import sys; print(sys.prefix)")) - -ifeq ($(USE_PY_BINDING),2) - PY_WRAPPER_C = $(OBJ_DIR)/HamlibPy2_wrap.c - PY_WRAPPER_O = $(OBJ_DIR)/HamlibPy2_wrap.$(O) - -else ifeq ($(USE_PY_BINDING),3) - PY_WRAPPER_C = $(OBJ_DIR)/HamlibPy3_wrap.c - PY_WRAPPER_O = $(OBJ_DIR)/HamlibPy3_wrap.$(O) -endif - -ifeq ($(CC),gcc) - PYD_LIBS = $(PY_ROOT)/libs/libpython$(USE_PY_BINDING)*.a -endif - -_Hamlib_PYD_deps = $(PY_WRAPPER_O) $(OBJ_DIR)/HamlibPy.res $(Hamlib_IMP_LIB) -PY_CFLAGS = -I$(PY_ROOT)/include -DNO_SSIZE_T -DDLL_EXPORT - -ifeq ($(USE_PY_BINDING),0) - py_module: - $(error Use 'USE_PY_BINDING=[2|3]'.) - -else - py_module: _Hamlib.pyd $(OBJ_DIR)/Hamlib.py $(Hamlib_DLL) - $(COPY) $^ $(PY_ROOT)/Lib/site-packages -ifneq ($(CC),gcc) - $(COPY) _Hamlib.pdb $(PY_ROOT)/Lib/site-packages -endif -endif - -$(OBJ_DIR)/Hamlib.py: $(PY_WRAPPER_C) - -SWIG_FLAGS = -I./include -I./bindings # -macroerrors - -$(PY_WRAPPER_C): bindings/Hamlib.swg include/hamlib/rig.h - $(call green_message, Generating $@ and $(OBJ_DIR)/Hamlib.py) - swig -python $(SWIG_FLAGS) -o $@ $< - -$(PY_WRAPPER_O) $(PY_WRAPPER_C:.c=.i): EXTRA_CFLAGS += $(PY_CFLAGS) - -ifeq ($(USE_PY_BINDING),3) - _Hamlib.pyd: $(_Hamlib_PYD_deps) - $(call link_PYD, $@, $^ $(PYD_LIBS), PyInit__Hamlib) - -else ifeq ($(USE_PY_BINDING),2) - _Hamlib.pyd: $(_Hamlib_PYD_deps) - $(call link_PYD, $@, $^ $(PYD_LIBS), init_Hamlib) -endif - -py_JUNK = $(OBJ_DIR)/Hamlib.py \ - _Hamlib.pyd \ - _Hamlib.map \ - _Hamlib.pdb \ - _Hamlib.exp \ - _Hamlib.lib \ - $(PY_WRAPPER_C) \ - $(OBJ_DIR)/HamlibPy.res - -py_clean: - rm -f $(py_JUNK) - -# -# Lua module stuff. Only LuaJIT seems to be stable. -# -# The 'HamlibLua.dll' exports only 'luaopen_Hamliblua()' -# -lua_module: HamlibLua.dll - $(call green_message, Remember to update your 'LUA_CPATH' for 'HamlibLua.dll'. And your 'PATH' for the needed '$(Hamlib_DLL)') -# $(COPY) $^ $(some_where_on_PATH_and_LUA_CPATH) - -$(OBJ_DIR)/HamlibLua_wrap.c: bindings/Hamlib.swg - $(call green_message, Generating $@) - swig -lua $(SWIG_FLAGS) -o $@ $< - -$(OBJ_DIR)/HamlibLua_wrap.$(O) HamlibLua_wrap.i: EXTRA_CFLAGS = -I$(LUA_ROOT)/src -DDLL_EXPORT - -# -# The imp-lib 'HamlibLua.$(A)' is not needed for anything. -# -HamlibLua.dll: $(OBJ_DIR)/HamlibLua_wrap.$(O) $(Hamlib_IMP_LIB) $(OBJ_DIR)/HamlibLua.res - $(call link_DLL, $@, HamlibLua.$(A), $^ $(LUA_LIB)) - -lua_JUNK = HamlibLua.dll \ - HamlibLua.$(A) \ - HamlibLua.map \ - HamlibLua.pdb \ - HamlibLua.exp \ - $(OBJ_DIR)/HamlibLua_wrap.c - -lua_clean: - rm -f $(lua_JUNK) - -$(OBJ_DIR)/Hamlib.rc: $(THIS_FILE) - $(call make_rc, $@, $(Hamlib_DLL), "Ham Radio Control Library for C", VFT_DLL) - -$(OBJ_DIR)/Hamlib++.rc: $(THIS_FILE) - $(call make_rc, $@, $(Hamlib++_DLL), "Ham Radio Control Library for C++", VFT_DLL) - -$(OBJ_DIR)/HamlibPy.rc: $(THIS_FILE) - $(call make_rc, $@, _Hamlib.pyd, "Hamlib module for Python v$(USE_PY_BINDING).x", VFT_DLL) - -$(OBJ_DIR)/HamlibLua.rc: $(THIS_FILE) - $(call make_rc, $@, HamlibLua.dll, "Hamlib module for LuaJIT", VFT_DLL) - -$(OBJ_DIR)/%.res: $(OBJ_DIR)/%.rc config.h - $(call make_res, $<, $@) - -# -# Create an export definition file by using 'nm $(Hamlib_STAT_LIB)' to -# extract all the public functions; -# i.e. ' T ' symbols are "Text symbol, global". See 'man nm' for details. -# -# On 'CPU=x86', all symbols have a leading '_'. Drop these. -# -# Ignore symbols matching ' Wspiapi.*' and ' _.*'. -# -# Append the DATA symbols manually. -# -ifeq ($(CPU),x86) - uscore := _ -endif - -# -# Export all code symbols. -# -extract_code_syms = nm $(2) | grep ' T $(uscore)[a-zA-Z0-9_]*' | \ - sed -e 's@^.* $(uscore)@ @g' \ - -e 's@ Wspiapi.*@@g' \ - -e 's@ _.*@@g' | sort | uniq >> $(1) - -define Hamlib_DATA - hamlib_version DATA - hamlib_copyright DATA - hamlib_version2 DATA - hamlib_copyright2 DATA - debugmsgsave DATA - debugmsgsave2 DATA -endef - -export Hamlib_DATA - -# -# We export stuff using this generated .def-file: -# -$(OBJ_DIR)/Hamlib.def: $(Hamlib_STAT_LIB) $(THIS_FILE) - $(call Generate, $@, ;) - $(file >> $@, LIBRARY $(Hamlib_DLL)) - $(file >> $@, EXPORTS) - $(call extract_code_syms, $@, $<) - @echo "$$Hamlib_DATA" >> $@ - -# -# GNU-make macros. -# -# This assumes you have a Cygwin/Msys 'echo' with colour support. -# -green_message = @echo -e "\e[1;32m$(strip $(1))\e[0m" -white_message = @echo -e "\e[1;37m$(strip $(1))\e[0m" - -# -# .c compile macro. -# $(1): the .c file (and extra CFLAGS) -# $(2): the .$(O) file -# -# Do not use '@gcc.args' since some old gcc gets confused by it!? -# -ifeq ($(CC),gcc) - define Compile - $(CC) @$(CC).args $(EXTRA_CFLAGS) -o $(2) $(1) - @echo - endef -else - define Compile - $(CC) @$(CC).args $(EXTRA_CFLAGS) -Fo$(strip $(2)) $(1) - @echo - endef -endif - -# -# Create an EXE from objects. -# arg1, $(1): The .exe file. -# arg2, $(2): The .$(O) file(s), extra args and libs. -# -define link_EXE - $(call green_message, Linking $(1)) - $(call link_EXE_$(CC), $(1), $(2)) - @echo -endef - -define link_EXE_cl - link $(LDFLAGS) -out:$(strip $(1)) $(2) > link.tmp - @cat link.tmp >> $(1:.exe=.map) -endef - -link_EXE_clang-cl = $(call link_EXE_cl, $(1), $(2)) -link_EXE_gcc = $(CC) $(LDFLAGS) -o $(1) $(2) > $(1:.exe=.map) - -# -# Macro to create a DLL + import-lib from objects. -# arg1, $(1): The .dll file. -# arg2, $(2): The import-lib. -# arg3, $(3): The .$(O) file(s), extra args and libs. -# -define link_DLL - $(call green_message, Linking $(1)) - $(call link_DLL_$(CC), $(1), $(2), $(3)) - @echo -endef - -define link_DLL_cl - link -dll $(LDFLAGS) -out:$(strip $(1)) -implib:$(strip $(2)) $(3) > link.tmp - @cat link.tmp >> $(1:.dll=.map) - @rm -f $(2:.lib=.exp) -endef - -link_DLL_clang-cl = $(call link_DLL_cl, $(1), $(2), $(3)) -link_DLL_gcc = $(CC) -shared $(LDFLAGS) -o $(1) -Wl,--out-implib,$(strip $(2)) $(3) > $(1:.dll=.map) - -# -# Macro to create a Python .PYD-module from objects. -# arg1, $(1): The .pyd file. -# arg2, $(2): The .$(O) file(s), extra args and libs. -# arg3, $(3): The name of the Python init function. -# Not used by MinGW. It exports the 'SWIGEXPORT SWIG_init()' function -# in the 'HamlibPyX_wrap.c' code. -# -define link_PYD - $(call green_message, Linking $(1)) - $(call link_PYD_$(CC), $(1), $(2), $(3)) - @echo -endef - -define link_PYD_cl - link -dll $(LDFLAGS) -libpath:$(PY_ROOT)/libs -export:$(strip $(3)) -out:$(strip $(1)) $(2) > link.tmp - @cat link.tmp >> $(1:.pyd=.map) - @rm -f $(1:.pyd=.exp) $(1:.pyd=.lib) -endef - -link_PYD_clang-cl = $(call link_PYD_cl, $(1), $(2), $(3)) -link_PYD_gcc = $(CC) -shared $(LDFLAGS) -o $(1) $(2) > $(1:.pyd=.map) - -define make_res - $(call green_message, Creating $(2)) - $(call make_res_$(CC), $(1), $(2)) - @echo -endef - -make_res_cl = rc -nologo -D_MSC_VER -Fo./$(strip $(2)) $(1) -make_res_clang-cl = rc -nologo -D__clang__ -Fo./$(strip $(2)) $(1) -make_res_gcc = windres -D__MINGW32__ -O COFF -I. $(RCFLAGS) -o $(2) -i $(1) - -# -# static .lib creation macro: -# arg1: $(1): the .$(A) file. -# arg2: $(2): the .$(O) files to put in it. -# -define create_lib - @rm -f $(1) - $(call green_message, Creating $(1)) - $(call create_resp_file, lib.args, $(2)) - $(call create_lib_$(CC), $(1)) - @echo -endef - -create_lib_cl = lib -nologo -out:$(strip $(1)) @lib.args -create_lib_clang-cl = $(call create_lib_cl, $(1)) -create_lib_gcc = ar rs $(1) @lib.args - -# -# Create a response file $(1). -# One word from $(2) per line. -# -define create_resp_file - $(file > $(1)) - $(foreach f, $(2), $(file >> $(1),$(strip $(f))) ) -endef - -define Warning - $(1) - $(1) DO NOT EDIT! This file was automatically generated - $(1) from $(realpath $(THIS_FILE)) at $(DATE). - $(1) Edit that file instead. - $(1) -endef - -define Generate - $(call green_message, Generating $(1)) - $(file > $(1),$(call Warning,$(strip $(2)))) -endef - -define Generate_fake - $(call Generate, $(1), //) - $(file >> $(1), // fake <$(strip $(1))> for MSVC/clang-cl) - $(file >> $(1), $(2)) -endef - -define CONFIG_H - #define ABI_VERSION $(ABI_VER) - - #if defined(IN_HAMLIB) && defined(DLL_EXPORT) && !defined(__cplusplus) - #error "Do not use '-DDLL_EXPORT' since we use a .def-file to control the exports." - #endif - - #ifndef WIN32 - #define WIN32 1 - #endif - - #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0601) - #undef _WIN32_WINNT - #define _WIN32_WINNT 0x0601 - #endif - - #define WIN32_LEAN_AND_MEAN - - /* - * MSVC/clang-cl: - * Except for .cc code (the 'LIBUSB_ROOT' code that needs Boost), and - * while doing 'make depend', pretend we are MinGW. - */ - #if defined(_MSC_VER) - #define _CRT_SECURE_NO_WARNINGS - #define _CRT_NONSTDC_NO_WARNINGS - - struct timeval; /* Forward */ - struct timezone; /* Forward */ - - extern int gettimeofday (struct timeval *, struct timezone *); - #else - /* - * MinGW section: - */ - #define HAVE_PTHREAD 1 - #define HAVE_UNISTD_H 1 - #define HAVE_SELECT 1 - #define HAVE_SSLEEP 1 - #define HAVE_SYS_TIME_H 1 - #define HAVE_STRTOK_R 1 - - #include /* 'gettimeofday()' */ - #endif - - #include - #include /* 'struct timeval' etc. */ - #include /* 'gai_strerror()' etc. */ - #include /* 'struct timespec' etc. */ - #include /* 'open()', 'close()' etc. */ - #include /* 'int64_t' etc. */ - #include /* 'getpid()' etc. */ - #include /* 'alloca()' etc. */ - - #define HAVE_SYS_TYPES_H 1 - #define HAVE_INTTYPES_H 1 - #define HAVE_WINRADIO 1 - #define HAVE_WINDOWS_H 1 - #define HAVE_WINBASE_H 1 - #define HAVE_WS2TCPIP_H 1 - #define HAVE_WSPIAPI_H 1 - #define HAVE_GETADDRINFO 1 - #define HAVE_DECL_GAI_STRERROR 1 - #define HAVE_SELECT 1 - #define HAVE_SSLEEP 1 - #define HAVE_SLEEP 1 - - #if defined(_MSC_VER) - #ifndef __clang__ - #define __attribute__(x) - #endif - - #define strncasecmp(s1, s2, n) _strnicmp (s1, s2, n) - #define sleep(s) Sleep (1000*(s)) - - extern int usleep (unsigned long usec); - #endif - - /* No point in defining this - */ -//#define HAVE_SIGNAL 1 - - /* Since 'WIN32_LEAN_AND_MEAN' is defined, this header is - * not included in . So do it explicitly, but it is - * only needed in 'rigs/winradio/g313-win.c'. - */ - #include - - #define _TIMEVAL_DEFINED - #define _TIMESPEC_DEFINED - #define _USE_MATH_DEFINES /* 'M_PI' etc. */ - - #if !defined(_SSIZE_T_DEFINED) && !defined(NO_SSIZE_T) - #include - - typedef SSIZE_T ssize_t; - #define _SSIZE_T_DEFINED - #endif - - #if !defined(_UINT_DEFINED) - typedef unsigned int uint; - - #define _UINT_DEFINED - #endif - - #if !defined(_MODE_T_DEFINED) && !defined(__MINGW32__) - typedef unsigned short mode_t; - #define _MODE_T_DEFINED - #endif - - #if !defined(timersub) - #define timersub(a, b, result) do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_usec += 1000000; \ - } \ - } while (0) - #endif - - /* Hack for using libusrp dynamically (untested) - */ - #ifdef HAVE_USRP - #define LIBUSRP_SPEC __declspec(dllimport) - #endif - - #define PACKAGE_VERSION "$(VERSION)" - - /* Functions in 'lib/win-misc.c': - */ - #ifndef CLOCK_REALTIME - #define CLOCK_REALTIME 0 - #endif - - extern int clock_gettime (int clock_id, struct timespec *ts); - - #ifndef HAVE_STRTOK_R - extern char *strtok_r (char *s, const char *delim, char **ptrptr); - #endif - -endef - -# -# The contents of 'doc/Hamlib.cfg' used by Doxygen. -# -define hamlib_CFG - # - # All paths are relative to './doc'. - # - PROJECT_NAME = "Hamlib" - PROJECT_NUMBER = $(VERSION) - PROJECT_LOGO = hamlib.png - OUTPUT_DIRECTORY = . - PREDEFINED = __GNUC__ DOXYGEN DOC_HIDDEN - OUTPUT_LANGUAGE = English - GENERATE_HTML = YES - GENERATE_LATEX = NO - GENERATE_RTF = NO - GENERATE_MAN = NO - MAN_EXTENSION = .3 - TAB_SIZE = 4 - CASE_SENSE_NAMES = NO - FULL_PATH_NAMES = NO -# ALIASES = \RETURNFUNC{1}="\b RETURNFUNC(\1)" \ - - INPUT = index.doxygen ../src/ ../include/hamlib/ - INCLUDE_PATH = ../include/ - EXAMPLE_PATH = .. \ - ../tests/testrig.c \ - ../scripts/README.build-Windows \ - ../scripts/build-w32.sh \ - ../scripts/build-w64.sh - - EXCLUDE = ../src/amp_conf.h \ - ../include/hamlib/ampclass.h \ - ../include/hamlib/rotclass.h - - QUIET = YES - HTML_EXTRA_STYLESHEET = hamlib.css - HTML_FOOTER = footer.html - - EXTRACT_ALL = NO - EXTRACT_STATIC = NO - HIDE_UNDOC_MEMBERS = NO - SHOW_INCLUDE_FILES = YES - INHERIT_DOCS = YES - ENABLED_SECTIONS = "" - JAVADOC_AUTOBRIEF = NO - OPTIMIZE_OUTPUT_FOR_C = YES - MAN_LINKS = NO - MACRO_EXPANSION = YES - SOURCE_BROWSER = YES - STRIP_CODE_COMMENTS = NO - GENERATE_HTMLHELP = YES - CHM_FILE = Hamlib.chm - SEARCHENGINE = NO -endef - -define RC_COMMON - #include - - #if defined(__clang__) - #define RC_BUILDER "clang-cl" - - #elif defined(_MSC_VER) - #define RC_BUILDER "MSVC" - - #elif defined(__MINGW32__) - #define RC_BUILDER "MinGW" - - #else - #error "Who are you?" - #endif - - #ifndef RC_DESCRIPTION - #error "Add a #define RC_DESCRIPTION .." - #endif - - #ifndef RC_FILENAME - #error "Add a #define RC_FILENAME .." - #endif - - #ifndef RC_FILETYPE - #define RC_FILETYPE VFT_DLL - #endif - - #define RC_VERSION $(MAJOR_VER),$(MINOR_VER),0,0 - #define RC_VER_STRING "$(VERSION).0.0 (" RC_BUILDER ", $(CPU))" - - VS_VERSION_INFO VERSIONINFO - FILEVERSION RC_VERSION - PRODUCTVERSION RC_VERSION - FILEFLAGSMASK 0x3fL - FILEOS VOS__WINDOWS32 - FILETYPE RC_FILETYPE - FILEFLAGS 0x0L - FILESUBTYPE 0x0L - - BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "https://hamlib.github.io/" - VALUE "FileDescription", RC_DESCRIPTION - VALUE "FileVersion", RC_VER_STRING - VALUE "InternalName", "Hamlib, ABI ver. $(ABI_VER)" - VALUE "LegalCopyright", "GNU General Public License v2.0" - VALUE "OriginalFilename", RC_FILENAME - VALUE "ProductName", RC_FILENAME - VALUE "ProductVersion", RC_VER_STRING - VALUE "PrivateBuild", "The privat build of ." - VALUE "SpecialBuild", "" - VALUE "Comments", "Built on $(DATE)" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END - END -endef - -define make_rc - $(call Generate, $(1), //) - $(file >> $@, #define RC_FILENAME "$(strip $(2))") - $(file >> $@, #define RC_DESCRIPTION $(3)) - $(file >> $@, #define RC_FILETYPE $(4)) - $(file >> $@, $(RC_COMMON)) -endef - -ifeq ($(USE_ASTYLE),1) - define Cxx_preprocess - $(file > $(1),/* The preprocessed and AStyle formatter output of '$(strip $(2))':) - $(file >> $(1), * $(CC) -E) - @$(foreach f, $(CFLAGS) $(EXTRA_CFLAGS), $(file >> $(1), * $(f))) - $(file >> $(1), *---------------------------------------------------------) - $(file >> $(1), */) - $(CC) -E @$(CC).args $(EXTRA_CFLAGS) $(2) | $(PYTHON) cpp_filter.py | astyle >> $(1) - endef - -else ifeq ($(USE_CLANG_FORMAT),1) - define Cxx_preprocess - $(file > $(1),/* The preprocessed and clang-formatted output of '$(strip $(2))':) - $(file >> $(1), * $(CC) -E) - @$(foreach f, $(CFLAGS) $(EXTRA_CFLAGS), $(file >> $(1), * $(f))) - $(file >> $(1), *---------------------------------------------------------) - $(file >> $(1), */) - $(CC) -E @$(CC).args $(EXTRA_CFLAGS) $(2) | $(PYTHON) cpp_filter.py | clang-format --assume-filename=$(strip $(3)) >> $(1) - endef - -else - define Cxx_preprocess - $(file > $(1),/* The raw preprocessed output of '$(strip $(2))':) - $(file >> $(1), * $(CC) -E) - @$(foreach f, $(CFLAGS) $(EXTRA_CFLAGS), $(file >> $(1), * $(f))) - $(file >> $(1), *---------------------------------------------------------) - $(file >> $(1), */) - $(CC) -E @$(CC).args $(EXTRA_CFLAGS) $(2) | $(PYTHON) cpp_filter.py >> $(1) - endef -endif - -define CPP_FILTER_PY - import sys, os - - try: - import ntpath - except ImportError as e: - print ("Failed to import ntpath: %s" % e) - sys.exit(1) - - def _win32_abspath (path): - path = ntpath.abspath (path) - return path.replace ('\\', '/') - - def skip_cwd (s1, s2): - ''' Skip the leading part that is in common with s1 and s2 - ''' - i = 0 - while i < len(s1) and s1[i] == s2[i]: - i += 1 - return s2[i:] - - cwd = _win32_abspath (os.getcwd()) + '/' - - last_line = '??' - last_fname = '??' - empty_lines = 0 - - while True: - line = sys.stdin.readline() - if not line: - break - if line.startswith('\n') or line.startswith('\r'): - empty_lines += 1 - continue - - line = line.replace ("\\\\", "/") - fname = None - quote = line.find ('\"') - - if line.startswith ("#line ") and quote > 0: - fname = _win32_abspath (line[quote:]) - last_fname = fname - - if line.strip() != '' and last_line != '': - if fname is None or fname != last_fname: - print (line, end="") - - if line.strip() == '}': # Print a newline after a function - print ("") - - last_line = line - - if empty_lines > 0: - sys.stderr.write ("Removed %d empty lines.\n" % empty_lines) - -endef - -cpp_filter.py: $(THIS_FILE) - $(call Generate, $@, #) - $(file >> $@,from __future__ import print_function) - $(file >> $@,if 1:) - $(file >> $@,$(CPP_FILTER_PY)) - -# -# Use gcc to create a '.depend.Windows' -# -DEP_CFLAGS = -MM --include config.h $(filter -I% -D%, $(CFLAGS)) -DEP_REPLACE = sed -e 's@\(.*\)\.o: @\n$$(OBJ_DIR)\/\1.$$(O): @' \ - -e 's@$(OBJ_DIR)/[a-z]*\.h@@g' \ - -e 's@$(OBJ_DIR)/sys/[a-z]*\.h@@g' \ - -e 's@$(LIBUSRP_ROOT)@$$(LIBUSRP_ROOT)@' - -ALL_C_SRC = $(hamlib_C_SRC) $(hamlib_misc_SRC) $(wildcard tests/*.c) -ALL_CC_SRC = $(hamlib_CC_SRC) $(hamlib++_SRC) $(hamlib_CPP_SRC) - -depend: $(OBJ_DIR) $(OBJ_DIR)/sys $(GENERATED) - $(call Generate, .depend.Windows, #) - $(call create_resp_file, depend1.args, $(DEP_CFLAGS) $(ALL_C_SRC)) - $(call create_resp_file, depend2.args, $(DEP_CFLAGS) -std=c++11 $(ALL_CC_SRC)) - gcc @depend1.args | $(DEP_REPLACE) >> .depend.Windows - gcc @depend2.args | $(DEP_REPLACE) >> .depend.Windows - rm -f depend1.args depend2.args - --include .depend.Windows - - © 2021 GitHub, Inc. - Terms - Privacy - Security - Status - Docs - - Contact GitHub - Pricing - API - Training - Blog - About - diff --git a/NEWS b/NEWS index b99dc6bb4..a0114ed9c 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,8 @@ Version 5.x -- future * Change FT1000MP Mark V model names to align with FT1000MP Version 4.6 + * Added BG2FX FX4/C/CR/L + * Fixed IC7610 to use new 0x25 0x26 command added in latest firmware * Fix W command in rigctld to work propery -- can take terminating char or # of bytes to expect * Add rig_set_debug_filename so Python can redirect debug stream * Fix Yaesu LBL_NR to use proper values diff --git a/configure.ac b/configure.ac index 08ba1fa48..4ae88dbdf 100644 --- a/configure.ac +++ b/configure.ac @@ -382,12 +382,14 @@ AS_IF([test x"$ax_cv_lib_readline" = "xno"], [ dnl Check if INDI support in rigctl/rotctl is wanted AC_MSG_CHECKING([whether to use INDI in rigctl/rotctl]) -AC_ARG_WITH([indi], - [AS_HELP_STRING([--without-indi], - [disable INDI in rigctl/rotctl @<:@default=yes@:>@])], - [cf_with_indi_support=no], - [cf_with_indi_support=yes] +AS_IF([test x"${cf_with_cxx_binding}" = "xyes"], [ + AC_ARG_WITH([indi], + [AS_HELP_STRING([--without-indi], + [disable INDI in rigctl/rotctl @<:@default=yes@:>@])], + [cf_with_indi_support=no], + [cf_with_indi_support=yes] ) +]) AS_IF([test x"$cf_with_indi_support" != "xno"], [ # INDI support needs a C++ compiler, tested for presence above. diff --git a/doc/man1/rigctld.1 b/doc/man1/rigctld.1 index af3b6b4e0..9680b7fc7 100644 --- a/doc/man1/rigctld.1 +++ b/doc/man1/rigctld.1 @@ -436,7 +436,7 @@ Since most of the .B Hamlib operations have a .BR set " and a " get -method, a single pper case letter will be used for +method, a single upper case letter will be used for .B set methods whereas the corresponding single lower case letter refers to the .B get diff --git a/include/hamlib/rig.h b/include/hamlib/rig.h index 908f753c4..20eb6466a 100644 --- a/include/hamlib/rig.h +++ b/include/hamlib/rig.h @@ -29,7 +29,7 @@ // Our shared secret password #define HAMLIB_SECRET_LENGTH 32 -#define HAMLIB_TRACE rig_debug(RIG_DEBUG_TRACE,"%s(%d) trace\n", __FILE__, __LINE__) +#define HAMLIB_TRACE rig_debug(RIG_DEBUG_TRACE,"%.*s%s(%d) trace\n",rig->state.depth-1, spaces(), __FILE__, __LINE__) #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #include @@ -2680,6 +2680,8 @@ struct rig_state { freq_t spectrum_spans[HAMLIB_MAX_SPECTRUM_SPANS]; /*!< Supported spectrum scope frequency spans in Hz in center mode. Last entry must be 0. */ struct rig_spectrum_avg_mode spectrum_avg_modes[HAMLIB_MAX_SPECTRUM_AVG_MODES]; /*!< Supported spectrum scope averaging modes. Last entry must have NULL name. */ int spectrum_attenuator[HAMLIB_MAXDBLSTSIZ]; /*!< Spectrum attenuator list in dB, 0 terminated */ + volatile int morse_data_handler_thread_run; + void *morse_data_handler_priv_data; }; /** @@ -2853,6 +2855,7 @@ typedef int (*spectrum_cb_t)(RIG *, * \sa rig_set_freq_callback(), rig_set_mode_callback(), rig_set_vfo_callback(), * rig_set_ptt_callback(), rig_set_dcd_callback() */ +// Do NOT add/remove from this structure -- it will break DLL backwards compatiblity struct rig_callbacks { freq_cb_t freq_event; /*!< Frequency change event */ rig_ptr_t freq_arg; /*!< Frequency change argument */ @@ -2914,17 +2917,29 @@ extern HAMLIB_EXPORT(void) rig_lock(RIG *rig, int lock); #if BUILTINFUNC -#define rig_set_freq(r,v, f) rig_set_vfo(r,v,f,__builtin_FUNCTION()) +#define rig_set_freq(r,v,f) rig_set_freq(r,v,f,__builtin_FUNCTION()) +extern HAMLIB_EXPORT(int) +rig_set_freq HAMLIB_PARAMS((RIG *rig, + vfo_t vfo, + freq_t freq, const char*)); #else extern HAMLIB_EXPORT(int) rig_set_freq HAMLIB_PARAMS((RIG *rig, vfo_t vfo, freq_t freq)); #endif +#if BUILTINFUNC +#define rig_get_freq(r,v,f) rig_get_freq(r,v,f,__builtin_FUNCTION()) +extern HAMLIB_EXPORT(int) +rig_get_freq HAMLIB_PARAMS((RIG *rig, + vfo_t vfo, + freq_t *freq, const char*)); +#else extern HAMLIB_EXPORT(int) rig_get_freq HAMLIB_PARAMS((RIG *rig, vfo_t vfo, freq_t *freq)); +#endif extern HAMLIB_EXPORT(int) rig_set_mode HAMLIB_PARAMS((RIG *rig, @@ -3540,7 +3555,7 @@ extern HAMLIB_EXPORT_VAR(char) debugmsgsave3[DEBUGMSGSAVE_SIZE]; // last-2 debu // Measuring elapsed time -- local variable inside function when macro is used #define ELAPSED1 struct timespec __begin; elapsed_ms(&__begin, HAMLIB_ELAPSED_SET); -#define ELAPSED2 rig_debug(RIG_DEBUG_TRACE, "%.*s%d:%s: elapsed=%.0lfms\n", rig->state.depth, spaces(), rig->state.depth, __func__, elapsed_ms(&__begin, HAMLIB_ELAPSED_GET)); +#define ELAPSED2 rig_debug(RIG_DEBUG_TRACE, "%.*s%d:%s: elapsed=%.0lfms\n", rig->state.depth-1, spaces(), rig->state.depth, __func__, elapsed_ms(&__begin, HAMLIB_ELAPSED_GET)); // use this instead of snprintf for automatic detection of buffer limit #define SNPRINTF(s,n,...) { snprintf(s,n,##__VA_ARGS__);if (strlen(s) > n-1) fprintf(stderr,"****** %s(%d): buffer overflow ******\n", __func__, __LINE__); } diff --git a/include/hamlib/riglist.h b/include/hamlib/riglist.h index f231f38b8..b186f2308 100644 --- a/include/hamlib/riglist.h +++ b/include/hamlib/riglist.h @@ -198,6 +198,7 @@ #define RIG_MODEL_LAB599_TX500 RIG_MAKE_MODEL(RIG_KENWOOD,50) #define RIG_MODEL_SDRUNO RIG_MAKE_MODEL(RIG_KENWOOD,51) #define RIG_MODEL_QRPLABS RIG_MAKE_MODEL(RIG_KENWOOD,52) +#define RIG_MODEL_FX4 RIG_MAKE_MODEL(RIG_KENWOOD,53) /* * Icom diff --git a/lib/Makefile.am b/lib/Makefile.am index ccfac19b0..323a00e74 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,4 +1,4 @@ -EXTRA_DIST = getopt.c getopt.h getopt_long.c usleep.c \ +EXTRA_DIST = getopt.c getopt.h getopt_long.c usleep.c \ termios.c win32termios.h gettimeofday.c getaddrinfo.c noinst_LTLIBRARIES = libmisc.la diff --git a/rigs/anytone/anytone.c b/rigs/anytone/anytone.c index 43298c2f5..da7452d7f 100644 --- a/rigs/anytone/anytone.c +++ b/rigs/anytone/anytone.c @@ -46,6 +46,7 @@ // --------------------------------------------------------------------------- #include "anytone.h" +int anytone_transaction(RIG *rig, unsigned char *cmd, int cmd_len, unsigned char *reply, int reply_len, int expected_len); DECLARE_INITRIG_BACKEND(anytone) { @@ -122,8 +123,8 @@ void *anytone_thread(void *vrig) while (p->runflag) { -// char c [] = { 0x2b, 0x41, 0x44, 0x41, 0x54, 0x41, 0x3a, 0x30, 0x30, 0x2c, 0x30, 0x30, 0x31, 0x0d, 0x0a, 0x61, 0x0d, 0x0a }; - char *c = "+ADATA:00,001\r\na\r\n"; + char c[64]; + SNPRINTF(c, sizeof(c), "+ADATA:00,001\r\na\r\n"); MUTEX_LOCK(p->priv.mutex); // if we don't have CACHE debug enabled then we only show WARN and higher for this rig enum rig_debug_level_e debug_level_save; @@ -135,17 +136,16 @@ void *anytone_thread(void *vrig) } write_block(&rig->state.rigport, (unsigned char *)c, strlen(c)); - hl_usleep(100 * 1000); + char buf[32]; + read_block(&rig->state.rigport, (unsigned char*)buf, 22); if (rig_need_debug(RIG_DEBUG_CACHE) == 0) { rig_set_debug(debug_level_save); } - rig_flush(&rig->state.rigport); MUTEX_UNLOCK(p->priv.mutex); hl_usleep(1000 * 1000); // 1-second loop - } return NULL; @@ -155,7 +155,7 @@ void *anytone_thread(void *vrig) // anytone_send // --------------------------------------------------------------------------- int anytone_send(RIG *rig, - char *cmd, int cmd_len) + unsigned char *cmd, int cmd_len) { int retval = RIG_OK; struct rig_state *rs = &rig->state; @@ -197,10 +197,10 @@ int anytone_receive(RIG *rig, unsigned char *buf, int buf_len, int expected) // --------------------------------------------------------------------------- // anytone_transaction // --------------------------------------------------------------------------- -int anytone_transaction(RIG *rig, char *cmd, int cmd_len, int expected_len) +int anytone_transaction(RIG *rig, unsigned char *cmd, int cmd_len, unsigned char *reply, int reply_len, int expected_len) { int retval = RIG_OK; - anytone_priv_data_t *p = rig->state.priv; + //anytone_priv_data_t *p = rig->state.priv; ENTERFUNC; @@ -214,16 +214,8 @@ int anytone_transaction(RIG *rig, char *cmd, int cmd_len, int expected_len) if (retval == RIG_OK && expected_len != 0) { - unsigned char *buf = calloc(64, 1); - int len = anytone_receive(rig, buf, 64, expected_len); + int len = anytone_receive(rig, reply, reply_len, expected_len); rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): rx len=%d\n", __func__, __LINE__, len); - - if (buf[0] == 0xaa && buf[1] == 0x53) - { - p->vfo_curr = buf[8] == 0x00 ? RIG_VFO_A : RIG_VFO_B; - } - - free(buf); } } @@ -238,7 +230,6 @@ int anytone_init(RIG *rig) int retval = RIG_OK; ENTERFUNC; - // Check Params if (rig != NULL) { @@ -296,20 +287,21 @@ int anytone_open(RIG *rig) int retval = RIG_OK; ENTERFUNC; - // Check Params if (rig == NULL) { retval = -RIG_EARG; } - else - { - // grace period for the radio to be there - // hl_usleep(500); // do we need this for AnyTone? - - // can we ask for any information? Maybe just toggle A/B? - } + unsigned char cmd[] = { 0x2B,0x41,0x44,0x41,0x54,0x41,0x3A,0x30,0x30,0x2C,0x30,0x30,0x31,0x0d,0x0a,'a',0x0d,0x0a }; + write_block(&rig->state.rigport, cmd, sizeof(cmd)); + hl_usleep(500 * 1000); + char cmd2[64]; + SNPRINTF(cmd2, sizeof(cmd2), "+ADATA:00,016\r\n%cD578UV COM MODE\r\n", 0x01); + write_block(&rig->state.rigport, (unsigned char *)cmd2, strlen(cmd2)); + SNPRINTF(cmd2, sizeof(cmd2), "+ADATA:00,000\r\n"); + unsigned char reply[512]; + anytone_transaction(rig, (unsigned char*)cmd2, strlen(cmd2), reply, sizeof(reply), strlen(cmd2)); pthread_t id; // will start the keep alive @@ -322,12 +314,6 @@ int anytone_open(RIG *rig) RETURNFUNC(-RIG_EINTERNAL); } - hl_usleep(500 * 1000); - char *cmd = "+ADATA:00,016\r\n"; - - anytone_transaction(rig, cmd, strlen(cmd), 21); - - RETURNFUNC(retval); } @@ -340,7 +326,7 @@ int anytone_close(RIG *rig) ENTERFUNC; char *cmd = "+ADATA:00,000\r\n"; - anytone_transaction(rig, cmd, strlen(cmd), 0); + anytone_transaction(rig, (unsigned char*)cmd, strlen(cmd), NULL, 0, 0); RETURNFUNC(retval); } @@ -351,10 +337,11 @@ int anytone_close(RIG *rig) int anytone_get_vfo(RIG *rig, vfo_t *vfo) { int retval = RIG_OK; - char cmd[] = { 0x41, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x06 }; + //char cmd[] = { 0x41, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x06 }; + //char cmd[] = { "+ADATA06:00,001",0x41, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x06 }; + unsigned char cmd[] = { 0x2b,0x41,0x44,0x41,0x54,0x41,0x3a,0x30,0x30,0x2c,0x30,0x30,0x36,0x0d,0x0a,0x04,0x05,0x00,0x00,0x00,0x00,0x0d,0x0a }; ENTERFUNC; - // Check Params if (rig == NULL) { @@ -364,7 +351,15 @@ int anytone_get_vfo(RIG *rig, vfo_t *vfo) { anytone_priv_data_ptr p = (anytone_priv_data_ptr) rig->state.priv; - anytone_transaction(rig, cmd, sizeof(cmd), 17); + unsigned char reply[512]; + anytone_transaction(rig, cmd, sizeof(cmd), reply, sizeof(reply), 114); + if (reply[113] == 0x9b) *vfo = RIG_VFO_A; + else if (reply[113] == 0x9c) *vfo = RIG_VFO_B; + else + { + *vfo = RIG_VFO_A; // default to VFOA + rig_debug(RIG_DEBUG_ERR, "%s: unknown vfo=0x%02x\n", __func__, reply[113]); + } *vfo = p->vfo_curr; } @@ -378,57 +373,15 @@ int anytone_get_vfo(RIG *rig, vfo_t *vfo) int anytone_set_vfo(RIG *rig, vfo_t vfo) { int retval = RIG_OK; - anytone_priv_data_t *p = rig->state.priv; + //anytone_priv_data_t *p = rig->state.priv; ENTERFUNC; - // Check Params + RETURNFUNC(RIG_OK); if (rig == NULL) { retval = -RIG_EARG; } - else - { - // can we use status reponse to deteremin which VFO is active? - if (vfo == RIG_VFO_A) - { - char buf1[8] = { 0x41, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x06 }; - char buf2[8] = { 0x41, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x06 }; - MUTEX_LOCK(p->mutex); - anytone_transaction(rig, buf1, 8, 0); - hl_usleep(100 * 1000); - anytone_transaction(rig, buf2, 8, 0); - // we expect 16 bytes coming back - unsigned char reply[16]; - int nbytes = read_block(&rig->state.rigport, reply, 16); - - rig_debug(RIG_DEBUG_ERR, "%s(%d): nbytes=%d\n", __func__, __LINE__, nbytes); - - if (reply[8] == 0x00) { p->vfo_curr = RIG_VFO_A; } - else { p->vfo_curr = RIG_VFO_B; } - - MUTEX_UNLOCK(p->mutex); - } - else - { - char buf1[8] = { 0x41, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x06 }; - char buf2[8] = { 0x41, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x06 }; - MUTEX_LOCK(p->mutex); - anytone_transaction(rig, buf1, 8, 0); - hl_usleep(100 * 1000); - anytone_transaction(rig, buf2, 8, 0); - unsigned char reply[17]; - int nbytes = read_block(&rig->state.rigport, reply, 17); - rig_debug(RIG_DEBUG_ERR, "%s(%d): nbytes=%d\n", __func__, __LINE__, nbytes); - - if (reply[8] == 0x00) { p->vfo_curr = RIG_VFO_A; } - else { p->vfo_curr = RIG_VFO_B; } - - MUTEX_UNLOCK(p->mutex); - } - - } - RETURNFUNC(retval); } @@ -440,7 +393,6 @@ int anytone_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) int retval = RIG_OK; ENTERFUNC; - // Check Params if (rig == NULL) { @@ -470,12 +422,15 @@ int anytone_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) else { //char buf[8] = { 0x41, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x06 }; - char *cmd = "+ADATA:00,001\r\na\r\n"; + unsigned char ptton[] = { 0x2B,0x41,0x44,0x41,0x54,0x41,0x3A,0x30,0x30,0x2C,0x30,0x30,0x31,0x0d,0x0a,0x61,0x0d,0x0a }; + unsigned char pttoff[] = { 0x2B,0x41,0x44,0x41,0x54,0x41,0x3A,0x30,0x30,0x2C,0x30,0x32,0x33,0x0d,0x0a,0x56,0x0d,0x0a }; + void *pttcmd = ptton; + if (!ptt) pttcmd = pttoff; - if (!ptt) { cmd = "+ADATA:00,023\r\nV\r\n"; } + //if (!ptt) { cmd = " (unsigned char*)+ADATA:00,023\r\nV\r\n"; } MUTEX_LOCK(p->mutex); - anytone_transaction(rig, cmd, strlen(cmd), 1); + anytone_transaction(rig, pttcmd, sizeof(ptton), NULL, 0, 0); anytone_priv_data_t *p = rig->state.priv; p->ptt = ptt; MUTEX_UNLOCK(p->mutex); @@ -487,47 +442,65 @@ int anytone_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) int anytone_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char cmd[32]; + int retval; - if (vfo == RIG_VFO_A) - { - SNPRINTF(cmd, sizeof(cmd), "+ADATA:00,119\r\n"); - cmd[15] = 0x04; - cmd[16] = 0x2c; - cmd[17] = 0x07; - cmd[18] = 0x00; - cmd[19] = 0x00; - cmd[21] = 0x00; - cmd[22] = 0x00; - cmd[23] = 0x0d; - cmd[24] = 0x0a; - } - else - { - SNPRINTF(cmd, sizeof(cmd), "+ADATA:00,006\r\n"); - cmd[15] = 0x04; - cmd[16] = 0x2d; - cmd[17] = 0x07; - cmd[18] = 0x00; - cmd[19] = 0x00; - cmd[21] = 0x00; - cmd[22] = 0x00; - cmd[23] = 0x0d; - cmd[24] = 0x0a; - } + SNPRINTF(cmd, sizeof(cmd), "+ADATA:00,006\r\n"); + cmd[15] = 0x04; + cmd[16] = 0x2c; + cmd[17] = 0x07; + cmd[18] = 0x00; + cmd[19] = 0x00; + cmd[21] = 0x00; + cmd[22] = 0x00; + cmd[23] = 0x0d; + cmd[24] = 0x0a; - write_block(&rig->state.rigport, (unsigned char *)cmd, 25); - unsigned char buf[64]; - int retval = read_block(&rig->state.rigport, buf, 135); + if (vfo == RIG_VFO_B) { cmd[16] = 0x2d; } - if (retval == 135) + int retry = 2; + MUTEX_LOCK(p->priv.mutex); + rig_flush(&rig->state.rigport); + + do { - *freq = buf[17] * 10e7 + buf[18] * 10e5 + buf[19] * 10e3 + buf[20] * 10e1; - retval = RIG_OK; + write_block(&rig->state.rigport, (unsigned char *)cmd, 25); + unsigned char buf[512]; + retval = read_block(&rig->state.rigport, buf, 138); + + if (retval == 138) + { + *freq = from_bcd_be(&buf[17], 8) * 10; + rig_debug(RIG_DEBUG_VERBOSE, "%s: VFOA freq=%g\n", __func__, *freq); + retval = RIG_OK; + } } + while (retval != 138 && --retry > 0); + MUTEX_UNLOCK(p->priv.mutex); return RIG_OK; } +int anytone_set_freq(RIG *rig, vfo_t vfo, freq_t freq) +{ + char cmd[64]; + if (vfo == RIG_VFO_A) + snprintf(cmd, sizeof(cmd), "ADATA:00,005\r\n%c%c%c%c\r\n", 2, 0, 0, 0); + else + snprintf(cmd, sizeof(cmd), "ADATA:00,005\r\n%c%c%c%c\r\n", 1, 0, 0, 0); + MUTEX_LOCK(p->priv.mutex); + rig_flush(&rig->state.rigport); + write_block(&rig->state.rigport, (unsigned char*) cmd, 20); + unsigned char backend[] = { 0x2f, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0x15, 0x50, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x09, 0x00, 0x00, 0x0d, 0x0a}; + snprintf(cmd, sizeof(cmd), "ADATA:00,023\r\n"); + int bytes = strlen(cmd) + sizeof(backend); + memcpy(&cmd[15], backend, sizeof(backend)); + hl_usleep(10*1000); + write_block(&rig->state.rigport, (unsigned char*)cmd, bytes); + MUTEX_UNLOCK(p->priv.mutex); + + return -RIG_ENIMPL; +} + // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- diff --git a/rigs/anytone/anytone.h b/rigs/anytone/anytone.h index 1b1c6d0c4..7185549fa 100644 --- a/rigs/anytone/anytone.h +++ b/rigs/anytone/anytone.h @@ -42,6 +42,7 @@ extern int anytone_get_ptt(RIG *rig, vfo_t vfo,ptt_t *ptt); extern int anytone_set_vfo(RIG *rig, vfo_t vfo); extern int anytone_get_vfo(RIG *rig, vfo_t *vfo); +extern int anytone_set_freq(RIG *rig, vfo_t vfo, freq_t freq); extern int anytone_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); #endif /* _ANYTONE_H */ diff --git a/rigs/anytone/d578.c b/rigs/anytone/d578.c index e16cbb3d4..2493e8ab5 100644 --- a/rigs/anytone/d578.c +++ b/rigs/anytone/d578.c @@ -84,6 +84,7 @@ const struct rig_caps anytone_d578_caps = .get_ptt = anytone_get_ptt, .set_ptt = anytone_set_ptt, + .set_freq = anytone_set_freq, .get_freq = anytone_get_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS diff --git a/rigs/dummy/dummy.c b/rigs/dummy/dummy.c index e19130341..076d60657 100644 --- a/rigs/dummy/dummy.c +++ b/rigs/dummy/dummy.c @@ -2240,7 +2240,7 @@ int dummy_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, #define DUMMY_VFO_OP 0x7ffffffUL /* All possible VFO OPs */ #define DUMMY_SCAN 0x7ffffffUL /* All possible scan OPs */ -#define DUMMY_VFOS (RIG_VFO_TX|RIG_VFO_TX|RIG_VFO_A|RIG_VFO_B|RIG_VFO_C|RIG_VFO_MEM|RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MAIN_A|RIG_VFO_MAIN_B|RIG_VFO_SUB_A|RIG_VFO_SUB_B) +#define DUMMY_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_C|RIG_VFO_MEM|RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MAIN_A|RIG_VFO_MAIN_B|RIG_VFO_SUB_A|RIG_VFO_SUB_B) #define DUMMY_MODES (RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_RTTY | \ RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_WFM | \ @@ -2279,7 +2279,7 @@ struct rig_caps dummy_caps = RIG_MODEL(RIG_MODEL_DUMMY), .model_name = "Dummy", .mfg_name = "Hamlib", - .version = "20221128.0", + .version = "20230611.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, diff --git a/rigs/dummy/flrig.c b/rigs/dummy/flrig.c index 8a77cc69e..bc5964043 100644 --- a/rigs/dummy/flrig.c +++ b/rigs/dummy/flrig.c @@ -138,7 +138,7 @@ const struct rig_caps flrig_caps = RIG_MODEL(RIG_MODEL_FLRIG), .model_name = "FLRig", .mfg_name = "FLRig", - .version = "20221109.0", + .version = "20230703.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, @@ -996,12 +996,12 @@ static int flrig_open(RIG *rig) else if (streq(p, "LSB-D2")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "LSB-D3")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "NFM")) { modeMapAdd(&modes, RIG_MODE_FMN, p); } - else if (streq(p, "PKT")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } + else if (streq(p, "PKT")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "PKT-FM")) { modeMapAdd(&modes, RIG_MODE_PKTFM, p); } - else if (streq(p, "PKT-L")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } - else if (streq(p, "PKT-U")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } - else if (streq(p, "PKT(L)")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } - else if (streq(p, "PKT(U)")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } + else if (streq(p, "PKT-L")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } + else if (streq(p, "PKT-U")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } + else if (streq(p, "PKT(L)")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } + else if (streq(p, "PKT(U)")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "PSK")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "PSK-L")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "PSK-R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } diff --git a/rigs/dummy/netrigctl.c b/rigs/dummy/netrigctl.c index a79eeaaa2..baf77ee94 100644 --- a/rigs/dummy/netrigctl.c +++ b/rigs/dummy/netrigctl.c @@ -843,18 +843,17 @@ static int netrigctl_open(RIG *rig) { double min, max, step; sscanf(p, "%*d=%lf,%lf,%lf", &min, &max, &step); - rs->level_gran[i].min.f = min; - rs->level_gran[i].max.f = max; - rs->level_gran[i].step.f = step; + rig->caps->level_gran[i].min.f = rs->level_gran[i].min.f = min; + rig->caps->level_gran[i].max.f = rs->level_gran[i].max.f = max; + rig->caps->level_gran[i].step.f = rs->level_gran[i].step.f = step; } else { int min, max, step; sscanf(p, "%*d=%d,%d,%d", &min, &max, &step); - rs->level_gran[i].min.i = min; - rs->level_gran[i].max.i = max; - rs->level_gran[i].step.i = step; - + rig->caps->level_gran[i].min.i = rs->level_gran[i].min.i = min; + rig->caps->level_gran[i].max.i = rs->level_gran[i].max.i = max; + rig->caps->level_gran[i].step.i = rs->level_gran[i].step.i = step; } p = strtok(NULL, ";"); @@ -872,17 +871,17 @@ static int netrigctl_open(RIG *rig) { double min, max, step; sscanf(p, "%*d=%lf,%lf,%lf", &min, &max, &step); - rs->parm_gran[i].min.f = min; - rs->parm_gran[i].max.f = max; - rs->parm_gran[i].step.f = step; + rig->caps->parm_gran[i].min.f = rs->parm_gran[i].min.f = min; + rig->caps->parm_gran[i].max.f = rs->parm_gran[i].max.f = max; + rig->caps->parm_gran[i].step.f = rs->parm_gran[i].step.f = step; } else { int min, max, step; sscanf(p, "%*d=%d,%d,%d", &min, &max, &step); - rs->parm_gran[i].min.i = min; - rs->parm_gran[i].max.i = max; - rs->parm_gran[i].step.i = step; + rig->caps->parm_gran[i].min.i = rs->parm_gran[i].min.i = min; + rig->caps->parm_gran[i].max.i = rs->parm_gran[i].max.i = max; + rig->caps->parm_gran[i].step.i = rs->parm_gran[i].step.i = step; } p = strtok(NULL, ";"); } @@ -2810,7 +2809,7 @@ struct rig_caps netrigctl_caps = RIG_MODEL(RIG_MODEL_NETRIGCTL), .model_name = "NET rigctl", .mfg_name = "Hamlib", - .version = "20230602.0", + .version = "20230617.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, diff --git a/rigs/icom/frame.c b/rigs/icom/frame.c index 32f096048..5b9e9bc81 100644 --- a/rigs/icom/frame.c +++ b/rigs/icom/frame.c @@ -733,7 +733,6 @@ int rig2icom_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, void icom2rig_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *width) { - ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: mode=0x%02x, pd=%d\n", __func__, md, pd); *width = RIG_PASSBAND_NORMAL; @@ -864,6 +863,5 @@ void icom2rig_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, default: rig_debug(RIG_DEBUG_ERR, "icom: Unsupported Icom mode width %#.2x\n", pd); } - } diff --git a/rigs/icom/ic7300.c b/rigs/icom/ic7300.c index 182b1c258..16e6bb8a5 100644 --- a/rigs/icom/ic7300.c +++ b/rigs/icom/ic7300.c @@ -910,7 +910,7 @@ struct rig_caps ic9700_caps = RIG_MODEL(RIG_MODEL_IC9700), .model_name = "IC-9700", .mfg_name = "Icom", - .version = BACKEND_VER ".13", + .version = BACKEND_VER ".14", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, @@ -1169,7 +1169,7 @@ struct rig_caps ic9700_caps = .get_freq = icom_get_freq, .set_mode = icom_set_mode_with_data, .get_mode = icom_get_mode_with_data, - .get_vfo = icom_get_vfo, +// .get_vfo = icom_get_vfo, .set_vfo = ic9700_set_vfo, .set_ant = NULL, .get_ant = NULL, @@ -2108,5 +2108,5 @@ int ic9700_set_vfo(RIG *rig, vfo_t vfo) return -retval; } - return retval; + RETURNFUNC(retval); } diff --git a/rigs/icom/ic7600.c b/rigs/icom/ic7600.c index 9b9e84fdd..f56806fe1 100644 --- a/rigs/icom/ic7600.c +++ b/rigs/icom/ic7600.c @@ -263,7 +263,7 @@ int ic7600_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, return retval; } -const struct rig_caps ic7600_caps = +struct rig_caps ic7600_caps = { RIG_MODEL(RIG_MODEL_IC7600), .model_name = "IC-7600", diff --git a/rigs/icom/ic7610.c b/rigs/icom/ic7610.c index 71957e762..26e4e8961 100644 --- a/rigs/icom/ic7610.c +++ b/rigs/icom/ic7610.c @@ -345,12 +345,12 @@ int ic7610_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, return retval; } -const struct rig_caps ic7610_caps = +struct rig_caps ic7610_caps = { RIG_MODEL(RIG_MODEL_IC7610), .model_name = "IC-7610", .mfg_name = "Icom", - .version = BACKEND_VER ".14", + .version = BACKEND_VER ".15", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, @@ -545,7 +545,7 @@ const struct rig_caps ic7610_caps = .set_mode = icom_set_mode_with_data, .get_mode = icom_get_mode_with_data, .set_vfo = icom_set_vfo, - .get_vfo = icom_get_vfo, +// .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, diff --git a/rigs/icom/ic785x.c b/rigs/icom/ic785x.c index 0bb1e6a59..46e180617 100644 --- a/rigs/icom/ic785x.c +++ b/rigs/icom/ic785x.c @@ -242,7 +242,7 @@ const struct rig_caps ic785x_caps = RIG_MODEL(RIG_MODEL_IC785x), .model_name = "IC-7850/7851", .mfg_name = "Icom", - .version = BACKEND_VER ".7", + .version = BACKEND_VER ".8", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, @@ -438,7 +438,7 @@ const struct rig_caps ic785x_caps = .set_mode = icom_set_mode_with_data, .get_mode = icom_get_mode_with_data, .set_vfo = icom_set_vfo, - .get_vfo = icom_get_vfo, +// .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, diff --git a/rigs/icom/icom.c b/rigs/icom/icom.c index 803b1cdb7..b16a3079e 100644 --- a/rigs/icom/icom.c +++ b/rigs/icom/icom.c @@ -684,34 +684,35 @@ int icom_init(RIG *rig) priv->filter = RIG_PASSBAND_NOCHANGE; priv->x25cmdfails = -1; priv->x1cx03cmdfails = 0; + priv->serial_USB_echo_off = -1; // unknown at this point // we can add rigs here that will never use the 0x25 cmd // some like the 751 don't even reject the command and have to time out if ( - rig->caps->rig_model == RIG_MODEL_IC275 - || rig->caps->rig_model == RIG_MODEL_IC375 - || rig->caps->rig_model == RIG_MODEL_IC706 - || rig->caps->rig_model == RIG_MODEL_IC706MKII - || rig->caps->rig_model == RIG_MODEL_IC706MKIIG - || rig->caps->rig_model == RIG_MODEL_IC751 - || rig->caps->rig_model == RIG_MODEL_X5105 - || rig->caps->rig_model == RIG_MODEL_IC1275 - || rig->caps->rig_model == RIG_MODEL_IC746 - || rig->caps->rig_model == RIG_MODEL_IC756 - || rig->caps->rig_model == RIG_MODEL_IC756PRO - || rig->caps->rig_model == RIG_MODEL_IC756PROII - || rig->caps->rig_model == RIG_MODEL_IC756PROIII - || rig->caps->rig_model == RIG_MODEL_IC746PRO - || rig->caps->rig_model == RIG_MODEL_IC756 - || rig->caps->rig_model == RIG_MODEL_IC7000 - || rig->caps->rig_model == RIG_MODEL_IC7100 - || rig->caps->rig_model == RIG_MODEL_IC7200 - || rig->caps->rig_model == RIG_MODEL_IC7700 - || rig->caps->rig_model == RIG_MODEL_IC821H - || rig->caps->rig_model == RIG_MODEL_IC910 - || rig->caps->rig_model == RIG_MODEL_IC2730 - || rig->caps->rig_model == RIG_MODEL_ID5100 - || rig->caps->rig_model == RIG_MODEL_IC9100 + RIG_IS_IC275 + || RIG_IS_IC375 + || RIG_IS_IC706 + || RIG_IS_IC706MKII + || RIG_IS_IC706MKIIG + || RIG_IS_IC751 + || RIG_IS_X5105 + || RIG_IS_IC1275 + || RIG_IS_IC746 + || RIG_IS_IC756 + || RIG_IS_IC756PRO + || RIG_IS_IC756PROII + || RIG_IS_IC756PROIII + || RIG_IS_IC746PRO + || RIG_IS_IC756 + || RIG_IS_IC7000 + || RIG_IS_IC7100 + || RIG_IS_IC7200 + || RIG_IS_IC7700 + || RIG_IS_IC821H + || RIG_IS_IC910 + || RIG_IS_IC2730 + || RIG_IS_ID5100 + || RIG_IS_IC9100 ) { priv->x25cmdfails = 1; @@ -960,13 +961,13 @@ static vfo_t icom_current_vfo(RIG *rig) // some rigs like IC9700 cannot do 0x25 0x26 command in satmode static void icom_satmode_fix(RIG *rig, int satmode) { - if (rig->caps->rig_model == RIG_MODEL_IC9700) + if (RIG_IS_IC9700) { rig_debug(RIG_DEBUG_VERBOSE, "%s: toggling IC9700 targetable for satmode=%d\n", __func__, satmode); - if (satmode) { rig->caps->targetable_vfo = 0; } - else { rig->caps->targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE; } + if (satmode) { rig->caps->targetable_vfo = rig->state.targetable_vfo = 0; } + else { rig->caps->targetable_vfo = rig->state.targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE; } } } @@ -1341,7 +1342,7 @@ int icom_set_freq(RIG *rig, vfo_t vfo, freq_t freq) freq_len = priv->civ_731_mode ? 4 : 5; - if (rig->caps->rig_model == RIG_MODEL_IC905) { freq_len = 6; } + if (RIG_IS_IC905) { freq /= 10; freq_len = 6; } /* * to_bcd requires nibble len @@ -1372,6 +1373,11 @@ int icom_set_freq(RIG *rig, vfo_t vfo, freq_t freq) HAMLIB_TRACE; subcmd = 0x01; // get unselected VFO } + if (RIG_IS_IC7600) + { // the 7600/7610 do it different 0=Main, 1=Sub -- maybe other Icoms will start doing this too + subcmd = 0; + if (vfo & RIG_VFO_B || vfo & RIG_VFO_SUB) subcmd = 1; + } cmd = 0x25; retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, ackbuf, @@ -1520,14 +1526,16 @@ int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) rig_debug(RIG_DEBUG_VERBOSE, "%s called for %s, curr_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo)); + rs = &rig->state; priv = (struct icom_priv_data *) rs->priv; + if (priv->serial_USB_echo_off == -1) icom_get_usb_echo_off(rig); cmd = C_RD_FREQ; subcmd = -1; if (vfo == RIG_VFO_MEM && (priv->civ_731_mode - || rig->caps->rig_model == RIG_MODEL_IC706)) + || RIG_IS_IC706)) { rig_debug(RIG_DEBUG_TRACE, "%s: VFO=MEM so turning off civ_731\n", __func__); civ_731_mode = 1; @@ -1656,6 +1664,20 @@ int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) subcmd2 = 0x01; // get unselected VFO } + // Rigs like IC-7600 new firmware has 0x25 and 0x26 + // So if this succeeds we'll assume all such rigs are targetable freq & mode + int targetable_vfo_save = rig->caps->targetable_vfo; + if ((RIG_IS_IC7600 || RIG_IS_IC7610) && priv->x25cmdfails <= 0) + { // the 7600/7610 do it different 0=Main, 1=Sub -- maybe other Icoms will start doing this too + subcmd2 = 0; + if (vfo & RIG_VFO_B || vfo & RIG_VFO_SUB) subcmd2 = 1; + if (priv->x25cmdfails < 0) + { // we'll test this once to support the newer firmware + rig_debug(RIG_DEBUG_VERBOSE, "%s: TARGETABLE_FREQ and TARGETABLE_MODE enabled for testing\n", __func__); + rig->caps->targetable_vfo = rig->state.targetable_vfo |= RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE; + } + } + retval = icom_transaction(rig, cmd2, subcmd2, NULL, 0, freqbuf, &freq_len); if (retval == RIG_OK) @@ -1667,6 +1689,11 @@ int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) if (priv->x25cmdfails < 0) { priv->x25cmdfails = 1; + if (RIG_IS_IC7600 || RIG_IS_IC7610) + { + rig->caps->targetable_vfo = targetable_vfo_save; + rig_debug(RIG_DEBUG_VERBOSE, "%s: TARGETABLE_FREQ and TARGETABLE_MODE disabled -- older firmare likely\n", __func__); + } } rig_debug(RIG_DEBUG_TRACE, @@ -1762,6 +1789,8 @@ int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) if (freq_len == 3) { *freq *= 10000; } // 3-byte freq for ID5100 is in 10000Hz units so convert to Hz +if (RIG_IS_IC905) { *freq *= 10; } + if (vfo == RIG_VFO_MEM && civ_731_mode) { priv->civ_731_mode = 1; } switch (vfo) @@ -2154,6 +2183,11 @@ static int icom_set_mode_x26(RIG *rig, vfo_t vfo, rmode_t mode, int datamode, { subcmd2 = 0x01; // get unselected VFO } + if (RIG_IS_IC7600 || RIG_IS_IC7610) + { // the 7600/7610 do it different 0=Main, 1=Sub -- maybe other Icoms will start doing this too + subcmd2 = 0; + if (vfo & RIG_VFO_B || vfo & RIG_VFO_SUB) subcmd2 = 1; + } buf[0] = mode; buf[1] = datamode; @@ -2188,19 +2222,19 @@ int icom_set_mode_with_data(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t twidth; //struct icom_priv_data *priv = (struct icom_priv_data *) rig->state.priv; unsigned char dm_sub_cmd = - rig->caps->rig_model == RIG_MODEL_IC7200 ? 0x04 : S_MEM_DATA_MODE; - int filter_byte = rig->caps->rig_model == RIG_MODEL_IC7100 - || rig->caps->rig_model == RIG_MODEL_IC7200 - || rig->caps->rig_model == RIG_MODEL_IC7300 - || rig->caps->rig_model == RIG_MODEL_IC7600 - || rig->caps->rig_model == RIG_MODEL_IC7610 - || rig->caps->rig_model == RIG_MODEL_IC7700 - || rig->caps->rig_model == RIG_MODEL_IC7800 - || rig->caps->rig_model == RIG_MODEL_IC785x - || rig->caps->rig_model == RIG_MODEL_IC9100 - || rig->caps->rig_model == RIG_MODEL_IC9700 - || rig->caps->rig_model == RIG_MODEL_IC705 - || rig->caps->rig_model == RIG_MODEL_X6100; + RIG_IS_IC7200 ? 0x04 : S_MEM_DATA_MODE; + int filter_byte = RIG_IS_IC7100 + || RIG_IS_IC7200 + || RIG_IS_IC7300 + || RIG_IS_IC7600 + || RIG_IS_IC7610 + || RIG_IS_IC7700 + || RIG_IS_IC7800 + || RIG_IS_IC785X + || RIG_IS_IC9100 + || RIG_IS_IC9700 + || RIG_IS_IC705 + || RIG_IS_X6100; ENTERFUNC; @@ -2215,13 +2249,6 @@ int icom_set_mode_with_data(RIG *rig, vfo_t vfo, rmode_t mode, RETURNFUNC(retval); } - // do we really need/want to skip if width == twidth? - if ((width == RIG_PASSBAND_NOCHANGE) || (width == twidth)) - { - rig_debug(RIG_DEBUG_TRACE, "%s: width not changing..keeping filter selection\n", __func__); - RETURNFUNC(RIG_OK); - } - // looks like we need to change it switch (mode) @@ -2266,7 +2293,8 @@ int icom_set_mode_with_data(RIG *rig, vfo_t vfo, rmode_t mode, hl_usleep(50 * 1000); // pause for possible transceive message which we'll flush - if (RIG_OK == retval) + // we + if (RIG_OK == retval && mode != tmode) { unsigned char datamode[2]; unsigned char mode_icom; // Not used, we only need the width @@ -2341,6 +2369,14 @@ int icom_set_mode_with_data(RIG *rig, vfo_t vfo, rmode_t mode, } } + // do we really need/want to skip if width == twidth? + if ((width == RIG_PASSBAND_NOCHANGE) || (width == twidth)) + { + rig_debug(RIG_DEBUG_TRACE, "%s: width not changing..keeping filter selection\n", + __func__); + RETURNFUNC(RIG_OK); + } + icom_set_dsp_flt(rig, mode, width); RETURNFUNC(retval); @@ -2395,12 +2431,12 @@ int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) /* IC-375, IC-731, IC-726, IC-735, IC-910, IC-7000 don't support passband data */ /* IC-726 & IC-475A/E also limited support - only on CW */ /* TODO: G4WJS CW wide/narrow are possible with above two radios */ - if (priv->civ_731_mode || rig->caps->rig_model == RIG_MODEL_OS456 - || rig->caps->rig_model == RIG_MODEL_IC375 - || rig->caps->rig_model == RIG_MODEL_IC726 - || rig->caps->rig_model == RIG_MODEL_IC475 - || rig->caps->rig_model == RIG_MODEL_IC910 - || rig->caps->rig_model == RIG_MODEL_IC7000) + if (priv->civ_731_mode || RIG_IS_OS456 + || RIG_IS_IC375 + || RIG_IS_IC726 + || RIG_IS_IC475 + || RIG_IS_IC910 + || RIG_IS_IC7000) { icmode_ext = -1; } @@ -2689,13 +2725,13 @@ int icom_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) /* Likewise, don't ask if we happen to be an Omni VI Plus */ /* Likewise, don't ask if we happen to be an IC-R30 */ /* Likewise, don't ask if we happen to be an IC-706* */ - if ((rig->caps->rig_model == RIG_MODEL_IC910) || - (rig->caps->rig_model == RIG_MODEL_OMNIVIP) || - (rig->caps->rig_model == RIG_MODEL_IC706) || - (rig->caps->rig_model == RIG_MODEL_IC706MKII) || - (rig->caps->rig_model == RIG_MODEL_IC706MKIIG) || - (rig->caps->rig_model == RIG_MODEL_IC756) || - (rig->caps->rig_model == RIG_MODEL_ICR30)) + if ((RIG_IS_IC910) || + (RIG_IS_OMNIVIP) || + (RIG_IS_IC706) || + (RIG_IS_IC706MKII) || + (RIG_IS_IC706MKIIG) || + (RIG_IS_IC756) || + (RIG_IS_ICR30)) { RETURNFUNC2(RIG_OK); } @@ -2857,7 +2893,7 @@ int icom_set_vfo(RIG *rig, vfo_t vfo) if (rig->state.cache.split == RIG_SPLIT_ON && !rig->state.cache.satmode) { vfo = RIG_VFO_A; } // Seems the IC821H reverses Main/Sub when in satmode - if (rig->caps->rig_model == RIG_MODEL_IC821H && rig->state.cache.satmode) { vfo = RIG_VFO_SUB; } + if (RIG_IS_IC821H && rig->state.cache.satmode) { vfo = RIG_VFO_SUB; } } else if ((vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) && VFO_HAS_DUAL) { @@ -2874,7 +2910,7 @@ int icom_set_vfo(RIG *rig, vfo_t vfo) else if (rig->state.cache.split == RIG_SPLIT_ON) { vfo = RIG_VFO_B; } // Seems the IC821H reverses Main/Sub when in satmode - if (rig->caps->rig_model == RIG_MODEL_IC821H && rig->state.cache.satmode) { vfo = RIG_VFO_MAIN; } + if (RIG_IS_IC821H && rig->state.cache.satmode) { vfo = RIG_VFO_MAIN; } } else if ((vfo == RIG_VFO_A || vfo == RIG_VFO_B) && !VFO_HAS_A_B && VFO_HAS_MAIN_SUB) @@ -3340,7 +3376,7 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) } /* convert values to 0 .. 255 range */ - if (rig->caps->rig_model == RIG_MODEL_ICR75) + if (RIG_IS_ICR75) { switch (level) { @@ -3492,7 +3528,7 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) lvl_sc = S_LVL_CWPITCH; /* use 'set mode' call for CWPITCH on IC-R75 */ - if (rig->caps->rig_model == RIG_MODEL_ICR75) + if (RIG_IS_ICR75) { lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_MODE_SLCT; @@ -3622,7 +3658,7 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) break; case RIG_LEVEL_VOXGAIN: - if (rig->caps->rig_model == RIG_MODEL_IC910) + if (RIG_IS_IC910) { /* IC-910H */ lvl_cn = C_CTL_MEM; @@ -3637,7 +3673,7 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) break; case RIG_LEVEL_ANTIVOX: - if (rig->caps->rig_model == RIG_MODEL_IC910) + if (RIG_IS_IC910) { /* IC-910H */ lvl_cn = C_CTL_MEM; @@ -3999,7 +4035,7 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) lvl_sc = S_LVL_CWPITCH; /* use 'set mode' call for CWPITCH on IC-R75 */ - if (rig->caps->rig_model == RIG_MODEL_ICR75) + if (RIG_IS_ICR75) { lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_MODE_SLCT; @@ -4050,7 +4086,7 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) break; case RIG_LEVEL_VOXGAIN: /* IC-910H */ - if (rig->caps->rig_model == RIG_MODEL_IC910) + if (RIG_IS_IC910) { /* IC-910H */ lvl_cn = C_CTL_MEM; @@ -4065,7 +4101,7 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) break; case RIG_LEVEL_ANTIVOX: - if (rig->caps->rig_model == RIG_MODEL_IC910) + if (RIG_IS_IC910) { /* IC-910H */ lvl_cn = C_CTL_MEM; @@ -4497,7 +4533,7 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) } /* convert values from 0 .. 255 range */ - if (rig->caps->rig_model == RIG_MODEL_ICR75) + if (RIG_IS_ICR75) { switch (level) { @@ -5549,7 +5585,7 @@ int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) // we can add rigs we know will never have 0x25 here to skip this check if ((satmode == 0) - && !(rig->caps->rig_model == RIG_MODEL_IC751) + && !(RIG_IS_IC751) ) // only worth trying if not in satmode { int cmd, subcmd, freq_len, retry_save; @@ -5739,7 +5775,7 @@ int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) rig_strvfo(rig->state.current_vfo)); - if (rig->caps->rig_model == RIG_MODEL_IC910) + if (RIG_IS_IC910) { ptt_t ptt; rig_debug(RIG_DEBUG_VERBOSE, "%s: ic910#2\n", __func__); @@ -5796,6 +5832,11 @@ int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) // when transmitting in split mode the split VFO is active subcmd = (rig->state.cache.split && rig->state.cache.ptt) ? 0x00 : 0x01; // get the unselected vfo + if (RIG_IS_IC7600 || RIG_IS_IC7610) + { // the 7600/7610 do it different 0=Main, 1=Sub -- maybe other Icoms will start doing this too + subcmd = 0; + if (vfo & RIG_VFO_B || vfo & RIG_VFO_SUB) subcmd = 1; + } retval = icom_transaction(rig, cmd, subcmd, NULL, 0, ackbuf, &ack_len); @@ -7173,9 +7214,9 @@ int icom_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) break; case RIG_FUNC_DUAL_WATCH: - if ((rig->caps->rig_model == RIG_MODEL_IC9100) - || (rig->caps->rig_model == RIG_MODEL_IC9700) - || (rig->caps->rig_model == RIG_MODEL_ID5100)) + if ((RIG_IS_IC9100) + || (RIG_IS_IC9700) + || (RIG_IS_ID5100)) { fct_cn = C_CTL_FUNC; fct_sc = S_MEM_DUALMODE; @@ -7190,7 +7231,7 @@ int icom_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) break; case RIG_FUNC_SATMODE: - if (rig->caps->rig_model == RIG_MODEL_IC910) + if (RIG_IS_IC910) { // Is the 910 the only one that uses this command? fct_cn = C_CTL_MEM; @@ -7415,8 +7456,8 @@ int icom_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) break; case RIG_FUNC_DUAL_WATCH: - if ((rig->caps->rig_model == RIG_MODEL_IC9100) || - (rig->caps->rig_model == RIG_MODEL_IC9700)) + if ((RIG_IS_IC9100) || + (RIG_IS_IC9700)) { fct_cn = C_CTL_FUNC; fct_sc = S_MEM_DUALMODE; @@ -7430,7 +7471,7 @@ int icom_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) break; case RIG_FUNC_SATMODE: - if (rig->caps->rig_model == RIG_MODEL_IC910) + if (RIG_IS_IC910) { // Is the 910 the only one that uses this command? fct_cn = C_CTL_MEM; @@ -8072,7 +8113,7 @@ int icom_set_powerstat(RIG *rig, powerstat_t status) retval = icom_transaction(rig, C_SET_PWR, pwr_sc, NULL, 0, ackbuf, &ack_len); - if (rig->caps->rig_model == RIG_MODEL_IC7300) + if (RIG_IS_IC7300) { rig_debug(RIG_DEBUG_VERBOSE, "%s: waiting 5 seconds for rig to wake up\n", __func__); @@ -8201,7 +8242,7 @@ int icom_get_powerstat(RIG *rig, powerstat_t *status) *status = RIG_POWER_OFF; // default return until proven otherwise /* r75 has no way to get power status, so fake it */ - if (rig->caps->rig_model == RIG_MODEL_ICR75) + if (RIG_IS_ICR75) { /* getting the mode doesn't work if a memory is blank */ /* so use one of the more innocuous 'set mode' commands instead */ @@ -8220,17 +8261,17 @@ int icom_get_powerstat(RIG *rig, powerstat_t *status) RIG_POWER_ON : RIG_POWER_OFF; } - if (rig->caps->rig_model == RIG_MODEL_IC2730 - || rig->caps->rig_model == RIG_MODEL_IC705 - || rig->caps->rig_model == RIG_MODEL_IC7100 - || rig->caps->rig_model == RIG_MODEL_IC7300 - || rig->caps->rig_model == RIG_MODEL_IC7600 - || rig->caps->rig_model == RIG_MODEL_IC7610 - || rig->caps->rig_model == RIG_MODEL_IC7700 - || rig->caps->rig_model == RIG_MODEL_IC7800 - || rig->caps->rig_model == RIG_MODEL_IC785x - || rig->caps->rig_model == RIG_MODEL_IC9700 - || rig->caps->rig_model == RIG_MODEL_IC905) + if (RIG_IS_IC2730 + || RIG_IS_IC705 + || RIG_IS_IC7100 + || RIG_IS_IC7300 + || RIG_IS_IC7600 + || RIG_IS_IC7610 + || RIG_IS_IC7700 + || RIG_IS_IC7800 + || RIG_IS_IC785X + || RIG_IS_IC9700 + || RIG_IS_IC905) { freq_t freq; short retry_save = rig->state.rigport.retry; @@ -8508,7 +8549,7 @@ int icom_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, { retval = icom_transaction(rig, C_CTL_ANT, -1, NULL, 0, ackbuf, &ack_len); } - else if (rig->caps->rig_model == RIG_MODEL_IC785x) + else if (RIG_IS_IC785X) { unsigned char buf[2]; buf[0] = 0x03; @@ -8823,11 +8864,14 @@ morse_retry: { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); - if (len == 1 && --retry > 0) { + + if (len == 1 && --retry > 0) + { // 50 retries should be around 200ms --plenty of time to clear out some characters - hl_usleep(10*1000); + hl_usleep(10 * 1000); goto morse_retry; } + RETURNFUNC(-RIG_ERJCTED); } diff --git a/rigs/icom/icom.h b/rigs/icom/icom.h index ff260c7a5..6ff4ea050 100644 --- a/rigs/icom/icom.h +++ b/rigs/icom/icom.h @@ -35,7 +35,7 @@ #include #endif -#define BACKEND_VER "20230606" +#define BACKEND_VER "20230707" #define ICOM_IS_ID31 rig_is_model(rig, RIG_MODEL_ID31) #define ICOM_IS_ID51 rig_is_model(rig, RIG_MODEL_ID51) @@ -443,8 +443,8 @@ extern const struct rig_caps ic756pro_caps; extern const struct rig_caps ic756pro2_caps; extern const struct rig_caps ic756pro3_caps; extern const struct rig_caps ic751_caps; -extern const struct rig_caps ic7600_caps; -extern const struct rig_caps ic7610_caps; +extern struct rig_caps ic7600_caps; // need to modify targetable_vfo depending on response to 0x25 cmd +extern struct rig_caps ic7610_caps; extern const struct rig_caps ic761_caps; extern const struct rig_caps ic765_caps; extern const struct rig_caps ic7700_caps; @@ -509,4 +509,88 @@ extern const struct rig_caps x5105_caps; extern const struct rig_caps icr8600_caps; extern const struct rig_caps icr30_caps; +#define RIG_IS_IC1271 (rig->state.rig_model == RIG_MODEL_IC1271) +#define RIG_IS_IC1275 (rig->state.rig_model == RIG_MODEL_IC1275) +#define RIG_IS_IC271 (rig->state.rig_model == RIG_MODEL_IC271) +#define RIG_IS_IC2730 (rig->state.rig_model == RIG_MODEL_IC2730) +#define RIG_IS_IC275 (rig->state.rig_model == RIG_MODEL_IC275) +#define RIG_IS_IC375 (rig->state.rig_model == RIG_MODEL_IC375) +#define RIG_IS_IC471 (rig->state.rig_model == RIG_MODEL_IC471) +#define RIG_IS_IC475 (rig->state.rig_model == RIG_MODEL_IC475) +#define RIG_IS_IC575 (rig->state.rig_model == RIG_MODEL_IC575) +#define RIG_IS_IC7000 (rig->state.rig_model == RIG_MODEL_IC7000) +#define RIG_IS_IC703 (rig->state.rig_model == RIG_MODEL_IC703) +#define RIG_IS_IC705 (rig->state.rig_model == RIG_MODEL_IC705) +#define RIG_IS_IC706 (rig->state.rig_model == RIG_MODEL_IC706) +#define RIG_IS_IC706MKII (rig->state.rig_model == RIG_MODEL_IC706MKII) +#define RIG_IS_IC706MKIIG (rig->state.rig_model == RIG_MODEL_IC706MKIIG) +#define RIG_IS_IC707 (rig->state.rig_model == RIG_MODEL_IC707) +#define RIG_IS_IC7100 (rig->state.rig_model == RIG_MODEL_IC7100) +#define RIG_IS_IC718 (rig->state.rig_model == RIG_MODEL_IC718) +#define RIG_IS_IC7200 (rig->state.rig_model == RIG_MODEL_IC7200) +#define RIG_IS_IC725 (rig->state.rig_model == RIG_MODEL_IC725) +#define RIG_IS_IC726 (rig->state.rig_model == RIG_MODEL_IC726) +#define RIG_IS_IC728 (rig->state.rig_model == RIG_MODEL_IC728) +#define RIG_IS_IC729 (rig->state.rig_model == RIG_MODEL_IC729) +#define RIG_IS_IC7300 (rig->state.rig_model == RIG_MODEL_IC7300) +#define RIG_IS_IC731 (rig->state.rig_model == RIG_MODEL_IC731) +#define RIG_IS_IC735 (rig->state.rig_model == RIG_MODEL_IC735) +#define RIG_IS_IC736 (rig->state.rig_model == RIG_MODEL_IC736) +#define RIG_IS_IC737 (rig->state.rig_model == RIG_MODEL_IC737) +#define RIG_IS_IC738 (rig->state.rig_model == RIG_MODEL_IC738) +#define RIG_IS_IC7410 (rig->state.rig_model == RIG_MODEL_IC7410) +#define RIG_IS_IC746 (rig->state.rig_model == RIG_MODEL_IC746) +#define RIG_IS_IC746PRO (rig->state.rig_model == RIG_MODEL_IC746PRO) +#define RIG_IS_IC751 (rig->state.rig_model == RIG_MODEL_IC751) +#define RIG_IS_IC751A (rig->state.rig_model == RIG_MODEL_IC751A) +#define RIG_IS_IC756 (rig->state.rig_model == RIG_MODEL_IC756) +#define RIG_IS_IC756PRO (rig->state.rig_model == RIG_MODEL_IC756PRO) +#define RIG_IS_IC756PROII (rig->state.rig_model == RIG_MODEL_IC756PROII) +#define RIG_IS_IC756PROIII (rig->state.rig_model == RIG_MODEL_IC756PROIII) +#define RIG_IS_IC7600 (rig->state.rig_model == RIG_MODEL_IC7600) +#define RIG_IS_IC761 (rig->state.rig_model == RIG_MODEL_IC761) +#define RIG_IS_IC7610 (rig->state.rig_model == RIG_MODEL_IC7610) +#define RIG_IS_IC765 (rig->state.rig_model == RIG_MODEL_IC765) +#define RIG_IS_IC7700 (rig->state.rig_model == RIG_MODEL_IC7700) +#define RIG_IS_IC775 (rig->state.rig_model == RIG_MODEL_IC775) +#define RIG_IS_IC78 (rig->state.rig_model == RIG_MODEL_IC78) +#define RIG_IS_IC7800 (rig->state.rig_model == RIG_MODEL_IC7800) +#define RIG_IS_IC781 (rig->state.rig_model == RIG_MODEL_IC781) +#define RIG_IS_IC785X (rig->state.rig_model == RIG_MODEL_IC785x) +#define RIG_IS_IC820 (rig->state.rig_model == RIG_MODEL_IC820) +#define RIG_IS_IC821 (rig->state.rig_model == RIG_MODEL_IC821) +#define RIG_IS_IC821H (rig->state.rig_model == RIG_MODEL_IC821H) +#define RIG_IS_IC905 (rig->state.rig_model == RIG_MODEL_IC905) +#define RIG_IS_IC910 (rig->state.rig_model == RIG_MODEL_IC910) +#define RIG_IS_IC9100 (rig->state.rig_model == RIG_MODEL_IC9100) +#define RIG_IS_IC92D (rig->state.rig_model == RIG_MODEL_IC92D) +#define RIG_IS_IC970 (rig->state.rig_model == RIG_MODEL_IC970) +#define RIG_IS_IC9700 (rig->state.rig_model == RIG_MODEL_IC9700) +#define RIG_IS_IC8101 (rig->state.rig_model == RIG_MODEL_ICF8101) +#define RIG_IS_ICID1 (rig->state.rig_model == RIG_MODEL_ICID1) +#define RIG_IS_ICM700PRO (rig->state.rig_model == RIG_MODEL_IC_M700PRO) +#define RIG_IS_ICM710 (rig->state.rig_model == RIG_MODEL_IC_M710) +#define RIG_IS_ICM802 (rig->state.rig_model == RIG_MODEL_IC_M802) +#define RIG_IS_ICM803 (rig->state.rig_model == RIG_MODEL_IC_M803) +#define RIG_IS_ICR10 (rig->state.rig_model == RIG_MODEL_ICR10) +#define RIG_IS_ICR20 (rig->state.rig_model == RIG_MODEL_ICR20) +#define RIG_IS_ICR30 (rig->state.rig_model == RIG_MODEL_ICR30) +#define RIG_IS_ICR6 (rig->state.rig_model == RIG_MODEL_ICR6) +#define RIG_IS_ICR7000 (rig->state.rig_model == RIG_MODEL_ICR7000) +#define RIG_IS_ICR71 (rig->state.rig_model == RIG_MODEL_ICR71) +#define RIG_IS_ICR7100 (rig->state.rig_model == RIG_MODEL_ICR7100) +#define RIG_IS_ICR72 (rig->state.rig_model == RIG_MODEL_ICR72) +#define RIG_IS_ICR75 (rig->state.rig_model == RIG_MODEL_ICR75) +#define RIG_IS_ICR8500 (rig->state.rig_model == RIG_MODEL_ICR8500) +#define RIG_IS_ICR8600 (rig->state.rig_model == RIG_MODEL_ICR8600) +#define RIG_IS_ICR9000 (rig->state.rig_model == RIG_MODEL_ICR9000) +#define RIG_IS_ICR9500 (rig->state.rig_model == RIG_MODEL_ICR9500) +#define RIG_IS_ICRX7 (rig->state.rig_model == RIG_MODEL_ICRX7) +#define RIG_IS_ID5100 (rig->state.rig_model == RIG_MODEL_ID5100) +#define RIG_IS_OMNIVIP (rig->state.rig_model == RIG_MODEL_OMNIVIP) +#define RIG_IS_OS456 (rig->state.rig_model == RIG_MODEL_OS456) +#define RIG_IS_X5105 (rig->state.rig_model == RIG_MODEL_X5105) +#define RIG_IS_X6100 (rig->state.rig_model == RIG_MODEL_X6100) + + #endif /* _ICOM_H */ diff --git a/rigs/kenwood/flex6xxx.c b/rigs/kenwood/flex6xxx.c index 14604e04f..fe715085b 100644 --- a/rigs/kenwood/flex6xxx.c +++ b/rigs/kenwood/flex6xxx.c @@ -1242,7 +1242,7 @@ const struct rig_caps powersdr_caps = RIG_MODEL(RIG_MODEL_POWERSDR), .model_name = "PowerSDR/Thetis", .mfg_name = "FlexRadio/ANAN", - .version = "20221123.0", + .version = "20230608.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, @@ -1373,6 +1373,9 @@ const struct rig_caps powersdr_caps = .set_func = powersdr_set_func, //.set_ant = kenwood_set_ant_no_ack, //.get_ant = kenwood_get_ant, + .send_morse = kenwood_send_morse, + .stop_morse = kenwood_stop_morse, + .wait_morse = rig_wait_morse, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; diff --git a/rigs/kenwood/kenwood.c b/rigs/kenwood/kenwood.c index 6495488ae..649a7fee8 100644 --- a/rigs/kenwood/kenwood.c +++ b/rigs/kenwood/kenwood.c @@ -1874,6 +1874,9 @@ int kenwood_set_freq(RIG *rig, vfo_t vfo, freq_t freq) if (RIG_OK != err) { RETURNFUNC2(err); } } + // Malchite is so slow we don't do the get_freq + if (!RIG_IS_MALACHITE) + { rig_get_freq(rig, tvfo, &tfreq); if (tfreq == freq) @@ -1881,6 +1884,7 @@ int kenwood_set_freq(RIG *rig, vfo_t vfo, freq_t freq) rig_debug(RIG_DEBUG_TRACE, "%s: no freq change needed\n", __func__); RETURNFUNC2(RIG_OK); } + } switch (tvfo) { @@ -3191,7 +3195,7 @@ int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) if (RIG_IS_TS2000) { - vfo_num = (vfo == RIG_VFO_C) ? 1 : 0; + vfo_num = (vfo == RIG_VFO_B) ? 1 : 0; } else { @@ -3261,7 +3265,7 @@ int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) if (RIG_IS_TS2000) { - vfo_num = (vfo == RIG_VFO_C) ? 1 : 0; + vfo_num = (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) ? 1 : 0; } else { @@ -3521,7 +3525,7 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { len = 3; - if (vfo == RIG_VFO_C) + if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { cmd = "SM1"; } @@ -3559,7 +3563,7 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { len = 3; - if (vfo == RIG_VFO_C) + if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { cmd = "SM1"; // TS-2000 sub-transceiver S-meter range is half of the main one @@ -3605,7 +3609,7 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) if (RIG_IS_TS2000) { - vfo_num = (vfo == RIG_VFO_C) ? 1 : 0; + vfo_num = (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) ? 1 : 0; } else { @@ -3792,7 +3796,7 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) if (RIG_IS_TS2000) { - vfo_num = (vfo == RIG_VFO_C) ? 1 : 0; + vfo_num = (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) ? 1 : 0; } else { @@ -4857,7 +4861,7 @@ int kenwood_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) case RIG_PTT_ON: case RIG_PTT_ON_MIC: case RIG_PTT_ON_DATA: - ptt_cmd = (vfo == RIG_VFO_C) ? "TX1" : "TX0"; + ptt_cmd = "VX0;TX"; break; case RIG_PTT_OFF: @@ -4959,7 +4963,7 @@ int kenwood_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) } if ((RIG_IS_TS990S && RIG_VFO_SUB == vfo) || - (RIG_IS_TS2000 && RIG_VFO_C == vfo)) + (RIG_IS_TS2000 && (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo))) { offs = 3; } @@ -6101,6 +6105,7 @@ DECLARE_INITRIG_BACKEND(kenwood) rig_register(&tx500_caps); rig_register(&sdruno_caps); rig_register(&qrplabs_caps); + rig_register(&fx4_caps); return (RIG_OK); } diff --git a/rigs/kenwood/kenwood.h b/rigs/kenwood/kenwood.h index 4060bd60c..c12a850f3 100644 --- a/rigs/kenwood/kenwood.h +++ b/rigs/kenwood/kenwood.h @@ -28,7 +28,7 @@ #include "token.h" #include "idx_builtin.h" -#define BACKEND_VER "20230517" +#define BACKEND_VER "20230626" #define EOM_KEN ';' #define EOM_TH '\r' @@ -318,6 +318,7 @@ extern const struct rig_caps malachite_caps; extern const struct rig_caps tx500_caps; extern const struct rig_caps sdruno_caps; extern const struct rig_caps qrplabs_caps; +extern const struct rig_caps fx4_caps; /* use when not interested in the answer, but want to check its len */ static int inline kenwood_simple_transaction(RIG *rig, const char *cmd, diff --git a/rigs/kenwood/ts480.c b/rigs/kenwood/ts480.c index fae7b73e0..df46bfca6 100644 --- a/rigs/kenwood/ts480.c +++ b/rigs/kenwood/ts480.c @@ -31,6 +31,7 @@ #include "misc.h" #include "token.h" #include "kenwood.h" +#include "cache.h" #define TS480_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define SDRUNO_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTUSB) @@ -2022,21 +2023,37 @@ int malachite_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) int malachite_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int post_write_delay_save = rig->state.post_write_delay; + ENTERFUNC; rig->state.post_write_delay = 0; int retval = kenwood_get_freq(rig, vfo, freq); rig->state.post_write_delay = post_write_delay_save; - return retval; + RETURNFUNC(retval); } int malachite_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; - // Malachite has a bug where it takes two freq set to make it work - // under some band changes -- so we just do this all the time - retval = kenwood_set_freq(rig, vfo, freq + 1); + ENTERFUNC; - if (retval != RIG_OK) { RETURNFUNC(retval); } + rig_debug(RIG_DEBUG_TRACE, "%s: freqMainA=%g, freq=%g\n", __func__, + rig->state.cache.freqMainA, freq); + + if ((rig->state.cache.freqMainA < 400000000 && freq >= 400000000) + || (rig->state.cache.freqMainA >= 400000000 && freq < 400000000) + || rig->state.cache.freqMainA == 0) + { + // Malachite has a bug where it takes two freq set to make it work + // under band changes -- so we just do this all the time + retval = kenwood_set_freq(rig, vfo, freq + 1); + rig->state.post_write_delay = 250; // need a bit more time on band change + + if (retval != RIG_OK) { RETURNFUNC(retval); } + } + else + { + rig->state.post_write_delay = 125; + } retval = kenwood_set_freq(rig, vfo, freq); @@ -2053,7 +2070,7 @@ const struct rig_caps malachite_caps = RIG_MODEL(RIG_MODEL_MALACHITE), .model_name = "DSP", .mfg_name = "Malachite", - .version = BACKEND_VER ".3", + .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, @@ -2066,13 +2083,15 @@ const struct rig_caps malachite_caps = .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, - .post_write_delay = 400, + // Malchite needs 125ms unless going from low to high band -- see malachite_set_freq + // Do not change this without checking the 300ms delay in malachite_set_freq + .post_write_delay = 250, .timeout = 3000, .retry = 3, .preamp = {0, RIG_DBLST_END,}, .attenuator = {0, RIG_DBLST_END,}, .max_ifshift = Hz(0), - .targetable_vfo = RIG_TARGETABLE_FREQ, +// .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_POLL, diff --git a/rigs/kenwood/ts590.c b/rigs/kenwood/ts590.c index 6902e34a6..b385da864 100644 --- a/rigs/kenwood/ts590.c +++ b/rigs/kenwood/ts590.c @@ -29,9 +29,13 @@ #include "cal.h" #include "iofunc.h" +#define FX4_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) #define TS590_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTFM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_PKTAM) +#define FX4_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define TS590_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) +#define FX4_AM_TX_MODES (RIG_MODE_AM) #define TS590_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) +#define FX4_VFO (RIG_VFO_A|RIG_VFO_B) #define TS590_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define TS590_LEVEL_GET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_STRENGTH|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH| \ @@ -49,6 +53,7 @@ #define TS590_SCAN_OPS (RIG_SCAN_VFO) +#define FX4_ANTS (RIG_ANT_1) #define TS590_ANTS (RIG_ANT_1|RIG_ANT_2) #define TS590_CHANNEL_CAPS { \ @@ -1734,6 +1739,200 @@ const struct rig_caps ts590_caps = .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; +/** + * BG2FX FX-4C/FX-4CR rig capabilities + * Supposed to be 590S compatible + * Separate entry allows for customization + */ +const struct rig_caps fx4_caps = +{ + RIG_MODEL(RIG_MODEL_FX4), + .model_name = "FX4/C/CR/L", + .mfg_name = "BG2FX", + .version = BACKEND_VER ".7", + .copyright = "LGPL", + .status = RIG_STATUS_STABLE, + .rig_type = RIG_TYPE_TRANSCEIVER, + .ptt_type = RIG_PTT_RIG_MICDATA, + .dcd_type = RIG_DCD_RIG, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 115200, + .serial_rate_max = 115200, + .serial_data_bits = 8, + .serial_stop_bits = 1, + .serial_parity = RIG_PARITY_NONE, + .serial_handshake = RIG_HANDSHAKE_HARDWARE, + .write_delay = 0, + .post_write_delay = 0, + .timeout = 500, + .retry = 3, + .preamp = {12, RIG_DBLST_END,}, + .attenuator = {12, RIG_DBLST_END,}, + .max_rit = kHz(9.99), + .max_xit = kHz(9.99), + .max_ifshift = Hz(0), + .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, + .transceive = RIG_TRN_RIG, + .agc_level_count = 6, + .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_SUPERFAST, RIG_AGC_ON }, + + .chan_list = { /* TBC */ + { 0, 89, RIG_MTYPE_MEM, TS590_CHANNEL_CAPS }, + { 90, 99, RIG_MTYPE_EDGE, TS590_CHANNEL_CAPS }, + RIG_CHAN_END, + }, + + .rx_range_list1 = { + {kHz(30), Hz(59999999), FX4_ALL_MODES, -1, -1, FX4_VFO, FX4_ANTS}, + RIG_FRNG_END, + }, /*!< Receive frequency range list for ITU region 1 */ + .tx_range_list1 = { + {kHz(3500), kHz(3800), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {kHz(3500), kHz(3800), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {MHz(7), kHz(7200), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {MHz(7), kHz(7200), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {kHz(10100), kHz(10150), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {kHz(10100), kHz(10150), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {MHz(14), kHz(14350), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {MHz(14), kHz(14350), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {kHz(18068), kHz(18168), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {kHz(18068), kHz(18168), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {MHz(21), kHz(21450), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {MHz(21), kHz(21450), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {kHz(24890), kHz(24990), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {kHz(24890), kHz(24990), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {MHz(28), kHz(29700), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {MHz(28), kHz(29700), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {MHz(50), kHz(52000), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {MHz(50), kHz(52000), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + RIG_FRNG_END, + }, /*!< Transmit frequency range list for ITU region 1 */ + .rx_range_list2 = { + {kHz(30), Hz(59999999), FX4_ALL_MODES, -1, -1, FX4_VFO, FX4_ANTS}, + RIG_FRNG_END, + }, /*!< Receive frequency range list for ITU region 2 */ + .tx_range_list2 = { + {kHz(3500), MHz(4) - 1, FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {kHz(3500), MHz(4) - 1, FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {kHz(5250), kHz(5450), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {kHz(5250), kHz(5450), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {MHz(7), kHz(7300), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {MHz(7), kHz(7300), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {kHz(10100), kHz(10150), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {kHz(10100), kHz(10150), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {MHz(14), kHz(14350), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {MHz(14), kHz(14350), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {kHz(18068), kHz(18168), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {kHz(18068), kHz(18168), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {MHz(21), kHz(21450), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {MHz(21), kHz(21450), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {kHz(24890), kHz(24990), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {kHz(24890), kHz(24990), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {MHz(28), kHz(29700), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {MHz(28), kHz(29700), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + {MHz(50), kHz(52000), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, + {MHz(50), kHz(52000), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, + RIG_FRNG_END, + }, /*!< Transmit frequency range list for ITU region 2 */ + .tuning_steps = { + {TS590_ALL_MODES, kHz(1)}, + {TS590_ALL_MODES, Hz(2500)}, + {TS590_ALL_MODES, kHz(5)}, + {TS590_ALL_MODES, Hz(6250)}, + {TS590_ALL_MODES, kHz(10)}, + {TS590_ALL_MODES, Hz(12500)}, + {TS590_ALL_MODES, kHz(15)}, + {TS590_ALL_MODES, kHz(20)}, + {TS590_ALL_MODES, kHz(25)}, + {TS590_ALL_MODES, kHz(30)}, + {TS590_ALL_MODES, kHz(100)}, + {TS590_ALL_MODES, kHz(500)}, + {TS590_ALL_MODES, MHz(1)}, + {TS590_ALL_MODES, 0}, /* any tuning step */ + RIG_TS_END, + }, + /* mode/filter list, remember: order matters! */ + .filters = { + {RIG_MODE_SSB, kHz(2.2)}, + {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, + {RIG_MODE_AM, kHz(6)}, + {RIG_MODE_FM, kHz(12)}, + RIG_FLT_END, + }, + .level_gran = + { +#include "level_gran_kenwood.h" + [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, + [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, + [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 1000}, .step = {.i = 50}}, + [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, + [LVL_SLOPE_LOW] = {.min = {.i = 0}, .max = {.i = 2400}, .step = {.i = 10}}, + [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, + }, + + .str_cal = TS590_STR_CAL, + .swr_cal = TS590_SWR_CAL, + + .ext_tokens = ts590_ext_tokens, + .extfuncs = ts590_ext_funcs, + .extlevels = ts590_ext_levels, + + .priv = (void *)& ts590_priv_caps, + .rig_init = kenwood_init, + .rig_cleanup = kenwood_cleanup, + .rig_open = kenwood_open, + .rig_close = kenwood_close, + .set_freq = kenwood_set_freq, + .get_freq = kenwood_get_freq, + .set_rit = ts590_set_rit, + .get_rit = ts590_get_rit, + .set_xit = ts590_set_rit, + .get_xit = ts590_get_rit, + .set_mode = ts590_set_mode, + .get_mode = ts590_get_mode, + .set_vfo = kenwood_set_vfo, + .get_vfo = kenwood_get_vfo_if, + .set_split_vfo = kenwood_set_split_vfo, + .get_split_vfo = kenwood_get_split_vfo_if, + .get_ptt = kenwood_get_ptt, + .set_ptt = kenwood_set_ptt, + .get_dcd = kenwood_get_dcd, + .set_powerstat = kenwood_set_powerstat, + .get_powerstat = kenwood_get_powerstat, + .get_info = ts590_get_info, + .reset = kenwood_reset, + .set_ant = kenwood_set_ant, + .get_ant = kenwood_get_ant, + .scan_ops = TS590_SCAN_OPS, + .scan = kenwood_scan, /* not working, invalid arguments using rigctl; kenwood_scan does only support on/off and not tone and CTCSS scan */ + .has_set_level = TS590_LEVEL_SET, + .has_get_level = TS590_LEVEL_GET, + .set_level = ts590_set_level, + .get_level = ts590_get_level, + .set_ext_level = ts590_set_ext_level, + .get_ext_level = ts590_get_ext_level, + .has_get_func = TS590_FUNC_ALL, + .has_set_func = TS590_FUNC_ALL, + .set_func = ts590_set_func, + .get_func = ts590_get_func, + .set_ext_func = ts590_set_ext_func, + .get_ext_func = ts590_get_ext_func, + .set_ctcss_tone = kenwood_set_ctcss_tone, + .get_ctcss_tone = kenwood_get_ctcss_tone, + .ctcss_list = kenwood38_ctcss_list, + .set_trn = kenwood_set_trn, + .get_trn = kenwood_get_trn, + .send_morse = kenwood_send_morse, + .stop_morse = kenwood_stop_morse, + .wait_morse = rig_wait_morse, + .set_mem = kenwood_set_mem, + .get_mem = kenwood_get_mem, + .vfo_ops = TS590_VFO_OPS, + .vfo_op = kenwood_vfo_op, + .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS +}; + /** * TS-590SG rig capabilities */ diff --git a/rigs/yaesu/newcat.c b/rigs/yaesu/newcat.c index eb30eb57f..9b8de873d 100644 --- a/rigs/yaesu/newcat.c +++ b/rigs/yaesu/newcat.c @@ -1943,6 +1943,7 @@ int newcat_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) if (rig->state.current_mode != RIG_MODE_CW && rig->state.current_mode != RIG_MODE_CWR && rig->state.current_mode != RIG_MODE_CWN + && (is_ftdx3000 || is_ftdx3000dm) ) { // DX3000 with seperate rx/tx antennas was failing frequency change @@ -10908,6 +10909,7 @@ int newcat_set_cmd_validate(RIG *rig) { int bytes; char cmd[256]; // big enough + repeat: rig_flush(&state->rigport); /* discard any unsolicited data */ SNPRINTF(cmd, sizeof(cmd), "%s", priv->cmd_str); rc = write_block(&state->rigport, (unsigned char *) cmd, strlen(cmd)); @@ -10942,6 +10944,7 @@ int newcat_set_cmd_validate(RIG *rig) if (strncmp(priv->cmd_str, "TX", 2) == 0 && strncmp(priv->ret_data, "TX", 2) == 0) { + if (strstr(priv->ret_data,"TX2")) goto repeat; // TX command does not echo what's sent so we just check the basic command RETURNFUNC(RIG_OK); } diff --git a/rigs/yaesu/newcat.h b/rigs/yaesu/newcat.h index c943de044..23cc3083d 100644 --- a/rigs/yaesu/newcat.h +++ b/rigs/yaesu/newcat.h @@ -50,7 +50,7 @@ typedef char ncboolean; /* shared function version */ -#define NEWCAT_VER "20230531" +#define NEWCAT_VER "20230702" /* Hopefully large enough for future use, 128 chars plus '\0' */ #define NEWCAT_DATA_LEN 129 diff --git a/security/password.c b/security/password.c index f71ef8188..68f4a1979 100644 --- a/security/password.c +++ b/security/password.c @@ -41,7 +41,8 @@ HAMLIB_EXPORT(void) rig_password_generate_secret(char *pass, char newpass[256]; product = pass[0]; - for (int i = 1; pass[i]; ++i) + int i; + for (i = 1; pass[i]; ++i) { product *= pass[i]; } diff --git a/simulators/Makefile.am b/simulators/Makefile.am index 3b9df17b0..9f23ea49e 100644 --- a/simulators/Makefile.am +++ b/simulators/Makefile.am @@ -8,7 +8,7 @@ DISTCLEANFILES = bin_PROGRAMS = -check_PROGRAMS = simelecraft simicom simkenwood simyaesu simicom9100 simicom9700 simft991 simftdx1200 simftdx3000 simjupiter simpowersdr simid5100 simft736 simftdx5000 simtmd700 simrotorez simspid simft817 simts590 simft847 simicom7300 simicom7100 simatd578 simicom905 +check_PROGRAMS = simelecraft simicom simkenwood simyaesu simicom9100 simicom9700 simft991 simftdx1200 simftdx3000 simjupiter simpowersdr simid5100 simft736 simftdx5000 simtmd700 simrotorez simspid simft817 simts590 simft847 simicom7300 simicom7100 simatd578 simicom905 simts450 simelecraft_SOURCES = simelecraft.c simicom_SOURCES = simicom.c diff --git a/simulators/simicom7600.c b/simulators/simicom7600.c new file mode 100644 index 000000000..13301cdf4 --- /dev/null +++ b/simulators/simicom7600.c @@ -0,0 +1,635 @@ +// simicom will show the pts port to use for rigctl on Unix +// using virtual serial ports on Windows is to be developed yet +// Needs a lot of improvement to work on all Icoms +// gcc -g -Wall -o simicom simicom.c -lhamlib +// On mingw in the hamlib src directory +// gcc -static -I../include -g -Wall -o simicom simicom.c -L../../build/src/.libs -lhamlib -lwsock32 -lws2_32 +#define _XOPEN_SOURCE 700 +// since we are POSIX here we need this +struct ip_mreq + { + int dummy; + }; + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../src/misc.h" +#include +#include + + +#define BUFSIZE 256 +#define X25 + +int civ_731_mode = 0; +vfo_t current_vfo = RIG_VFO_A; +int split = 0; + +// we make B different from A to ensure we see a difference at startup +float freqA = 14074000; +float freqB = 14074500; +mode_t modeA = RIG_MODE_PKTUSB; +mode_t modeB = RIG_MODE_PKTUSB; +int datamodeA = 0; +int datamodeB = 0; +pbwidth_t widthA = 0; +pbwidth_t widthB = 1; +ant_t ant_curr = 0; +int ant_option = 0; +int ptt = 0; +int satmode = 0; +int agc_time = 1; +int ovf_status = 0; +int powerstat = 1; +int datamode = 0; + +void dumphex(unsigned char *buf, int n) +{ + for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } + + printf("\n"); +} + +int +frameGet(int fd, unsigned char *buf) +{ + int i = 0; + memset(buf, 0, BUFSIZE); + unsigned char c; + +again: + + while (read(fd, &c, 1) > 0) + { + buf[i++] = c; + //printf("i=%d, c=0x%02x\n",i,c); + + if (c == 0xfd) + { + dumphex(buf, i); + return i; + } + + if (i > 2 && c == 0xfe) + { + printf("Turning power on due to 0xfe string\n"); + powerstat = 1; + int j; + + for (j = i; j < 175; ++j) + { + if (read(fd, &c, 1) < 0) { break; } + } + + i = 0; + goto again; + } + } + + printf("Error??? c=x%02x\n", c); + + return 0; +} + +void frameParse(int fd, unsigned char *frame, int len) +{ + double freq; + int n = 0; + + dumphex(frame, len); + + if (frame[0] != 0xfe && frame[1] != 0xfe) + { + printf("expected fe fe, got "); + dumphex(frame, len); + return; + } + + switch (frame[4]) + { + case 0x03: + + //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); + if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) + { + printf("get_freqA\n"); + to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); + } + else + { + printf("get_freqB\n"); + to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); + } + + frame[10] = 0xfd; + + if (powerstat) + { + n = write(fd, frame, 11); + } + + break; + + case 0x04: + if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) + { + printf("get_modeA\n"); + frame[5] = modeA; + frame[6] = widthA; + } + else + { + printf("get_modeB\n"); + frame[5] = modeB; + frame[6] = widthB; + } + + frame[7] = 0xfd; + n = write(fd, frame, 8); + break; + + case 0x05: + freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); + printf("set_freq to %.0f\n", freq); + + if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } + else { freqB = freq; } + + frame[4] = 0xfb; + frame[5] = 0xfd; + n = write(fd, frame, 6); + break; + + case 0x06: + if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } + else { modeB = frame[6]; } + + frame[4] = 0xfb; + frame[5] = 0xfd; + n = write(fd, frame, 6); + break; + + case 0x07: + + switch (frame[5]) + { + case 0x00: current_vfo = RIG_VFO_A; break; + + case 0x01: current_vfo = RIG_VFO_B; break; + + case 0xd0: current_vfo = RIG_VFO_MAIN; break; + + case 0xd1: current_vfo = RIG_VFO_SUB; break; + } + + printf("set_vfo to %s\n", rig_strvfo(current_vfo)); + + frame[4] = 0xfb; + frame[5] = 0xfd; + n = write(fd, frame, 6); + break; + + case 0x0f: + if (frame[5] == 0) { split = 0; } + else if (frame[5] == 1) { split = 1; } + else { frame[6] = split; } + + if (frame[5] == 0xfd) + { + printf("get split %d\n", 1); + frame[7] = 0xfd; + n = write(fd, frame, 8); + } + else + { + printf("set split %d\n", 1); + frame[4] = 0xfb; + frame[5] = 0xfd; + n = write(fd, frame, 6); + } + + break; + + case 0x12: // we're simulating the 3-byte version -- not the 2-byte + if (frame[5] != 0xfd) + { + printf("Set ant %d\n", -1); + ant_curr = frame[5]; + ant_option = frame[6]; + dump_hex(frame, 8); + } + else + { + printf("Get ant\n"); + } + + frame[5] = ant_curr; + frame[6] = ant_option; + frame[7] = 0xfd; + printf("write 8 bytes\n"); + dump_hex(frame, 8); + n = write(fd, frame, 8); + break; + + case 0x14: + switch (frame[5]) + { + static int power_level = 0; + + case 0x07: + case 0x08: + if (frame[6] != 0xfd) + { + frame[6] = 0xfb; + dumphex(frame, 7); + n = write(fd, frame, 7); + printf("ACK x14 x08\n"); + } + else + { + to_bcd(&frame[6], (long long)128, 2); + frame[8] = 0xfb; + dumphex(frame, 9); + n = write(fd, frame, 9); + printf("SEND x14 x08\n"); + } + + break; + + case 0x0a: + printf("Using power level %d\n", power_level); + power_level += 10; + + if (power_level > 250) { power_level = 0; } + + to_bcd(&frame[6], (long long)power_level, 2); + frame[8] = 0xfd; + n = write(fd, frame, 9); + break; + } + + break; + + case 0x15: + switch (frame[5]) + { + static int meter_level = 0; + + case 0x07: + frame[6] = ovf_status; + frame[7] = 0xfd; + n = write(fd, frame, 8); + ovf_status = ovf_status == 0 ? 1 : 0; + break; + + case 0x11: + printf("Using meter level %d\n", meter_level); + meter_level += 10; + + if (meter_level > 250) { meter_level = 0; } + + to_bcd(&frame[6], (long long)meter_level, 2); + frame[8] = 0xfd; + n = write(fd, frame, 9); + break; + } + + case 0x16: + switch (frame[5]) + { + case 0x5a: + if (frame[6] == 0xfe) + { + satmode = frame[6]; + } + else + { + frame[6] = satmode; + frame[7] = 0xfd; + n = write(fd, frame, 8); + } + + break; + } + + break; + + case 0x18: // miscellaneous things + frame[5] = 1; + frame[6] = 0xfd; + n = write(fd, frame, 7); + break; + + case 0x19: // miscellaneous things + frame[5] = 0x94; + frame[6] = 0xfd; + n = write(fd, frame, 7); + break; + + case 0x1a: // miscellaneous things + switch (frame[5]) + { + case 0x03: // width + if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } + else { frame[6] = widthB; } + + frame[7] = 0xfd; + n = write(fd, frame, 8); + break; + + case 0x04: // AGC TIME + printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); + + if (frame[6] == 0xfd) // the we are reading + { + frame[6] = agc_time; + frame[7] = 0xfd; + n = write(fd, frame, 8); + } + else + { + printf("AGC_TIME RESPONSE******************************"); + agc_time = frame[6]; + frame[4] = 0xfb; + frame[5] = 0xfd; + n = write(fd, frame, 6); + } + + break; + + case 0x06: // satmode + if (frame[6] == 0xfd) // then we are reading + { + frame[6] = datamode; + frame[7] = 0xfd; + n = write(fd, frame, 8); + } + else + { + datamode = frame[6]; + frame[4] = 0xfd; + frame[5] = 0xfd; + n = write(fd, frame, 6); + } + break; + case 0x07: // satmode + frame[4] = 0; + frame[7] = 0xfd; + n = write(fd, frame, 8); + break; + + } + + break; + + case 0x1c: + switch (frame[5]) + { + case 0: + if (frame[6] == 0xfd) + { + frame[6] = ptt; + frame[7] = 0xfd; + n = write(fd, frame, 8); + } + else + { + ptt = frame[6]; + frame[7] = 0xfb; + frame[8] = 0xfd; + n = write(fd, frame, 9); + } + + break; + + } + + break; + + +#ifdef X25 + + case 0x25: + if (frame[6] == 0xfd) + { + if (frame[5] == 0x00) + { + to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); + printf("X25 get_freqA=%.0f\n", freqA); + } + else + { + to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); + printf("X25 get_freqB=%.0f\n", freqB); + } + + frame[11] = 0xfd; +#if 0 // async frame + unsigned char frame2[11]; + + frame2[0] = 0xfe; + frame2[1] = 0xfe; + frame2[2] = 0x00; // send transceive frame + frame2[3] = frame[3]; // send transceive frame + frame2[4] = 0x00; + frame2[5] = 0x70; + frame2[6] = 0x28; + frame2[7] = 0x57; + frame2[8] = 0x03; + frame2[9] = 0x00; + frame2[10] = 0xfd; + n = write(fd, frame2, 11); +#endif + n = write(fd, frame, 12); + } + else + { + freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); + printf("set_freq to %.0f\n", freq); + + if (frame[5] == 0x00) { freqA = freq; } + else { freqB = freq; } + + frame[4] = 0xfb; + frame[5] = 0xfd; + n = write(fd, frame, 6); + // send async frame + frame[2] = 0x00; // async freq + frame[3] = 0xa2; + frame[4] = 0x00; + frame[5] = 0x00; + frame[6] = 0x10; + frame[7] = 0x01; + frame[8] = 0x96; + frame[9] = 0x12; + frame[10] = 0xfd; + n = write(fd, frame, 11); + } + + break; + + case 0x26: + for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } + + if (frame[6] == 0xfd) // then a query + { + for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } + + frame[6] = frame[5] == 0 ? modeA : modeB; + frame[7] = frame[5] == 0 ? datamodeA : datamodeB; + frame[8] = 0xfb; + frame[9] = 0xfd; + n = write(fd, frame, 10); + } + else + { + for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } + + if (frame[6] == 0) + { + modeA = frame[7]; + datamodeA = frame[8]; + } + else + { + modeB = frame[7]; + datamodeB = frame[8]; + } + + frame[4] = 0xfb; + frame[5] = 0xfd; + n = write(fd, frame, 6); + } + + printf("\n"); + break; +#else + + case 0x25: + printf("x25 send nak\n"); + frame[4] = 0xfa; + frame[5] = 0xfd; + n = write(fd, frame, 6); + break; + + case 0x26: + printf("x26 send nak\n"); + frame[4] = 0xfa; + frame[5] = 0xfd; + n = write(fd, frame, 6); + break; +#endif + + default: printf("cmd 0x%02x unknown\n", frame[4]); + } + + if (n == 0) { printf("Write failed=%s\n", strerror(errno)); } + +// don't care about the rig type yet + +} + +#if defined(WIN32) || defined(_WIN32) +int openPort(char *comport) // doesn't matter for using pts devices +{ + int fd; + fd = open(comport, O_RDWR); + + if (fd < 0) + { + perror(comport); + } + + return fd; +} + +#else +int openPort(char *comport) // doesn't matter for using pts devices +{ + int fd = posix_openpt(O_RDWR); + char *name = ptsname(fd); + + if (name == NULL) + { + perror("pstname"); + return -1; + } + + printf("name=%s\n", name); + + if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) + { + perror("posix_openpt"); + return -1; + } + + return fd; +} +#endif + +void rigStatus() +{ + char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; + char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; + printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, + datamodeA, + widthA, + freqA); + printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, + datamodeB, + widthB, + freqB); +} + +int main(int argc, char **argv) +{ + unsigned char buf[256]; + int fd = openPort(argv[1]); + + printf("%s: %s\n", argv[0], rig_version()); +#ifdef X25 + printf("x25/x26 command recognized\n"); +#else + printf("x25/x26 command rejected\n"); +#endif +#if defined(WIN32) || defined(_WIN32) + + if (argc != 2) + { + printf("Missing comport argument\n"); + printf("%s [comport]\n", argv[0]); + exit(1); + } + +#endif + + while (1) + { + int len = frameGet(fd, buf); + + if (len <= 0) + { + close(fd); + fd = openPort(argv[1]); + } + + if (powerstat) + { + frameParse(fd, buf, len); + } + else + { + hl_usleep(1000 * 1000); + } + + rigStatus(); + } + + return 0; +} diff --git a/simulators/simts450.c b/simulators/simts450.c new file mode 100644 index 000000000..a7902f051 --- /dev/null +++ b/simulators/simts450.c @@ -0,0 +1,428 @@ +// can run this using rigctl/rigctld and socat pty devices +// gcc -o simyaesu simyaesu.c +#define _XOPEN_SOURCE 700 +// since we are POSIX here we need this +struct ip_mreq +{ + int dummy; +}; + +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 256 + +int mysleep = 20; + +float freqA = 14074000; +float freqB = 14074500; +int filternum = 7; +int datamode = 0; +int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; +int tomode = 0; + +int +getmyline(int fd, char *buf) +{ + char c; + int i = 0; + memset(buf, 0, BUFSIZE); + + while (read(fd, &c, 1) > 0) + { + buf[i++] = c; + + if (c == ';') { return strlen(buf); } + } + + return strlen(buf); +} + +#if defined(WIN32) || defined(_WIN32) +int openPort(char *comport) // doesn't matter for using pts devices +{ + int fd; + fd = open(comport, O_RDWR); + + if (fd < 0) + { + perror(comport); + } + + return fd; +} + +#else +int openPort(char *comport) // doesn't matter for using pts devices +{ + int fd = posix_openpt(O_RDWR); + char *name = ptsname(fd); + + if (name == NULL) + { + perror("pstname"); + return -1; + } + + printf("name=%s\n", name); + + if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) + { + perror("posix_openpt"); + return -1; + } + + return fd; +} +#endif + + + +int main(int argc, char *argv[]) +{ + char buf[256]; + char *pbuf; + int n; + int fd = openPort(argv[1]); + int freqa = 14074000, freqb = 140735000; + int modeA = 1, modeB = 2; + + while (1) + { + buf[0] = 0; + + if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } + +// else { return 0; } + + if (strcmp(buf, "RM5;") == 0) + { + printf("%s\n", buf); + hl_usleep(mysleep * 1000); + pbuf = "RM5100000;"; + n = write(fd, pbuf, strlen(pbuf)); +// printf("n=%d\n", n); + + if (n <= 0) { perror("RM5"); } + } + + else if (strcmp(buf, "AN0;") == 0) + { + printf("%s\n", buf); + hl_usleep(mysleep * 1000); + pbuf = "AN030;"; + n = write(fd, pbuf, strlen(pbuf)); +// printf("n=%d\n", n); + + if (n <= 0) { perror("AN"); } + } + else if (strcmp(buf, "IF;") == 0) + { + char ifbuf[256]; + printf("%s\n", buf); + hl_usleep(mysleep * 1000); + pbuf = "IF000503130001000+0000000000030000000;"; + sprintf(ifbuf, "IF%011d0001000+0000000000030000000;", freqa); + //pbuf = "IF00010138698 +00000000002000000 ; + n = write(fd, ifbuf, strlen(ifbuf)); +// printf("n=%d\n", n); + + if (n <= 0) { perror("IF"); } + + continue; + } + else if (strcmp(buf, "NB;") == 0) + { + hl_usleep(mysleep * 1000); + pbuf = "NB0;"; + n = write(fd, pbuf, strlen(pbuf)); + continue; + } + else if (strcmp(buf, "RA;") == 0) + { + hl_usleep(mysleep * 1000); + pbuf = "RA01;"; + n = write(fd, pbuf, strlen(pbuf)); + continue; + } + else if (strcmp(buf, "RG;") == 0) + { + hl_usleep(mysleep * 1000); + pbuf = "RG055;"; + n = write(fd, pbuf, strlen(pbuf)); + continue; + } + else if (strcmp(buf, "MG;") == 0) + { + hl_usleep(mysleep * 1000); + pbuf = "MG050;"; + n = write(fd, pbuf, strlen(pbuf)); + continue; + } + else if (strcmp(buf, "AG;") == 0) + { + hl_usleep(mysleep * 1000); + pbuf = "AG100;"; + n = write(fd, pbuf, strlen(pbuf)); + continue; + } + else if (strcmp(buf, "FV;") == 0) + { + hl_usleep(mysleep * 1000); + pbuf = "FV1.2;"; + n = write(fd, pbuf, strlen(pbuf)); + continue; + } + else if (strncmp(buf, "IS;", 3) == 0) + { + SNPRINTF(buf, sizeof(buf), "IS+0000;"); + n = write(fd, buf, strlen(buf)); + printf("%s\n", buf); + continue; + } + else if (strncmp(buf, "IS", 2) == 0) + { + continue; + } + else if (strncmp(buf, "SM;", 3) == 0) + { + SNPRINTF(buf, sizeof(buf), "SM0035;"); + n = write(fd, buf, strlen(buf)); + printf("%s\n", buf); + continue; + } + else if (strncmp(buf, "PC;", 3) == 0) + { + SNPRINTF(buf, sizeof(buf), "PC100;"); + n = write(fd, buf, strlen(buf)); + printf("%s\n", buf); + continue; + } + else if (strcmp(buf, "FW;") == 0) + { + //usleep(mysleep * 1000); + pbuf = "FW240"; + n = write(fd, pbuf, strlen(pbuf)); + hl_usleep(20 * 1000); + pbuf = "0;"; + n = write(fd, pbuf, strlen(pbuf)); + continue; + } + else if (strncmp(buf, "FW", 2) == 0) + { + continue; + } + else if (strcmp(buf, "ID;") == 0) + { + printf("%s\n", buf); + hl_usleep(mysleep * 1000); + SNPRINTF(buf, sizeof(buf), "ID%03d;", 10); + n = write(fd, buf, strlen(buf)); +// printf("n=%d\n", n); + + if (n <= 0) { perror("ID"); } + + continue; + } + + else if (strncmp(buf, "AI", 2) == 0) + { + if (strcmp(buf, "AI;")) + { + printf("%s\n", buf); + hl_usleep(mysleep * 1000); + pbuf = "AI0;"; + n = write(fd, pbuf, strlen(pbuf)); + printf("n=%d\n", n); + + if (n <= 0) { perror("AI"); } + } + } + + else if (strcmp(buf, "VS;") == 0) + { + printf("%s\n", buf); + hl_usleep(mysleep * 1000); + pbuf = "VS0;"; + n = write(fd, pbuf, strlen(pbuf)); +// printf("n=%d\n", n); + + if (n < 0) { perror("VS"); } + + continue; + } + else if (strcmp(buf, "EX032;") == 0) + { + static int ant = 0; + ant = (ant + 1) % 3; + printf("%s\n", buf); + hl_usleep(mysleep * 1000); + SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); + n = write(fd, buf, strlen(buf)); +// printf("n=%d\n", n); + + if (n < 0) { perror("EX032"); } + + continue; + } + else if (strncmp(buf, "EX", 2) == 0) + { + continue; + } + else if (strcmp(buf, "FA;") == 0) + { + SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); + n = write(fd, buf, strlen(buf)); + continue; + } + else if (strcmp(buf, "FB;") == 0) + { + SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); + n = write(fd, buf, strlen(buf)); + continue; + } + else if (strncmp(buf, "FA", 2) == 0) + { + sscanf(buf, "FA%d", &freqa); + continue; + } + else if (strncmp(buf, "FB", 2) == 0) + { + sscanf(buf, "FB%d", &freqb); + continue; + } + else if (strncmp(buf, "AI;", 3) == 0) + { + SNPRINTF(buf, sizeof(buf), "AI0;"); + n = write(fd, buf, strlen(buf)); + continue; + } + + else if (strncmp(buf, "PS;", 3) == 0) + { + SNPRINTF(buf, sizeof(buf), "PS1;"); + n = write(fd, buf, strlen(buf)); + continue; + } + else if (strncmp(buf, "SA;", 3) == 0) + { + SNPRINTF(buf, sizeof(buf), "SA0;"); + n = write(fd, buf, strlen(buf)); + } + else if (buf[3] == ';' && strncmp(buf, "SF", 2)==0) + { + SNPRINTF(buf, sizeof(buf), "SF%c%011.0f%c;", buf[2], buf[2] == '0' ? freqA : freqB, + buf[2] == '0' ? modeA + '0' : modeB + '0'); + n = write(fd, buf, strlen(buf)); + continue; + } + else if (strncmp(buf, "SF", 2) == 0) + { + mode_t tmpmode= buf[14]; + + if (buf[2] == '0') { modeA = tmpmode - '0'; } + else { modeB = tmpmode - '0'; } + printf("modeA=%c, modeB=%c\n", modeA, modeB); + + continue; + } + else if (strncmp(buf, "MD;", 3) == 0) + { + SNPRINTF(buf, sizeof(buf), "MD%d;", + modeA); // not worried about modeB yet for simulator + n = write(fd, buf, strlen(buf)); + continue; + } + else if (strncmp(buf, "MD", 2) == 0) + { + sscanf(buf, "MD%d", &modeA); // not worried about modeB yet for simulator + continue; + } + else if (strncmp(buf, "FL;", 3) == 0) + { + SNPRINTF(buf, sizeof(buf), "FL%03d;", filternum); + n = write(fd, buf, strlen(buf)); + continue; + } + else if (strncmp(buf, "FL", 2) == 0) + { + sscanf(buf, "FL%d", &filternum); + continue; + } + else if (strcmp(buf, "FR;") == 0) + { + SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); + n = write(fd, buf, strlen(buf)); + continue; + } + else if (strncmp(buf, "FR", 2) == 0) + { + sscanf(buf, "FR%d", &vfo); + } + else if (strcmp(buf, "FT;") == 0) + { + SNPRINTF(buf, sizeof(buf), "FR%d;", vfo_tx); + n = write(fd, buf, strlen(buf)); + continue; + } + else if (strncmp(buf, "FT", 2) == 0) + { + sscanf(buf, "FT%d", &vfo_tx); + } + else if (strncmp(buf, "DA;", 3) == 0) + { + SNPRINTF(buf, sizeof(buf), "DA%d;", datamode); + n = write(fd, buf, strlen(buf)); + printf("%s\n", buf); + continue; + } + else if (strncmp(buf, "DA", 2) == 0) + { + sscanf(buf, "DA%d", &datamode); + printf("%s\n", buf); + continue; + } + else if (strncmp(buf, "TO;", 3) == 0) + { + SNPRINTF(buf, sizeof(buf), "TO%d;", tomode); + continue; + } + else if (strncmp(buf, "BD;", 3) == 0) + { + continue; + } + else if (strncmp(buf, "BU;", 3) == 0) + { + continue; + } + else if (strncmp(buf, "TX", 2) == 0) + { + ptt = ptt_mic = ptt_data = ptt_tune = 0; + + switch (buf[2]) + { + case ';': ptt = 1; + + case '0': ptt_mic = 1; + + case '1': ptt_data = 1; + + case '2': ptt_tune = 1; + } + + continue; + } + else if (strlen(buf) > 0) + { + fprintf(stderr, "Unknown command: %s\n", buf); + } + + + } + + return 0; +} diff --git a/simulators/simts590.c b/simulators/simts590.c index cb9ba6eeb..4b083a2a4 100644 --- a/simulators/simts590.c +++ b/simulators/simts590.c @@ -24,27 +24,6 @@ int filternum = 7; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; -// ID 0310 == 310, Must drop leading zero -typedef enum nc_rigid_e -{ - NC_RIGID_NONE = 0, - NC_RIGID_FT450 = 241, - NC_RIGID_FT450D = 244, - NC_RIGID_FT950 = 310, - NC_RIGID_FT891 = 135, - NC_RIGID_FT991 = 135, - NC_RIGID_FT2000 = 251, - NC_RIGID_FT2000D = 252, - NC_RIGID_FTDX1200 = 583, - NC_RIGID_FTDX9000D = 101, - NC_RIGID_FTDX9000Contest = 102, - NC_RIGID_FTDX9000MP = 103, - NC_RIGID_FTDX5000 = 362, - NC_RIGID_FTDX3000 = 460, - NC_RIGID_FTDX101D = 681, - NC_RIGID_FTDX101MP = 682 -} nc_rigid_t; - int getmyline(int fd, char *buf) { @@ -324,7 +303,7 @@ int main(int argc, char *argv[]) continue; } - if (strncmp(buf, "PS;", 3) == 0) + else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); diff --git a/src/Makefile.am b/src/Makefile.am index 17d5a2701..6da17e185 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,7 +10,7 @@ RIGSRC = hamlibdatetime.h rig.c serial.c serial.h misc.c misc.h register.c regis network.c network.h cm108.c cm108.h gpio.c gpio.h idx_builtin.h token.h \ par_nt.h microham.c microham.h amplifier.c amp_reg.c amp_conf.c \ amp_conf.h amp_settings.c extamp.c sleep.c sleep.h sprintflst.c \ - sprintflst.h cache.c cache.h snapshot_data.c snapshot_data.h multicast.c + sprintflst.h cache.c cache.h snapshot_data.c snapshot_data.h multicast.c fifo.c fifo.h if VERSIONDLL RIGSRC += \ diff --git a/src/cache.c b/src/cache.c index 7649abc46..cf257a3d8 100644 --- a/src/cache.c +++ b/src/cache.c @@ -216,7 +216,7 @@ int rig_set_cache_freq(RIG *rig, vfo_t vfo, freq_t freq) break; default: - rig_debug(RIG_DEBUG_ERR, "%s(%d): unknown vfo?, vfo=%s\n", __func__, __LINE__, + rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown vfo?, vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); return (-RIG_EINVAL); } @@ -323,8 +323,8 @@ int rig_get_cache(RIG *rig, vfo_t vfo, freq_t *freq, int *cache_ms_freq, break; default: - rig_debug(RIG_DEBUG_ERR, "%s(%d): unknown vfo=%s\n", __func__, __LINE__, - rig_strvfo(vfo)); + rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown vfo=%s, curr_vfo=%s\n", __func__, __LINE__, + rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo)); } } @@ -449,7 +449,7 @@ int rig_get_cache(RIG *rig, vfo_t vfo, freq_t *freq, int *cache_ms_freq, break; default: - rig_debug(RIG_DEBUG_ERR, "%s(%d): unknown vfo?, vfo=%s\n", __func__, __LINE__, + rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown vfo?, vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } diff --git a/src/fifo.c b/src/fifo.c new file mode 100644 index 000000000..3272188e0 --- /dev/null +++ b/src/fifo.c @@ -0,0 +1,59 @@ +#include +#include +#include "fifo.h" + + +void initFIFO(FIFO *fifo) +{ + fifo->head = 0; + fifo->tail = 0; +} + +// returns RIG_OK if added +// return -RIG error if overflow +int push(FIFO *fifo, const char *msg) +{ + int len = strlen(msg); + + for (int i = 0; i < len; ++i) + { + fifo->data[fifo->tail] = msg[i]; + fifo->tail = (fifo->tail + 1) % FIFO_SIZE; + + if (fifo->tail == fifo->head) { return -RIG_EDOM; } + } + + return RIG_OK; +} + +char pop(FIFO *fifo) +{ + if (fifo->tail == fifo->head) { return -1; } + + char c = fifo->data[fifo->head]; + fifo->head = (fifo->head + 1) % FIFO_SIZE; + return c; +} + +#ifdef TEST +int main() +{ + FIFO fifo; + initFIFO(&fifo); + + const char *str = "Hello, World!\n"; + + // Pushing the string onto the FIFO + push(&fifo, str); + + // Popping and printing one character at a time + int c; + + while ((c = pop(&fifo)) != -1) + { + printf("%c", c); + } + + return 0; +} +#endif diff --git a/src/fifo.h b/src/fifo.h new file mode 100644 index 000000000..0eeaedb99 --- /dev/null +++ b/src/fifo.h @@ -0,0 +1,12 @@ +#define FIFO_SIZE 1024 + +typedef struct +{ + char data[FIFO_SIZE]; + int head; + int tail; +} FIFO; + +void initFIFO(FIFO *fifo); +int push(FIFO *fifo, const char *msg); +char pop(FIFO *fifo); diff --git a/src/gpio.c b/src/gpio.c index 298b8a2d4..1b2602eee 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -99,7 +99,28 @@ int gpio_open(hamlib_port_t *port, int output, int on_value) int gpio_close(hamlib_port_t *port) { - return close(port->fd); + int retval; + char pathname[HAMLIB_FILPATHLEN * 2]; + FILE *fexp; + + retval = close(port->fd); + + SNPRINTF(pathname, HAMLIB_FILPATHLEN, "/sys/class/gpio/unexport"); + fexp = fopen(pathname, "w"); + + if (!fexp) + { + rig_debug(RIG_DEBUG_ERR, + "Export GPIO%s (using %s): %s\n", + port->pathname, + pathname, + strerror(errno)); + return -RIG_EIO; + } + + fprintf(fexp, "%s\n", port->pathname); + fclose(fexp); + return retval; } diff --git a/src/iofunc.c b/src/iofunc.c index 2e37fb227..4be5d5633 100644 --- a/src/iofunc.c +++ b/src/iofunc.c @@ -492,12 +492,10 @@ static int port_read_sync_data(hamlib_port_t *p, void *buf, size_t count) switch (result) { case ERROR_SUCCESS: - HAMLIB_TRACE; // No error? break; case ERROR_IO_PENDING: - HAMLIB_TRACE; timeout.QuadPart = (p->timeout * -1000000LL); if ((result = SetWaitableTimer(hLocal, &timeout, 0, NULL, NULL, 0)) == 0) @@ -510,7 +508,6 @@ static int port_read_sync_data(hamlib_port_t *p, void *buf, size_t count) wait_result = WaitForMultipleObjects(3, event_handles, FALSE, p->timeout); } - HAMLIB_TRACE; switch (wait_result) { @@ -1340,7 +1337,10 @@ static int read_string_generic(hamlib_port_t *p, { ssize_t rd_count = 0; int result; + int timeout_save = p->timeout; +// p->timeout = 2; result = port_wait_for_data(p, direct); + p->timeout = timeout_save; if (result == -RIG_ETIMEOUT) { diff --git a/src/misc.h b/src/misc.h index 66cdd7faf..fac999786 100644 --- a/src/misc.h +++ b/src/misc.h @@ -158,7 +158,7 @@ extern HAMLIB_EXPORT(char *)date_strget(char *buf, int buflen, int localtime); void errmsg(int err, char *s, const char *func, const char *file, int line); #define ERRMSG(err, s) errmsg(err, s, __func__, __FILENAME__, __LINE__) #define ENTERFUNC { ++rig->state.depth; \ - rig_debug(RIG_DEBUG_VERBOSE, "%.*s%d:%s(%d):%s entered\n", rig->state.depth, spaces(), rig->state.depth, __FILENAME__, __LINE__, __func__); \ + rig_debug(RIG_DEBUG_VERBOSE, "%.*s%d:%s(%d):%s entered\n", rig->state.depth-1, spaces(), rig->state.depth, __FILENAME__, __LINE__, __func__); \ } #define ENTERFUNC2 { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d):%s entered\n", __FILENAME__, __LINE__, __func__); \ } @@ -166,7 +166,7 @@ void errmsg(int err, char *s, const char *func, const char *file, int line); // could be a function call #define RETURNFUNC(rc) {do { \ int rctmp = rc; \ - rig_debug(RIG_DEBUG_VERBOSE, "%.*s%d:%s(%d):%s returning(%ld) %s\n", rig->state.depth, spaces(), rig->state.depth, __FILENAME__, __LINE__, __func__, (long int) (rctmp), rctmp<0?rigerror2(rctmp):""); \ + rig_debug(RIG_DEBUG_VERBOSE, "%.*s%d:%s(%d):%s returning(%ld) %s\n", rig->state.depth-1, spaces(), rig->state.depth, __FILENAME__, __LINE__, __func__, (long int) (rctmp), rctmp<0?rigerror2(rctmp):""); \ if (rig->state.depth == 0) rig_debug(RIG_DEBUG_ERR, "%s(%d) depth=0 ******************\n", __func__, __LINE__); \ --rig->state.depth; \ return (rctmp); \ diff --git a/src/multicast.c b/src/multicast.c index de834c7e1..a79a78863 100644 --- a/src/multicast.c +++ b/src/multicast.c @@ -214,9 +214,8 @@ void json_add_vfoB(RIG *rig, char *msg) { strcat(msg, ",\n{\n"); json_add_string(msg, "Name", "VFOB", 1); - json_add_int(msg, "Freq", rig->state.cache.freqMainB, 0); + json_add_int(msg, "Freq", rig->state.cache.freqMainB, 1); -#if 0 if (strlen(rig_strrmode(rig->state.cache.modeMainB)) > 0) { json_add_string(msg, "Mode", rig_strrmode(rig->state.cache.modeMainB), 1); @@ -226,7 +225,6 @@ void json_add_vfoB(RIG *rig, char *msg) { json_add_int(msg, "Width", rig->state.cache.widthMainB, 0); } -#endif #if 0 // not working yet if (rig->state.rx_vfo != rig->state.tx_vfo && rig->state.cache.split) @@ -291,14 +289,12 @@ void *multicast_thread(void *vrig) // do the 1st packet all the time multicast_status_changed(rig); multicast_send_json(rig); - int loopcount = 4; + int loopcount = 8; + freq_t freqA, freqAsave = 0; + freq_t freqB, freqBsave = 0; while (rig->state.multicast->runflag) { - hl_usleep(100 * 1000); - freq_t freqA, freqAsave = 0; - freq_t freqB, freqBsave = 0; - if ((retval = rig_get_freq(rig, RIG_VFO_A, &freqA)) != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_get_freqA:%s\n", __func__, rigerror(retval)); @@ -314,14 +310,19 @@ void *multicast_thread(void *vrig) freqB = rig->state.cache.freqMainB; } - if (freqA != freqAsave || freqB != freqBsave || loopcount-- == 0) + if (freqA != freqAsave || freqB != freqBsave || loopcount-- <= 0) { multicast_status_changed(rig); multicast_send_json(rig); - loopcount = 4; + loopcount = 8; freqAsave = freqA; freqBsave = freqB; } + else + { + hl_usleep(100 * 1000); + } + } @@ -379,7 +380,7 @@ int multicast_init(RIG *rig, char *addr, int port) if (port == 0) { port = RIG_MULTICAST_PORT; } // Create a UDP socket - rig->state.multicast->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + rig->state.multicast->sock = socket(AF_INET, SOCK_DGRAM, 0); if (rig->state.multicast->sock < 0) { @@ -392,6 +393,7 @@ int multicast_init(RIG *rig, char *addr, int port) return -RIG_EIO; } +#if 0 // Set the SO_REUSEADDR option to allow multiple processes to use the same address int optval = 1; @@ -402,19 +404,22 @@ int multicast_init(RIG *rig, char *addr, int port) rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno)); return -RIG_EIO; } +#endif // Bind the socket to any available local address and the specified port - struct sockaddr_in saddr = {0}; - saddr.sin_family = AF_INET; - saddr.sin_addr.s_addr = htonl(INADDR_ANY); - saddr.sin_port = htons(port); + //struct sockaddr_in saddr = {0}; + //saddr.sin_family = AF_INET; + //saddr.sin_addr.s_addr = inet_addr(addr); + //saddr.sin_port = htons(port); +#if 0 if (bind(rig->state.multicast->sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: bind: %s\n", __func__, strerror(errno)); return -RIG_EIO; } +#endif // Construct the multicast group address // struct ip_mreq mreq = {0}; @@ -431,26 +436,30 @@ int multicast_init(RIG *rig, char *addr, int port) return -RIG_EIO; } +#if 0 +// look like we need to implement the client in a separate thread? // Join the multicast group if (setsockopt(rig->state.multicast->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&rig->state.multicast->mreq, sizeof(rig->state.multicast->mreq)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno)); - return -RIG_EIO; + //return -RIG_EIO; } +#endif // prime the dest_addr for the send routine + memset(&rig->state.multicast->dest_addr,0,sizeof(rig->state.multicast->dest_addr)); rig->state.multicast->dest_addr.sin_family = AF_INET; rig->state.multicast->dest_addr.sin_addr.s_addr = inet_addr(addr); rig->state.multicast->dest_addr.sin_port = htons(port); - printf("starting thread\n"); - +#if 0 rig->state.multicast->runflag = 1; pthread_create(&rig->state.multicast->threadid, NULL, multicast_thread, (void *)rig); //printf("threadid=%ld\n", rig->state.multicast->threadid); rig->state.multicast->multicast_running = 1; +#endif return RIG_OK; } @@ -479,11 +488,17 @@ int multicast_send(RIG *rig, const char *msg, int msglen) { // Construct the message to send if (msglen == 0) { msglen = strlen((char *)msg); } + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("224.0.0.1"); + addr.sin_port = htons(4532); + // Send the message to the multicast group ssize_t num_bytes = sendto(rig->state.multicast->sock, msg, msglen, 0, - (struct sockaddr *)&rig->state.multicast->dest_addr, - sizeof(rig->state.multicast->dest_addr)); + (struct sockaddr *)&addr, + sizeof(addr)); if (num_bytes < 0) { diff --git a/src/rig.c b/src/rig.c index 513de25bc..16beff2f7 100644 --- a/src/rig.c +++ b/src/rig.c @@ -51,6 +51,7 @@ #include "hamlib/rig.h" #include "hamlib/config.h" +#include "fifo.h" #include #include @@ -240,6 +241,22 @@ static int async_data_handler_stop(RIG *rig); void *async_data_handler(void *arg); #endif +typedef struct morse_data_handler_args_s +{ + RIG *rig; +} morse_data_handler_args; + +typedef struct morse_data_handler_priv_data_s +{ + pthread_t thread_id; + morse_data_handler_args args; + FIFO fifo; +} morse_data_handler_priv_data; + +static int morse_data_handler_start(RIG *rig); +static int morse_data_handler_stop(RIG *rig); +void *morse_data_handler(void *arg); + /* * track which rig is opened (with rig_open) * needed at least for transceive mode @@ -248,6 +265,7 @@ static int add_opened_rig(RIG *rig) { struct opened_rig_l *p; + ENTERFUNC2; p = (struct opened_rig_l *)calloc(1, sizeof(struct opened_rig_l)); if (!p) @@ -560,11 +578,13 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model) pthread_mutex_init(&rs->mutex_set_transaction, NULL); #endif + rs->rig_model = caps->rig_model; rs->priv = NULL; rs->async_data_enabled = 1; rs->rigport.fd = -1; rs->pttport.fd = -1; rs->comm_state = 0; + rig->state.depth = 1; #if 0 // extra debug if needed rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %p rs->comm_state==0?=%d\n", __func__, __LINE__, &rs->comm_state, @@ -655,6 +675,7 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model) rs->lo_freq = 0; rs->cache.timeout_ms = 500; // 500ms cache timeout by default rs->cache.ptt = 0; + rs->targetable_vfo = rig->caps->targetable_vfo; // We are using range_list1 as the default // Eventually we will have separate model number for different rig variations @@ -1299,6 +1320,16 @@ int HAMLIB_API rig_open(RIG *rig) rs->comm_state); hl_usleep(100 * 1000); // wait a bit after opening to give some serial ports time + status = morse_data_handler_start(rig); + + if (status < 0) + { + rig_debug(RIG_DEBUG_ERR, "%s: cw_data_handler_start failed: %s\n", __func__, rigerror(status)); + port_close(&rs->rigport, rs->rigport.type.rig); + RETURNFUNC2(status); + } + + /* * Maybe the backend has something to initialize * In case of failure, just close down and report error code. @@ -1340,6 +1371,7 @@ int HAMLIB_API rig_open(RIG *rig) { remove_opened_rig(rig); async_data_handler_stop(rig); + morse_data_handler_stop(rig); port_close(&rs->rigport, rs->rigport.type.rig); memcpy(&rs->rigport_deprecated, &rs->rigport, sizeof(hamlib_port_t_deprecated)); rs->comm_state = 0; @@ -1350,7 +1382,6 @@ int HAMLIB_API rig_open(RIG *rig) /* * trigger state->current_vfo first retrieval */ - HAMLIB_TRACE; if (caps->get_vfo && rig_get_vfo(rig, &rs->current_vfo) == RIG_OK) { @@ -1383,7 +1414,7 @@ int HAMLIB_API rig_open(RIG *rig) { // for non-Icom rigs if there's no set_vfo then we need to set one rs->current_vfo = vfo_fixup(rig, RIG_VFO_A, rig->state.cache.split); - rig_debug(RIG_DEBUG_TRACE, "%s: No set_vfo function rig so default vfo = %s\n", + rig_debug(RIG_DEBUG_TRACE, "%s: No set_vfo function rig so default vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); } else @@ -1491,6 +1522,7 @@ int HAMLIB_API rig_close(RIG *rig) caps->rig_close(rig); } + morse_data_handler_stop(rig); async_data_handler_stop(rig); /* @@ -1793,9 +1825,10 @@ static int twiddling(RIG *rig) */ #if BUILTINFUNC #undef rig_set_freq -int HAMLIB_API rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq, const char *func) +int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq, const char *func) +#define rig_set_freq(r,v,f) rig_set_freq(r,v,f,__builtin_FUNCTION()) #else -int HAMLIB_API rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) +int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) #endif { const struct rig_caps *caps; @@ -1901,6 +1934,9 @@ int HAMLIB_API rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { HAMLIB_TRACE; retcode = caps->set_freq(rig, vfo, freq); + // disabling the freq check as of 2023-06-02 + // seems unnecessary and slows down rigs unnecessarily + tfreq = freq; // some rig will return -RIG_ENTARGET if cannot set ptt while transmitting // we will just return RIG_OK and the frequency set will be ignored @@ -1996,15 +2032,22 @@ int HAMLIB_API rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) // verify our freq to ensure HZ mods are seen // some rigs truncate or round e.g. 1,2,5,10,20,100Hz intervals // we'll try this all the time and if it works out OK eliminate the #else - - if ((unsigned long long)freq % 100 != 0 // only need to do if < 100Hz interval - || freq > 100e6 // or if we are in the VHF and up range + if (((unsigned long long)freq % 100 != 0 // only need to do if < 100Hz interval + || freq > 100e6) // or if we are in the VHF and up range #if 0 // do we need to only do this when cache is turned on? 2020-07-02 W9MDB && rig->state.cache.timeout_ms > 0 #endif ) { + // some rigs we can skip this check for speed sake + if (rig->state.rig_model == RIG_MODEL_MALACHITE) + { + rig_set_cache_freq(rig, vfo, freq); + ELAPSED2; + LOCK(0); + RETURNFUNC(RIG_OK); + } // Unidirectional rigs do not reset cache if (rig->caps->rig_model != RIG_MODEL_FT736R) { @@ -2012,6 +2055,7 @@ int HAMLIB_API rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) } HAMLIB_TRACE; + retcode = rig_get_freq(rig, vfo, &freq_new); if (retcode != RIG_OK) @@ -2064,7 +2108,13 @@ int HAMLIB_API rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) * * \sa rig_set_freq() */ +#if BUILTINFUNC +#undef rig_get_freq +int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq, const char *func) +#define rig_get_freq(r,v,f) rig_get_freq(r,v,f,__builtin_FUNCTION()) +#else int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) +#endif { const struct rig_caps *caps; int retcode; @@ -2073,6 +2123,14 @@ int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) pbwidth_t width; ENTERFUNC; +#if BUILTINFUNC + rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, called from %s\n", + __func__, + rig_strvfo(vfo), func); +#else + rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, + rig_strvfo(vfo)); +#endif if (CHECK_RIG_ARG(rig)) { @@ -2850,6 +2908,7 @@ pbwidth_t HAMLIB_API rig_passband_wide(RIG *rig, rmode_t mode) #if BUILTINFUNC #undef rig_set_vfo int HAMLIB_API rig_set_vfo(RIG *rig, vfo_t vfo, const char *func) +#define rig_set_vfo(r,v) rig_set_vfo(r,v,__builtin_FUNCTION()) #else int HAMLIB_API rig_set_vfo(RIG *rig, vfo_t vfo) #endif @@ -3041,7 +3100,7 @@ int HAMLIB_API rig_get_vfo(RIG *rig, vfo_t *vfo) if (caps->get_vfo == NULL) { - rig_debug(RIG_DEBUG_ERR, "%s: no get_vfo\n", __func__); + rig_debug(RIG_DEBUG_WARN, "%s: no get_vfo\n", __func__); ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } @@ -3377,7 +3436,12 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) retcode = gpio_ptt_set(&rig->state.pttport, ptt); break; + case RIG_PTT_NONE: + // allowed for use with VOX and WSJT-X + break; + default: + rig_debug(RIG_DEBUG_WARN, "%s: unknown PTT type=%d\n", __func__, rig->state.pttport.type.ptt); ELAPSED2; RETURNFUNC(-RIG_EINVAL); } @@ -4977,6 +5041,8 @@ int HAMLIB_API rig_set_split_freq_mode(RIG *rig, if (RIG_OK == retcode) { + rig_set_cache_freq(rig, vfo, tx_freq); + HAMLIB_TRACE; retcode = rig_set_split_mode(rig, vfo, tx_mode, tx_width); } @@ -5144,12 +5210,7 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig, if ((!(caps->targetable_vfo & RIG_TARGETABLE_FREQ)) && (!(rig->caps->rig_model == RIG_MODEL_NETRIGCTL))) -#if BUILTINFUNC - rig_set_vfo(rig, rx_vfo, __builtin_FUNCTION()); - -#else rig_set_vfo(rig, rx_vfo); -#endif if (rx_vfo == RIG_VFO_CURR || rx_vfo == rig->state.current_vfo) @@ -6083,6 +6144,7 @@ int HAMLIB_API rig_mW2power(RIG *rig, rmode_t mode) { const freq_range_t *txrange; + int limited = 0; if (!rig || !rig->caps || !power || mwpower == 0) { @@ -6110,14 +6172,20 @@ int HAMLIB_API rig_mW2power(RIG *rig, RETURNFUNC2(RIG_OK); } - *power = (float)mwpower / txrange->high_power; + *power = (float)mwpower / (float) txrange->high_power; if (*power > 1.0) { *power = 1.0; + limited = 1; + } + else if (*power < 0.0) + { + *power = 0; + limited = 1; } - RETURNFUNC2(mwpower > txrange->high_power ? RIG_OK : -RIG_ETRUNC); + RETURNFUNC2(limited ? RIG_ETRUNC : RIG_OK); } @@ -7702,6 +7770,39 @@ static int async_data_handler_start(RIG *rig) RETURNFUNC(RIG_OK); } +static int morse_data_handler_start(RIG *rig) +{ + struct rig_state *rs = &rig->state; + morse_data_handler_priv_data *morse_data_handler_priv; + + ENTERFUNC; + + rs->morse_data_handler_thread_run = 1; + rs->morse_data_handler_priv_data = calloc(1, + sizeof(morse_data_handler_priv_data)); + + if (rs->morse_data_handler_priv_data == NULL) + { + RETURNFUNC(-RIG_ENOMEM); + } + + morse_data_handler_priv = (morse_data_handler_priv_data *) + rs->morse_data_handler_priv_data; + morse_data_handler_priv->args.rig = rig; + int err = pthread_create(&morse_data_handler_priv->thread_id, NULL, + morse_data_handler, &morse_data_handler_priv->args); + + if (err) + { + rig_debug(RIG_DEBUG_ERR, "%s: pthread_create error: %s\n", __func__, + strerror(errno)); + RETURNFUNC(-RIG_EINTERNAL); + } + + RETURNFUNC(RIG_OK); +} + + static int async_data_handler_stop(RIG *rig) { struct rig_state *rs = &rig->state; @@ -7743,6 +7844,45 @@ static int async_data_handler_stop(RIG *rig) RETURNFUNC(RIG_OK); } +static int morse_data_handler_stop(RIG *rig) +{ + struct rig_state *rs = &rig->state; + morse_data_handler_priv_data *morse_data_handler_priv; + + ENTERFUNC; + + rs->morse_data_handler_thread_run = 0; + + morse_data_handler_priv = (morse_data_handler_priv_data *) + rs->morse_data_handler_priv_data; + + if (morse_data_handler_priv != NULL) + { + if (morse_data_handler_priv->thread_id != 0) + { + // all cleanup is done in this function so we can kill thread + // Windows was taking 30 seconds to stop without this + pthread_cancel(morse_data_handler_priv->thread_id); + int err = pthread_join(morse_data_handler_priv->thread_id, NULL); + + if (err) + { + rig_debug(RIG_DEBUG_ERR, "%s: pthread_join error: %s\n", __func__, + strerror(errno)); + // just ignore the error + } + + morse_data_handler_priv->thread_id = 0; + } + + free(rs->morse_data_handler_priv_data); + rs->morse_data_handler_priv_data = NULL; + } + + RETURNFUNC(RIG_OK); +} + + void *async_data_handler(void *arg) { struct async_data_handler_args_s *args = (struct async_data_handler_args_s *) @@ -7783,7 +7923,7 @@ void *async_data_handler(void *arg) __func__, result); hl_usleep(500 * 1000); } - + hl_usleep(10*1000); continue; } @@ -7828,6 +7968,40 @@ void *async_data_handler(void *arg) } #endif +void *morse_data_handler(void *arg) +{ + struct morse_data_handler_args_s *args = (struct morse_data_handler_args_s *) + arg; + RIG *rig = args->rig; + struct rig_state *rs = &rig->state; + int result; + FIFO fifo; + + rig_debug(RIG_DEBUG_VERBOSE, "%s: Starting morse data handler thread\n", + __func__); + + initFIFO(&fifo); + while (rs->morse_data_handler_thread_run) + { + char c[2]; + c[1] = 0; + while((c[0]=pop(&fifo)!=-1)) + { + result = rig_send_morse(rig, RIG_VFO_CURR, c); + if (result != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s: error: %s\n", __func__, rigerror(result)); + push(&fifo, c); + hl_usleep(20*1000); + } + } + hl_usleep(20*1000); + } + pthread_exit(NULL); + return NULL; +} + + HAMLIB_EXPORT(int) rig_password(RIG *rig, const char *key1) { int retval = -RIG_EPROTO; @@ -7995,3 +8169,5 @@ HAMLIB_EXPORT(int) rig_is_model(RIG *rig, rig_model_t model) return (is_rig); // RETURN is too verbose here } + + diff --git a/tests/Makefile.am b/tests/Makefile.am index 0e3d453d8..72717b30e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -17,9 +17,9 @@ DISTCLEANFILES = rigctl.log rigctl.sum testbcd.log testbcd.sum bin_PROGRAMS = rigctl rigctld rigmem rigsmtr rigswr rotctl rotctld rigctlcom rigctltcp rigctlsync ampctl ampctld rigtestmcast rigtestmcastrx $(TESTLIBUSB) #check_PROGRAMS = dumpmem testrig testrigopen testrigcaps testtrn testbcd testfreq listrigs testloc rig_bench testcache cachetest cachetest2 testcookie testgrid testsecurity -check_PROGRAMS = dumpmem testrig testrigopen testrigcaps testtrn testbcd testfreq listrigs testloc rig_bench testcache cachetest cachetest2 testcookie testgrid hamlibmodels +check_PROGRAMS = dumpmem testrig testrigopen testrigcaps testtrn testbcd testfreq listrigs testloc rig_bench testcache cachetest cachetest2 testcookie testgrid hamlibmodels testmW2power -RIGCOMMONSRC = rigctl_parse.c rigctl_parse.h dumpcaps.c dumpstate.c uthash.h +RIGCOMMONSRC = rigctl_parse.c rigctl_parse.h dumpcaps.c dumpstate.c uthash.h rig_tests.c rig_tests.h ROTCOMMONSRC = rotctl_parse.c rotctl_parse.h dumpcaps_rot.c uthash.h AMPCOMMONSRC = ampctl_parse.c ampctl_parse.h dumpcaps_amp.c uthash.h diff --git a/tests/dumpcaps.c b/tests/dumpcaps.c index 5b911fba6..9a917ddeb 100644 --- a/tests/dumpcaps.c +++ b/tests/dumpcaps.c @@ -236,10 +236,10 @@ int dumpcaps(RIG *rig, FILE *fout) } fprintf(fout, - "Write delay: %dmS, timeout %dmS, %d retry\n", + "Write delay: %dms, timeout %dms, %d retry\n", caps->write_delay, caps->timeout, caps->retry); fprintf(fout, - "Post Write delay: %dmS\n", + "Post write delay: %dms\n", caps->post_write_delay); fprintf(fout, diff --git a/tests/dumpcaps_amp.c b/tests/dumpcaps_amp.c index 39d16f9bd..a0b800b7f 100644 --- a/tests/dumpcaps_amp.c +++ b/tests/dumpcaps_amp.c @@ -114,13 +114,13 @@ int dumpcaps_amp(AMP *amp, FILE *fout) } fprintf(fout, - "Write delay:\t\t%dmS, timeout %dmS, %d retr%s\n", + "Write delay:\t\t%dms, timeout %dms, %d retr%s\n", caps->write_delay, caps->timeout, caps->retry, (caps->retry == 1) ? "y" : "ies"); fprintf(fout, - "Post Write delay:\t%dmS\n", + "Post write delay:\t%dms\n", caps->post_write_delay); fprintf(fout, "Has priv data:\t\t%c\n", caps->priv != NULL ? 'Y' : 'N'); diff --git a/tests/dumpcaps_rot.c b/tests/dumpcaps_rot.c index 8f4e0db97..69626dd46 100644 --- a/tests/dumpcaps_rot.c +++ b/tests/dumpcaps_rot.c @@ -132,13 +132,13 @@ int dumpcaps_rot(ROT *rot, FILE *fout) } fprintf(fout, - "Write delay:\t\t%dmS, timeout %dmS, %d retr%s\n", + "Write delay:\t\t%dms, timeout %dms, %d retr%s\n", caps->write_delay, caps->timeout, caps->retry, (caps->retry == 1) ? "y" : "ies"); fprintf(fout, - "Post Write delay:\t%dmS\n", + "Post write delay:\t%dms\n", caps->post_write_delay); if (rot->state.has_status != 0) diff --git a/tests/dumpstate.c b/tests/dumpstate.c index 5acee230f..5f0ec99dd 100644 --- a/tests/dumpstate.c +++ b/tests/dumpstate.c @@ -236,10 +236,10 @@ int dumpstate(RIG *rig, FILE *fout) } fprintf(fout, - "Write delay: %dmS, timeout %dmS, %d retry\n", + "Write delay: %dms, timeout %dms, %d retry\n", rig->state.write_delay, rig->state.timeout, rig->state.retry); fprintf(fout, - "Post Write delay: %dmS\n", + "Post write delay: %dms\n", rig->state.post_write_delay); fprintf(fout, diff --git a/tests/rig_tests.c b/tests/rig_tests.c new file mode 100644 index 000000000..a4a706b69 --- /dev/null +++ b/tests/rig_tests.c @@ -0,0 +1,32 @@ +#include +#include +#include + + +int rig_test_cw(RIG *rig) +{ + char *s = "SOS SOS SOS SOS SOS SOS SOS SOS SOS SOS SOS SOS SOS"; + //char *s = "TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST"; + int i; + ELAPSED1; + ENTERFUNC; + + for (i = 0; i < strlen(s); ++i) + { + char cw[2]; + cw[0] = s[i]; + cw[1] = '\0'; + + int retval = rig_send_morse(rig, RIG_VFO_CURR, cw); + hl_usleep(100*1000); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s: rig_send_morse error: %s\n", __func__, + rigerror(retval)); + } + } + + ELAPSED2; + RETURNFUNC(RIG_OK); +} diff --git a/tests/rig_tests.h b/tests/rig_tests.h new file mode 100644 index 000000000..7cd3e18a6 --- /dev/null +++ b/tests/rig_tests.h @@ -0,0 +1,3 @@ +#include + +int rig_test_cw(RIG *rig); diff --git a/tests/rigctl_parse.c b/tests/rigctl_parse.c index b58171f5b..c0386bd2a 100644 --- a/tests/rigctl_parse.c +++ b/tests/rigctl_parse.c @@ -36,6 +36,7 @@ #include #include #include +#include // If true adds some debug statements to see flow of rigctl parsing int debugflow = 0; @@ -264,6 +265,7 @@ declare_proto_rig(set_lock_mode); declare_proto_rig(get_lock_mode); declare_proto_rig(send_raw); declare_proto_rig(client_version); +declare_proto_rig(test); /* @@ -378,6 +380,8 @@ static struct test_table test_list[] = { 0xa3, "get_lock_mode", ACTION(get_lock_mode), ARG_NOVFO, "Locked" }, { 0xa4, "send_raw", ACTION(send_raw), ARG_NOVFO | ARG_IN1 | ARG_IN2 | ARG_OUT3, "Terminator", "Command", "Send raw answer" }, { 0xa5, "client_version", ACTION(client_version), ARG_NOVFO | ARG_IN1, "Version", "Client version" }, + { 0xa6, "get_vfo_list", ACTION(get_vfo_list), ARG_NOVFO }, + { 0xa7, "test", ACTION(test), ARG_NOVFO | ARG_IN, "routine" }, { 0x00, "", NULL }, }; @@ -1732,7 +1736,7 @@ readline_repeat: else { // Allow only certain commands when the rig is powered off - if ((rig_powerstat == RIG_POWER_OFF || rig_powerstat == RIG_POWER_STANDBY) + if (my_rig->state.powerstat == RIG_POWER_OFF && (rig_powerstat == RIG_POWER_OFF || rig_powerstat == RIG_POWER_STANDBY) && cmd_entry->cmd != '1' // dump_caps && cmd_entry->cmd != '3' // dump_conf && cmd_entry->cmd != 0x8f // dump_state @@ -2436,6 +2440,20 @@ declare_proto_rig(get_vfo_list) RETURNFUNC2(RIG_OK); } +/* '\test' */ +declare_proto_rig(test) +{ + ENTERFUNC2; + if (!strcmp(arg1, "?")) + { + fprintf(fout, "cw\n"); + RETURNFUNC2(RIG_OK); + } + if (strcmp(arg1, "cw")==0) rig_test_cw(rig); + + RETURNFUNC2(RIG_OK); +} + /* '\get_modes' */ declare_proto_rig(get_modes) { @@ -4567,8 +4585,10 @@ declare_proto_rig(dump_state) rig->state.level_gran[i].max.i, rig->state.level_gran[i].step.i); } } - fprintf(fout, "\n"); + + rig->state.rig_model = rig->caps->rig_model; + fprintf(fout, "rig_model=%d\n", rig->state.rig_model); fprintf(fout, "done\n"); } @@ -4793,7 +4813,7 @@ declare_proto_rig(get_powerstat) fprintf(fout, "%s: ", cmd->arg1); } - fprintf(fout, "%d\n", stat); + fprintf(fout, "%d%c", stat, resp_sep); rig_powerstat = stat; // update our global so others can see powerstat RETURNFUNC2(status); diff --git a/tests/rigctld.c b/tests/rigctld.c index bd0ad1b6b..7e18ce837 100644 --- a/tests/rigctld.c +++ b/tests/rigctld.c @@ -1117,7 +1117,6 @@ int main(int argc, char *argv[]) #ifdef HAVE_PTHREAD /* allow threads to finish current action */ mutex_rigctld(1); - HAMLIB_TRACE; if (client_count) { @@ -1125,17 +1124,13 @@ int main(int argc, char *argv[]) } rig_close(my_rig); - HAMLIB_TRACE; mutex_rigctld(0); - HAMLIB_TRACE; #else rig_close(my_rig); /* close port */ #endif - HAMLIB_TRACE; network_multicast_publisher_stop(my_rig); - HAMLIB_TRACE; rig_cleanup(my_rig); /* if you care about memory */ #ifdef __MINGW32__ diff --git a/tests/rigctltcp.c b/tests/rigctltcp.c index 56e612123..f80cfe906 100644 --- a/tests/rigctltcp.c +++ b/tests/rigctltcp.c @@ -1103,7 +1103,6 @@ int main(int argc, char *argv[]) #ifdef HAVE_PTHREAD /* allow threads to finish current action */ mutex_rigctld(1); - HAMLIB_TRACE; if (client_count) { @@ -1111,17 +1110,13 @@ int main(int argc, char *argv[]) } rig_close(my_rig); - HAMLIB_TRACE; mutex_rigctld(0); - HAMLIB_TRACE; #else rig_close(my_rig); /* close port */ #endif - HAMLIB_TRACE; network_multicast_publisher_stop(my_rig); - HAMLIB_TRACE; rig_cleanup(my_rig); /* if you care about memory */ #ifdef __MINGW32__ diff --git a/tests/testmW2power.c b/tests/testmW2power.c new file mode 100644 index 000000000..215b20b25 --- /dev/null +++ b/tests/testmW2power.c @@ -0,0 +1,78 @@ +/* + * Hamlib sample program to test transceive mode (async event) + */ + +#include +#include +#include +#include + +#include + +#include + +int nrigs = 0; + +int callback(const struct rig_caps *caps, rig_ptr_t rigp) +{ + RIG *rig = (RIG *) rigp; + + switch (caps->rig_model) + { + case RIG_MODEL_NETRIGCTL: + return 1; + break; + } + + rig = rig_init(caps->rig_model); + + if (!rig) + { + fprintf(stderr, "Unknown rig num: %u\n", caps->rig_model); + fprintf(stderr, "Please check riglist.h\n"); + exit(1); /* whoops! something went wrong (mem alloc?) */ + } + + if (caps->mW2power) + { + nrigs++; + printf("%20s:", caps->model_name); + fflush(stdout); + float fpow; + unsigned int mwpower = 1 * 1000; + freq_t freq = MHz(14); + int retcode = rig_mW2power(rig, &fpow, mwpower, freq, RIG_MODE_CW); + + if (retcode != RIG_OK) + { + printf("rig_mW2power: error = %s \n", rigerror(retcode)); + return 1; + } + + if (fpow < 0.009 || fpow > .11) + { +// printf("rig=%d, fpow=%g, min=%d, max=%d\n", caps->rig_model, fpow, caps->); + printf("rig=%d, fpow=%g\n", caps->rig_model, fpow); + // we call again to make debugging this section easier + rig_mW2power(rig, &fpow, mwpower, freq, RIG_MODE_CW); + } + else { printf("\n"); } + } + + rig_cleanup(rig); /* if you care about memory */ + return 1; +} + +int main(int argc, char *argv[]) +{ + RIG *rig; + int i; + + rig_set_debug(RIG_DEBUG_NONE); + + rig_load_all_backends(); + rig_list_foreach(callback, &rig); + printf("Done testing %d rigs\n", nrigs); + + return 0; +}